首页 > 代码库 > springMVC-model

springMVC-model

1.@SessionAttributes(String[] value,Class[] types)的使用(一种向session域中添加属性的方式)
    加在handler类上。
    >当响应的目标方法中有向request域中添加属性的操作时,若该属性名与value值中的一个相同,就将它也添加到session中;
        或者该属性类型与types中的一个相同,就将它也添加到session中。

2.ModelAttribute

MyHandler.java

package handler;

import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;

import model.User;

@SessionAttributes(value = { "username", }, types = { String.class })
@Controller
public class Handler {
    public static final String SUCCESS = "success";

    /**
     * 任何通过这个Handler的请求在执行目标方法之前都要执行@ModelAttribute修饰的getModel方法
     * 形参中的user只有表单上提交的属性值
     * 从数据库中取出对应的属性放到request中
     * */
    @ModelAttribute
    public void getModel(User user, Model map) {
        System.out.println("一"+user);
        if (user.getId() != null) {
            map.addAttribute("abc", new User(1, "Ji", "123"));
        }
    }
    
    
    /**(三个标*重点)
     * 模拟edit的一个场景。使表单上提交的项被赋到从数据库中得到的对象,而不是新的空对象。这样不能修改的项就不会为null
     * 表面的运行流程:
     * 1.执行@ModelAttribute注释的方法,从数据库中获取对应的对象并放入到request域中
     * 2.springMVC会将request域中以User(形参类型名)首字母小写为属性名的对象取出,将表单上的值赋给其对应的属性
     * 3.目标方法的形参就接受到了覆盖后的对象
     * 注意:若@ModelAttribute("abc")注释了形参,那么第二步中的user就会变成abc
     * 
     * 源码是怎么实现第二步的:(就算没有写 @ModelAttribute 注释的方法也会这么走)
     * 1.实际上把@ModelAttribute修饰的方法中的Map中的数据放到了implicitModel中
     * 2.解析目标方法的参数(就是@ModelAttribute("abc")User user),实际上它来自于WebDataBinder对象的target属性
     *     01.创建WebDataBinder对象
     *         001.*确定objectName属性:若传入的attrName属性为""(即没有用@ModelAttribute("abc")注释),
     *                             则objectName为参数类型名首字母小写;
     *                             若有用@ModelAttribute("abc")注释,attrName为abc,objectName为attrName
     *         002.确定target属性:
     *             >首先在implicitModel中查找objectName对应的属性值若存在就赋给target
     *             >*若不存在:看Handler是否使用了@SessionAttributes(value = http://www.mamicode.com/{"username", }),再在Session中查找,若
     *                 value中包含objectName,但session中又确实没有对应的属性值,那么抛出异常
     *             >以上若都没有得到target,那么就通过反射创建一个空的user对象
     *     02.springMVC把表单中的请求参数赋给WebDataBinder对象的target属性,实现覆盖。
     *     03*.springMVC把WebDataBinder的objectName和target给到implicitModel(相当于覆盖后又放到request域中了)
     *     04.把WebDataBinder的target传给形参user。
     * */
    @RequestMapping("/testModelAttribute")
    public ModelAndView testModelAttribute(@ModelAttribute("abc")User user) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.setViewName(SUCCESS);
        System.out.println(user);
        return modelAndView;
    }

    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Model model, HttpSession session) {

        model.addAttribute("username", "Ji");
        model.addAttribute("username2", "Yun");
        session.setAttribute("username3", "Fei");

        return SUCCESS;
    }

    @RequestMapping("/testSpringMVC")
    public String testSpringMVC() {
        System.out.println("testSpringMVC");
        return SUCCESS;
    }
}

 

springMVC-model