springMVC---处理模型数据方法 *

承接一二章

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Hello World</title>
<a href="springMVC/ModelAndView">ModelAndView</a>
    <br> <br>
  <a href="springMVC/Map">map</a>
  <br> <br>
 <!-- 
    模型修改操作
    1, 原始数据为 1 tom 123456
    2, 密码不能别修改
    3,表单回显,模拟操作直接在表单填写对应的属性值
  -->
<form action="springMVC/testModelAttribute" method="get">
    <input type="hidden" name="id" value="1"/>
    <br>
     name<input type="text" name="username" value="tom"/> 
     <br>
     <!-- pw<input type="text" name="password" value="123456"/>  -->
     <input type="submit" value="submit" />
</form>
<br>
<br>
<form action="springMVC1/testModelAttribute" method="get">
    <input type="hidden" name="id" value="1"/>
    <br>
     name<input type="text" name="username" value="tom"/> 
     <br>
     <!-- pw<input type="text" name="password" value="123456"/>  -->
     <input type="submit" value="submit" />
</form>
</body>
</html>

test.java

package com.hdxy.domian;

import java.util.Arrays;
import java.util.Date;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.hdxy.pojo.User;

@RequestMapping("springMVC")
@Controller
public class Test {
  /*处理模型数据方法:
   * @1 ModelAndView(可以包含视图和模型信息)
   *     处理方法返回值类型为ModelAndView时:方法体即可通过该对象添加模型数据
   * @2Map 及 Model
   *     入参为:org.springframework.ui.Model,org.springframework.ui.ModelMap
   *     或者java.ui.Map时处理方法返回时,Map中的数据会自动添加到模型中。
   * @3 SessionAttributes:
   *    将模型中的某个属性暂存在HttpSession中以便多个请求之间可以共享这个参数
   * @4 ModelAttribute: 
   *    方法入参标注该注解后,入参的对象就会放入到数据模型中
   *  SpringMVC确定目标方法POJO类型入参的过程:
   *    1.确定一个Key
   *      1)。若目标方法的POJO类型的参数没有使用@ModeleAttriBute 作为修饰 则key额为POJO类名第一个字母小写
   *      2)。若使用了@MOdelAttribute来修饰,则key为@ModeleAttriBute注解的value属性值
   *    2.在implicitModel中查找key对应的对象,若存在,则作为入参传入
   *      1)。若在@ModelAttribute标记的方法中在Map中保存过,且key和1确定的key一至,则获取到
   *    3.若implicitModel中不存在key对应的对象,则检查当前handler是佛使用sessionAttrbute注解修饰
   *    若使用了该注解,则@sessionAttributes注解的value属性值中包含了key,则会从Httpsession中来获取key
   *    所对应额value值,若存在则直接传入目标参数方法中,若不存在则抛出异常
   *    4.若handler没有标识@sessionAttributes注解或@sessionAttributes注解的value值中不包含key,则
   *    会通过反射来创建pojo类型的参数,传入目标方法的参数
   *    5.SpringMVC会把key和value保存到implicitModel中,进而会保存到request中
   *     
   * */
   final public String SUCCESS="loginSuccess";
  

   @RequestMapping(value="/ModelAndView")
   public ModelAndView TestModelAndView(){
      String viewName= SUCCESS;
      ModelAndView modelv=new ModelAndView(viewName);
      modelv.addObject("time",new Date());
    return modelv;
   }
   
   @RequestMapping("/Map")
   public String TestMap(Map<String,Object> map){
       /*System.out.println(map.getClass().getName());//测试ModelMap*/
       map.put("names", Arrays.asList("tom","jerry","2"));
       return SUCCESS;
   }
   
   
   @RequestMapping("/testModelAttribute")
   public String testModelAttribute(User user){
       //此方法从新new了一个User类 去赋修改后的值 得到的密码为空。(无法满足不修改密码的需求)
       //(test2.java)而ModelAttribute是从数据库获取User类(把修改的属性赋值,无修改的显示原先值) 然后赋值
       System.out.println("修改"+user);
       return SUCCESS;
   }
}

test2.java

package com.hdxy.domian;

import java.util.Map;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.hdxy.pojo.User;

@RequestMapping("/springMVC1")
@Controller
public class Test2 {
    final public String SUCCESS="loginSuccess";
    @ModelAttribute
    public void getUser(@RequestParam(value="id",required=false)Integer id,
            Map<String,Object> map){
        if(id !=null){
            //模拟从数据库中获取对象
            User user=new User();
            user.setId(1);
            user.setUsername("tom");
            user.setPassword("123456");
            System.out.println("从数据库中获取user"+user);
            /*map.put("adc", user);*/
            map.put("user", user);
        }
    }
/**
 * 运行流程
 * 1.执行:@ModelAttribute注解修饰的方法:从数据库中取出对象,放入到Map中 键值为: user
 
 * 2.springMVC从Map中取出user对象,并把表单的请求参数赋值给user对象对应属性
 * 3.SpringMVc把上述对象传入目标方法的参数中
 * 
 * 注: 在@ModelAttribute注解修饰的方法中,(只能修饰类)
 * 放入到Map时的键值 需要和 目标方法入参类型的第一个字母小写的字符串一致
 * 
 * Parma("abc")User user
 * */
       @RequestMapping("/testModelAttribute")
       public String testModelAttribute(User user){
           System.out.println("测试SpringMVC1");
           System.out.println("修改"+user);
           return SUCCESS;
       }
       
      /**
       *源码分析:
       *1.调用@ModelAttribute注解修饰的方法,实际上把ModelAttribute方法中的Map中的数据放在implicitModel中
       *2.解析请求处理器的目标参数来自于webDataBinder 对象的target属性
       *1).创建webdatabinder对象:
       *--确定ObjectName属性(若传入的attrname属性值为:“”,则objectName为类名的第一个字母小写)。
       *注意:attrName 若目标犯法的pojo属性使用了ModelAttribute 来修饰,则attrname 值为ModelAttribute的value属性值
       *---确定target属性:
       *   在implicitModel中查找attrName对应的属性值,如果存在,Ok 
       *   >若不存在:则验证当前handel石佛使用了@sessionAttributes进行修饰,若使用了,则尝试从session中获取attrName所对应的属性值
       *     若session没有则抛出异常
       *   >若handle没有使用@sessionAttributes 进行修饰,或@sessionAttributtes中没有使用value 值指定的key和attrName 相匹配,则通过反射创建POJO类
       * 2),  SpringMVC把表单的请求赋给了webdataBinder的target对应的属性
       * 3),springMVC会把webDataBinder的target和attrname给implicitModel
       * 4),把webDataBinder的target作为参数传递给目标方法的入参
       **/
}
原文地址:https://www.cnblogs.com/lnthz/p/8168834.html