ServletRequestAttributes considers standard Number subclasses (as defined in NumberUtils) as immutable

Issue: SPR-11738
master
Juergen Hoeller 10 years ago
parent bb6e07bd3a
commit 8f2ed66b4a
  1. 22
      spring-core/src/main/java/org/springframework/util/NumberUtils.java
  2. 17
      spring-web/src/main/java/org/springframework/web/context/request/ServletRequestAttributes.java

@ -21,6 +21,9 @@ import java.math.BigInteger;
import java.text.DecimalFormat; import java.text.DecimalFormat;
import java.text.NumberFormat; import java.text.NumberFormat;
import java.text.ParseException; import java.text.ParseException;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/** /**
* Miscellaneous utility methods for number conversion and parsing. * Miscellaneous utility methods for number conversion and parsing.
@ -37,6 +40,25 @@ public abstract class NumberUtils {
private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE); private static final BigInteger LONG_MAX = BigInteger.valueOf(Long.MAX_VALUE);
/**
* Standard number types (all immutable):
* Byte, Short, Integer, Long, BigInteger, Float, Double, BigDecimal.
*/
public static final Set<Class<?>> STANDARD_NUMBER_TYPES;
static {
Set<Class<?>> numberTypes = new HashSet<Class<?>>(8);
numberTypes.add(Byte.class);
numberTypes.add(Short.class);
numberTypes.add(Integer.class);
numberTypes.add(Long.class);
numberTypes.add(BigInteger.class);
numberTypes.add(Float.class);
numberTypes.add(Double.class);
numberTypes.add(BigDecimal.class);
STANDARD_NUMBER_TYPES = Collections.unmodifiableSet(numberTypes);
}
/** /**
* Convert the given number into an instance of the given target class. * Convert the given number into an instance of the given target class.

@ -16,13 +16,16 @@
package org.springframework.web.context.request; package org.springframework.web.context.request;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.NumberUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.util.WebUtils; import org.springframework.web.util.WebUtils;
@ -46,6 +49,15 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
public static final String DESTRUCTION_CALLBACK_NAME_PREFIX = public static final String DESTRUCTION_CALLBACK_NAME_PREFIX =
ServletRequestAttributes.class.getName() + ".DESTRUCTION_CALLBACK."; ServletRequestAttributes.class.getName() + ".DESTRUCTION_CALLBACK.";
protected static final Set<Class<?>> immutableValueTypes = new HashSet<Class<?>>(16);
static {
immutableValueTypes.addAll(NumberUtils.STANDARD_NUMBER_TYPES);
immutableValueTypes.add(Boolean.class);
immutableValueTypes.add(Character.class);
immutableValueTypes.add(String.class);
}
private final HttpServletRequest request; private final HttpServletRequest request;
@ -265,7 +277,7 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
* attribute, that is, doesn't have to be re-set via {@code session.setAttribute} * attribute, that is, doesn't have to be re-set via {@code session.setAttribute}
* since its value cannot meaningfully change internally. * since its value cannot meaningfully change internally.
* <p>The default implementation returns {@code true} for {@code String}, * <p>The default implementation returns {@code true} for {@code String},
* {@code Character}, {@code Boolean} and {@code Number} values. * {@code Character}, {@code Boolean} and standard {@code Number} values.
* @param name the name of the attribute * @param name the name of the attribute
* @param value the corresponding value to check * @param value the corresponding value to check
* @return {@code true} if the value is to be considered as immutable for the * @return {@code true} if the value is to be considered as immutable for the
@ -273,8 +285,7 @@ public class ServletRequestAttributes extends AbstractRequestAttributes {
* @see #updateAccessedSessionAttributes() * @see #updateAccessedSessionAttributes()
*/ */
protected boolean isImmutableSessionAttribute(String name, Object value) { protected boolean isImmutableSessionAttribute(String name, Object value) {
return (value instanceof String || value instanceof Character || return (value == null || immutableValueTypes.contains(value.getClass()));
value instanceof Boolean || value instanceof Number);
} }
/** /**

Loading…
Cancel
Save