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 | 请求中存在该参数 & nbsp; 按照该参数来传递 | 请求中存在该参数 & nbsp; 按照该参数来传递 |
请求中不存在该参数 & nbsp; 使用默认值来传递 | 请求中不存在该参数 & nbsp; 抛出缺少参数异常 | |
required 为 false | 请求中存在该参数 & nbsp; 按照该参数来传递 | 请求中存在该参数 & nbsp; 按照该参数来传递 |
请求中不存在该参数 & nbsp; 使用默认值来传递 | 请求中不存在该参数 & nbsp; 使用 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 不存在 且 参数类型为基本数据类型;
来源: https://www.cnblogs.com/lvbinbin2yujie/p/10398652.html