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. 2018/6/29 关于hashmap的总结

    hashMap和ConcurrentHashMap的区别 hashMap内部具体如何实现的 如果hashMap的key是一个自定义的类,怎么办 为什么重写equals还要重写hashcode 一.什么 ...

  2. js-图片时间困难版(倒计时)

    <!DOCTYPE html><html>    <head>        <meta charset="UTF-8">      ...

  3. RPC、RMI、SOAP、WSDL的区别详解

    RPC与RMI的区别============================================================================RPC:(Remote Pr ...

  4. cxGrid动态设置单元格对齐方式

    cxGrid动态设置单元格对齐方式 2013年10月08日 00:52:49 踏雪无痕 阅读数:2150更多 个人分类: cxGrid   判断: //uses cxTextEditcxGrid1DB ...

  5. Java map的匿名类的初始化

    可以直接使用: Map<String, Object> testMap = new HashMap<String, Object>() { { put("test1& ...

  6. 国内代码托管平台(Git)

    可以说GitHub的出现完全颠覆了以往大家对代码托管网站的认识.GitHub不但是一个代码托管网站,更是一个程序员的SNS社区.GitHub真正迷人的是它的创新能力与Geek精神,这些都是无法模仿的. ...

  7. python36--将数据保存为excel

    #!/usr/bin/env python # -*- coding: utf-8 -*- import xlwt import os class ExcelHelper(object): @stat ...

  8. INDEX--从数据存放的角度看索引

    测试表结构: CREATE TABLE TB1 ( ID ,), C1 INT, C2 INT ) 1. 聚集索引(Clustered index) 聚集索引可以理解为一个包含表中除索引键外多有剩余列 ...

  9. 彻底卸载Oracle database 12c教程

    1.WIN+R,然后输入regedit,回车:2.在注册表中,进入目录:\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services,删除所有以oracl ...

  10. BZOJ 3357--[Usaco2004]等差数列(STL&DP)

    3357: [Usaco2004]等差数列 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 516  Solved: 241[Submit][Statu ...