SpringMvc @RequestParam 使用推荐使用包装类型代替包装类型

 更新时间:2019年02月19日 11:28:28   作者:喜欢日向雏田一样的女子啊  
这篇文章主要介绍了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不存在 且 参数类型为基本数据类型;

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • mybatis执行批量更新batch update 的方法(oracle,mysql两种)

    mybatis执行批量更新batch update 的方法(oracle,mysql两种)

    这篇文章主要介绍了mybatis执行批量更新batch update 的方法,提供oracle和mysql两种方法,非常不错,需要的朋友参考下
    2017-01-01
  • java 三元操作符用法说明

    java 三元操作符用法说明

    这篇文章主要介绍了java 三元操作符用法说明,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • javax.servlet不存在的解决办法

    javax.servlet不存在的解决办法

    今天在关于servlet的编译中出现了一下小小的错误,发现javax.servlet不存在,本文就介绍一下解决方法,感兴趣的可以了解一下
    2021-07-07
  • 在SpringBoot中,如何使用Netty实现远程调用方法总结

    在SpringBoot中,如何使用Netty实现远程调用方法总结

    我们在进行网络连接的时候,建立套接字连接是一个非常消耗性能的事情,特别是在分布式的情况下,用线程池去保持多个客户端连接,是一种非常消耗线程的行为.那么我们该通过什么技术去解决上述的问题呢,那么就不得不提一个网络连接的利器——Netty,需要的朋友可以参考下
    2021-06-06
  • 一文读懂Spring Cloud-Hystrix

    一文读懂Spring Cloud-Hystrix

    这篇文章主要介绍了通过一文读懂Spring Cloud-Hystrix的相关知识,本文分步骤通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • SpringBoot集成gRPC微服务工程搭建实践的方法

    SpringBoot集成gRPC微服务工程搭建实践的方法

    这篇文章主要介绍了SpringBoot集成gRPC微服务工程搭建实践的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-01-01
  • IDEA2022搭建Spring Cloud多模块项目的详细过程

    IDEA2022搭建Spring Cloud多模块项目的详细过程

    这篇文章主要介绍了IDEA2022搭建Spring Cloud多模块项目,网上有很多教程父模块都是通过maven的方式创建的,然后子模块是通过Spring Initalizr方式创建,这种方式父模块无法管理子模块的依赖仲裁,需要每个子模块自行管理,就失去了父模块的用处了
    2022-10-10
  • MyEclipse如何将项目的开发环境与服务器的JDK 版本保持一致

    MyEclipse如何将项目的开发环境与服务器的JDK 版本保持一致

    我们使用MyEclipse开发Java项目开发中,偶尔会遇到因项目开发环境不协调,导致这样那样的问题,在这里以把所有环境调整为JDK1.6 为例,给大家详细介绍MyEclipse如何将项目的开发环境与服务器的JDK 版本保持一致,需要的朋友参考下吧
    2024-04-04
  • Java线程协调运行操作实例详解

    Java线程协调运行操作实例详解

    这篇文章主要介绍了Java线程协调运行操作,结合具体实例形式详细分析了Java线程协调运行原理、实现方法及相关操作注意事项,需要的朋友可以参考下
    2019-09-09
  • 一篇文章带你深入了解Java基础(3)

    一篇文章带你深入了解Java基础(3)

    这篇文章主要给大家介绍了关于Java中方法使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08

最新评论