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不存在  且 参数类型为基本数据类型;

SpringMvc @RequestParam 使用推荐使用包装类型代替包装类型的更多相关文章

  1. 【转】springmvc @RequestParam

    在SpringMVC后台控制层获取参数的方式主要有两种,一种是request.getParameter("name"),另外一种是用注解@RequestParam直接获取.这里主要 ...

  2. js基本类型的包装对象

    var test = "test"; test.a = "hello"; console.log(test.a); 在JavaScript中,“一切皆对象”,数 ...

  3. ongl(原始类型和包装类型)

    原始类型和包装类型 //首先创建两个实体类 user 和 address user中包含address package cn.jbit.bean; public class User { //用户类 ...

  4. js常用API 数据类型 基本类型,基本包装类型,引用类型 Object String Array Boolean Number Date Math

    数据类型 变量.作用域及内存 基础类型(primitive value):Undefined.Null.Boolean.Number和String.这些类型在内存中分别占用固定大小的空间,他们的值保存 ...

  5. 一道js题(引用类型、基本类型、包装对象、函数赋值)

    var a = 1; var obj = {     b: 2 }; var fn = function () {}; fn.c = 3;   function test(x, y, z) {     ...

  6. python基础之类的内置__setattr__,__delattr__,__getattr__和 二次加工标准类型(包装)

    一.内置attr:__setattr__,__delattr__,__getattr__ __setattr__ #添加/修改属性会触发它的执行 __delattr__ #删除属性的时候会触发 __g ...

  7. springmvc 类型转换器 自定义类型转换器

    自定义类型转换器的步骤: 1.定义类型转换器 2.类型转换器的注册(在springmvc配置文件处理) 来解决多种日期格式的问题: springmvc 类型转换器 表单数据填错后返回表单页面(接上面的 ...

  8. String类型和包装类型作为参数传递时,是属于值传递还是引用传递呢?

    原理知识: 如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的.如果在函数中改变了副本的 值不会改变原始的值. 如果参数类型是引用类型,那 ...

  9. JS 基本类型的包装对象

    笔记整理自:廖雪峰老师的JS教程 目录 包装对象 不写new的作用 总结 注意 包装对象 JavaScript还提供了包装对象,熟悉Java的小伙伴肯定很清楚int和Integer这种暧昧关系. nu ...

随机推荐

  1. ASP.NET Web API 框架研究 ASP.NET Web API 路由

    ASP.NET Web API 核心框架是一个独立的.抽象的消息处理管道,ASP.NET Web API有自己独立的路由系统,是消息处理管道的组成部分,其与ASP.NET路由系统有类似的设计,都能找到 ...

  2. Python自动化开发 - 面向对象(一)

    本节内容 1.编程范式 面向过程编程 面向对象编程 2.面向对象编程介绍 类的语法 类与实例内存分配 构造方法 自定义方法 3.面向对象特性 一.编程范式 编程是程序员 用特定的语法+数据结构+算法组 ...

  3. 有关VS报错Files的值XXX

    从网上下载了一个实例来学习,但是运行的时候报错:Files的值(后面跟一堆符号,看不懂), 环境:安装了易赛通加密软件(估计可能跟这个加密软件有关系了) 解决方案:找到程序根目录的obj/Debug/ ...

  4. spring项目读取配置的demo

    背景 读取配置是基础能力,研发这个模式不错,可以从不同配置中读取数据,如下图: 可以根据不同分类的文件来管理配置,然后统一在conf中配置哪些文件 package com.jwen.platform. ...

  5. 使用System.Net.Mail中的SMTP发送邮件(带附件)

    System.Net.Mail 使用简单邮件传输协议SMTP异步发送邮件 想要实现SMTP发送邮件,你需要了解这些类 SmtpClient :使用配置文件设置来初始化 SmtpClient类的新实例. ...

  6. DOM扩展:DOM API的进一步增强[总结篇-下]

    本文承接<DOM扩展:DOM API的进一步增强[总结篇-上]>,继续总结DOM扩展相关的功能和API. 3.6 插入标记 DOM1级中的接口已经提供了向文档中插入内容的接口,但是在给文档 ...

  7. ceph 源码安装 configure: error: "Can't find boost spirit headers"

    问题:configure: error: "Can't find boost spirit headers" 解决: 推荐:sudo apt-get install libboos ...

  8. 暴破助攻提权:ruadmin

    i春秋作家:yangyangwithgnu 1 缘由 千辛万苦拿下的 webshell 不是 www-data 用户就是 networkservice 权限,要想拓展攻击面.扩大战果,提权,是必经之路 ...

  9. [JavaScript] html5 video标签注意事项

    Chrome 66 禁止声音自动播放 声音无法自动播放这个在IOS/Android上面一直是个惯例,桌面版的Safari在2017年的11版本也宣布禁掉带有声音的多媒体自动播放功能,紧接着在2018年 ...

  10. 将 Microsoft Excel 导入至 MySQL

    将 Microsoft Excel 导入至 MySQL 一.前言 我得到了一份 Microsoft Excel 表格,里面记录了数据信息需要导入至 SQL 数据库. 如果只是导入数据,当然用 MSSQ ...