SpringMvc @RequestParam 使用推荐使用包装类型代替包装类型
springmvc 中@requestparam注解使用
建议使用包装类型来代替基本数据类型
public string form2(@requestparam(name="age") int age){
public string form2(@requestparam(name="age") integer age) {
上述两种方式 这种情况下使用起来基本没有差别,但是为什么要说建议使用包装类型而不是基本类型呢?
一.@requestparam属性作用
因为当@requestparam注解 required 属性(默认为true,代表该参数在请求中必不可少) 设置为false时,判断的标准是这样的:
object arg = resolvename(resolvedname.tostring(), nestedparameter, webrequest);
if (arg == null) {
if (namedvalueinfo.defaultvalue != null) {
arg = resolvestringvalue(namedvalueinfo.defaultvalue);
}
else if (namedvalueinfo.required && !nestedparameter.isoptional()) {
handlemissingvalue(namedvalueinfo.name, nestedparameter, webrequest);
}
arg = handlenullvalue(namedvalueinfo.name, arg, nestedparameter.getnestedparametertype());
}
else if ("".equals(arg) && namedvalueinfo.defaultvalue != null) {
arg = resolvestringvalue(namedvalueinfo.defaultvalue);
}
上述代码为spring abstractnamedvaluemethodargumentresolver 的 resolveargument 方法,顾名思义就是解析请求中参数并完成类型转换的方法;
arg 是从请求中获取的对应参数值,调用 request.getparametervalues(name) ;
当arg==null时,意味着请求中不包含该参数(即请求中不包含age参数),@requestparam的defaultvalue不为空 那就使用 defaultvalue作为请求中的参数,
但是required为true且默认值为null,就会执行handlemissingvalue抛出异常,请求中缺少对应参数 ;
两种逻辑都没有执行就代表required为 false 且 默认值为 null ,这时候就会抛出另外一种异常,java.lang.illegalstateexception: optional int parameter 'age' is present but cannot be translated into a null value due to being declared as a primitive type. consider declaring it as object wrapper for the corresponding primitive type.
查看异常说明,age参数存在但是无法转为null类型,因为age被定义为基本数据类型了,建议把它声明为对应的包装类型;
但是八种基本数据类型测试的时候, 就是 布尔类型 boolean,代码原因如下:
可以看到spring的解析当方法入参为boolean类型时候,直接返回boolean.false,但是其他七个基本数据类型就抛出异常了;
(补充一句,spring mvc:annotation-driven使用的情况下,比如请求中传入属性需要赋给布尔值,该属性值为 true 1 on yes这四个都可以赋给boolean类型的)
private object handlenullvalue(string name, object value, class<?> paramtype) { if (value == null) { if (boolean.type.equals(paramtype)) { return boolean.false; } else if (paramtype.isprimitive()) { throw new illegalstateexception("optional " + paramtype.getsimplename() + " parameter '" + name + "' is present but cannot be translated into a null value due to being declared as a " + "primitive type. consider declaring it as object wrapper for the corresponding primitive type."); } } return value;
}
二.@requestparam使用情形列举
简而言之@requestparam使用如下:
@requestparam name必须存在的情况 | defaultvalue存在 | defaultvalue不存在 |
required为true | 请求中存在该参数 按照该参数来传递 | 请求中存在该参数 按照该参数来传递 |
请求中不存在该参数 使用默认值来传递 | 请求中不存在该参数 抛出缺少参数异常 | |
required为false | 请求中存在该参数 按照该参数来传递 | 请求中存在该参数 按照该参数来传递 |
请求中不存在该参数 使用默认值来传递 | 请求中不存在该参数 使用null来传递 |
总结就是请求中包含参数信息,就使用请求中的参数;使用默认值的情况除上图两种以外,比如请求中值为空字符串"" 且 defaultvalue不为null,那也是用defaultvalue;
三.@requestparam出现两种异常原因解析
spring @requestparam中可能抛出两种异常原因解释:
异常一. required int parameter 'age' is not present
异常原因:required为true 且 请求中不包含 对应的参数 ;
异常二.optional int parameter 'age' is present but cannot be translated into a null value due to being declared as a primitive type.
异常原因:required为false 且 defaultvalue不存在 且 参数类型为基本数据类型;