springmvc 处理模型数据

springmvc中,模型数据是非常重要的,因为视图的渲染,需要模型数据,而模型数据的生成则在我们定义的controller中。

springmvc通过多种途经把模型数据暴露出来

  1. ModelAndView中,可以通过addObject(String attributeName, Object attributeValue)把数据添加到模型数据中

  2. @ModelAttribute 可以在方法的入参中,把入参数对象放到模型数据中

  3. Model 可以通过addAttribute(String attributeName, Object attributeValue)把对象添加到模型数据中

  4. Map和ModelMap可以通过put和get方法读写模型数据

  5. @SessionAttributes 将模型数据对象添加到HttpSession中,便于多个请求可以共享对象

ModelAndView包含视图信息和模型信息来处理视图和模型信息

添加模型数据
addObject(String attributeName, Object attributeValue);
addAllObjects(Map

@RequestMapping(value = { "", "/" })
public ModelAndView whatPage(
    @ModelAttribute("task") Task task, 
    Project project,  
    @ModelAttribute("address") String address, 
    String name) {
        return new ModelAndView("task/task");
    }

上面的例子中task,project和address会被放到模型数据中,name不会。

springmvc会把模型数据转存到ServletRequest的属性列表中,即通过
servletRequest的setAttribute(String name,Object o )保存,然后渲染的时候,会把视图模型数据拿出来进行渲染,如果前端渲染的视图是jsp页面的话,你可以通过${task.taskName}来获取任务名。

@ModelAttribute除了在方法入参中注解,也可以在方法级别上进行注解

@ModelAttribute
public Task getTask() {
    Task task = new Task();
    task.setTaskDetail("mydetai");
    task.setTaskName("mytaskName");
    return task;
}

springmvc在调用目标方法之前,都会先执行getTask方法,将task保存到模型数据中,那怎么获取模型数据呢

通过Map和ModelMap来获取模型数据中,springmvc会把Map和ModelMap对象绑定到方法入参中进行获取

@RequestMapping("/rmvc4")
public Map rmvc4(Map map){

    Task task = (Task)map.get("task");
    return map ;
}

@RequestMapping("/rmvc5")
public ModelMap rmvc5(ModelMap modelMap){

    Task task = (Task)modelMap.get("task");
    return modelMap ;
}

@ModelAttribute 原理是把对象绑定到request中,在一次请求共享数据,如果我们想在多个请求之间共享数据,可以通过@SessionAttributes 它会把对象绑定到httpSession中,在session级别上共享数据

@Controller
@RequestMapping("/task")
@SessionAttributes(value = { "task", "project", "name" })
public class TaskController {

   /** * task,project,name会保存到httpsession中 */
   @RequestMapping(value = { "", "/" })
   public ModelAndView whatPage(
    @ModelAttribute("task") Task task, 
    Project project, 
    @ModelAttribute("name") String name) {
        return new ModelAndView("task/task");
    }

    /** * 获取模型数据 */
    @RequestMapping("/rmvc4")
    public Map rmvc4(Map map){

        Task task = (Task)map.get("task");
        Project p = (Project)map.get("project");
        String name = (String)map.get("name");
        return map ;
    }

    /** * 方法级别上注解@ModelAttribute */
    @ModelAttribute
    public Task getTask() {
        Task task = new Task();
        task.setTaskDetail("mydetai");
        task.setTaskName("mytaskName");
        return task;
    }

}

SessionAttributes可以添加多个key来存储多个对象。接下来来看看SessionAttributes以及@ModelAttribute处理流程

  1. springmvc在调用任何方法处理之前,都会创建一个隐形的模型对象

  2. 调用方法级别的@ModelAttribute,即这里的getTask(),如果隐形的模型对象已经有task为key的模型对象则覆盖,如果没有则添加

  3. 查看类级别上是否有注解@SessionAttributes(“task”)所指定的task属性,如果有,则将getTask()返回的task进行覆盖httpsession中task为key的对象,如果没有则直接添加

  4. 在方法体的@ModelAttribute的处理如下

    a. 如果隐形模型中有key为”task”的属性,则覆盖,否则则添加

    b. 如果在类级别上有注解@SessionAttributes,则尝试从httpsession中拿出key为task的对象,然后再用请求消息填充该对象,如果在httpsession找不到该task属性,则会报抛出HttpSessionRequiredException异常

    c. 如果在类级别上没有标注@SessionAttributes,隐形模型数据中也没有task属性,则直接添加到隐形模型中

HttpSessionRequiredException异常的解决方法可以直接在方法级别上注解@ModelAttribute,这样如果在httpsession中找不到task属性,则直接调用getTask()方法返回task对象放到隐形模型中,这样方法入参中就会找到task为key的属性了

@SessionAttributes还可以通过type指定类,俩者都允许多个值

@SessionAttributes(value = {“task”,”project”}) 将模型中名为task和project添加到httpsession中

@SessionAttributes(type = {Task.class,Project.class}) 将模型中所有类型为Task和Project类添加到httpsession中

@SessionAttributes(value = {“task”,”project”},type = {Task.class} )将模型中名为task和project以及类为Task的放到httpsession中

你可能感兴趣的:(模型数据)