zoukankan      html  css  js  c++  java
  • Spring MVC POJO入参过程分析

    SpringMVC确定目标方法POJO类型的入参过程

    1、确认一个key:

      (1)、若目标方法的POJO类型的参数没有使用@ModelAttribute作为修饰,则key为POJO类名第一个字母的小写

      (2)、若使用@ModelAttribute来修饰,则key为@ModelAttibute注解的value属性值。

    1 @RequestMapping("/updateUser")
    2 public String update(User user){

      这里没有使用@ModelAttribute修饰,所有对应的key为POJO类名首字母小写,即为:user

    1 public String update(@ModelAttribute("abc") User user)

      这里使用了@ModelAttribute来修饰POJO,那么对应的可以为@ModelAttribute的value而值,即为:abc

     

      

    2、在implicitModel中查找key对应的对象。若存在,则作为参数传入

      (1)、若在@ModelAttibute标记的方法中在Map中保存过POJO,且key和1中确认的key一致,则会获取。例如:

     1 package com.proc;
     2 
     3 import java.util.Map;
     4 
     5 import org.springframework.stereotype.Controller;
     6 import org.springframework.web.bind.annotation.ModelAttribute;
     7 import org.springframework.web.bind.annotation.RequestMapping;
     8 import org.springframework.web.bind.annotation.RequestParam;
     9 
    10 @Controller
    11 public class UserController {
    12 
    13     
    14     @ModelAttribute
    15     public void getUser(@RequestParam(required=false) Integer id,Map map){
    16         if(id!=null){
    17             User user=new User();
    18             user.setId(1);
    19             user.setUsername("caoyc");
    20             user.setAge(18);
    21             user.setPassword("123456");
    22             map.put("user", user);
    23         }
    24     }
    25     
    26     @RequestMapping("/updateUser")
    27     public String update(@ModelAttribute("abc") User user){
    28         System.out.println("更新User对象为:"+user);
    29         return "success";
    30     }
    31 }

      JSP页面

     1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8" contentType="text/html; charset=utf-8"%>
     2 
     3 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
     4 <html>
     5   <head>
     6 
     7   </head>
     8   
     9   <body>
    10     <form action="updateUser" method="post">
    11         <input type="hidden" name="id" value="1">
    12         <table>
    13             <tr>
    14                 <td>用户名:</td><td><input type="text" name="username" value="caoyc"/></td>
    15             </tr>
    16             <tr>
    17                 <td>年龄:</td><td><input type="text" name="age" value="12"/></td>
    18             </tr>
    19             <tr>
    20                 <td></td><td><input type="submit" value="提交"></td>
    21             </tr>
    22            </table>
    23     </form>
    24   </body>
    25 </html>

      结果在控制台中输出:User [id=1, username=caoyc, password=123456, age=12]

        其中原因是:在方法/updateUser时对应的方法update( User user)时,先要执行@ModelAttribute标记的方法,而在@ModelAttribute中向implicitModel中保存了一个key为user的POJO对象。而此时update对象中参数的key为POJO类名首字母小写,也是user,也就是在implicitModel中存在该key和对应的POJO对象。那么就会以该对象作为原始值。而JSP页面中传入过来的POJO对象属性不为空且有变化的属性来修改原始值。

      原始对象:User [id=1, username=caoyc, password=123456, age=18]

      JSP中 :User[id=1, username=caoyc, password=null, age=12]

      这里需要修改的属性为age。在原始值得基础上修改了将age修改为12

      所以最总在implicitModel中key值为user的POJO对象为:User [id=1, username=caoyc, password=123456, age=12]

      

    3、座implicitModel中不存在key对应的对象,则检查当前的Handler是否使用了@SessionAttributes注解修饰,若使用了该注解,且@SessionAttribute注解的value属性值中包含了key,则会从HttpSession中获取key所对应的value值,若存在则直接传入到目标方法的入参中,若不存在则将抛出异常。

       Java代码

     1 @SessionAttributes(value={"user"})
     2 @Controller
     3 public class UserController {
     4 
     5     @RequestMapping("/updateUser")
     6     public String update(User user){
     7         //System.out.println("更新User对象为:"+user);
     8         return "success";
     9     }
    10 }

      此时,如果session中没有key为user的值,那么只需/updateUser时会抛出异常。因为在只需目标方法时,发现类有@SessionAttributes注解,且目标方法需要一个key为user的POJO对象,该key还存在@SessionAttributes注解的value中,所以会抛出异常。如果此时session中存在key为user的值,则将该值传入目标方法参数。

      怎么解决异常?

      方法一:添加一个使用@ModelAttribute的注解的方法,该方法向implicitModel保存一个为key为user的POJO

      方法二:去掉@SessionAttributes注解

      方法三:修改目标参数的key值。例如 @ModelAttribute(value="user2") User user

      

     

    4、若Handler没有标识@SessionAttributes注解或@SessionAttributes注解的value值中不包含key,则会通过反射来创建POJO类型的参数,并作为参数传入到目标方法

    5、SpringMVC会把key和POJO类型的对象保存到imlicitModel中,进而会保存到request中。

  • 相关阅读:
    链式结构(案例)
    基于JDK动态代理实现的接口链式调用(Fluent Interface)工具
    理解 OpenStack 高可用(HA)(3):Neutron 分布式虚拟路由(Neutron Distributed Virtual Routing)
    理解 OpenStack 高可用(HA)(2):Neutron L3 Agent HA 之 虚拟路由冗余协议(VRRP)
    Neutron 理解 (9): OpenStack 是如何实现 Neutron 网络 和 Nova虚机 防火墙的 [How Nova Implements Security Group and How Neutron Implements Virtual Firewall]
    Neutron 理解 (8): Neutron 是如何实现虚机防火墙的 [How Neutron Implements Security Group]
    Neutron 理解 (6): Neutron 是怎么实现虚拟三层网络的 [How Neutron implements virtual L3 network]
    Neutron 理解 (7): Neutron 是如何实现负载均衡器虚拟化的 [LBaaS V1 in Juno]
    Neutron 理解 (4): Neutron OVS OpenFlow 流表 和 L2 Population [Netruon OVS OpenFlow tables + L2 Population]
    Neutron 理解 (3): Open vSwitch + GRE/VxLAN 组网 [Netruon Open vSwitch + GRE/VxLAN Virutal Network]
  • 原文地址:https://www.cnblogs.com/caoyc/p/5636870.html
Copyright © 2011-2022 走看看