承接一二章
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作为参数传递给目标方法的入参 **/ }