SpringMVC学习(4):模型数据处理

版权声明:本文为博主原创文章,欢迎转载,转载请注明作者、原文超链接 ! https://blog.csdn.net/jex00000/article/details/86673850

前言

SpringMVC框架作为一个MVC框架,很重要的一项工作是在控制器获取模型数据并返回给客户端,即在JSP页面展示模型数据,使用的技术是通过EL表达式从域对象中取值。

JSP四大作用域对应的四个内置对象分别是 request,session,pageContext,application。开发中经常用到的域对象是request和session,pageContext和application可以通过获取原生Servlet资源的方式进行绑定,实际开发中使用不多。

处理模型数据是由ViewResolver来完成的,开发时,我们需要先添加模型数据,再交给ViewResolver来处理。

SpringMVC提供了以下方式添加模型数据:

Map 及 Model

ModelAndView

HttpServletRequest

@ModelAttribute

@SessionAttributes

Map 及 Model

SpringMVC在内部使用Model接口存储模型数据,在调用业务方法前会创建一个隐含对象作为模型数据的存储容器。入参为java.uti.Map、org.springframework.ui.Model 或 org.springframework.ui.ModelMap 时,处理方法返回时,Map 中的数据会自动添加到模型中。

具体步骤:

(1)Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。

(2) 如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据。

入参为 Map 类型的业务方法:

    @RequestMapping("/testMap")
    public String testMap(Map<String,Object> map){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        map.put("user", user);
        return "index";
    }

入参为 Model 类型的业务方法:

    @RequestMapping("/testModel")
    public String testModel(Model model){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        model.addAttribute("user", user);
        return "index";
    }

业务方法完成后,返回模型数据和视图信息给DispatcherServlet,DispatcherServlet通过ViewResolver将逻辑视图映射到物理视图,同时将模型数据绑定到JSP的request域对象中,在JSP页面,可直接通过EL表达式取值。

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></title>
</head>
<body>
id: ${user.id}
名字:${user.name}
</body>
</html>

运行:

image

image

ModelAndView

处理方法返回值类型为ModelAndView时, 方法体即可通过该对象添加模型数据。与Map或者Model不同的是,ModelAndView不但包含模型数据,同时也包含了视图信息,所以使用ModelAndView来处理模型数据,业务方法的返回值必须是ModelAndView。

目标方法的返回值是 ModelAndView 类型,其中可以包含视图和模型信息,SpringMVC 会把 ModelAndView 的 model 中数据放入到 request 域对象中.

ModelAndView的使用有8种方式:

    @RequestMapping("/testModelAndView1")
    public ModelAndView testModelAndView1(){
        ModelAndView modelAndView = new ModelAndView();
        User user = new User();
        user.setId(1);
        user.setName("jex");
        modelAndView.addObject("user", user);
        modelAndView.setViewName("index");
        return modelAndView;
    }

    @RequestMapping("/testModelAndView2")
    public ModelAndView testModelAndView2(){
        ModelAndView modelAndView = new ModelAndView();
        User user = new User();
        user.setId(1);
        user.setName("jex");
        modelAndView.addObject("user", user);
        View view = new InternalResourceView("/index.jsp");
        modelAndView.setView(view);
        return modelAndView;
    }

    @RequestMapping("/testModelAndView3")
    public ModelAndView testModelAndView3(){
        ModelAndView modelAndView = new ModelAndView("index");
        User user = new User();
        user.setId(1);
        user.setName("jex");
        modelAndView.addObject("user", user);
        return modelAndView;
    }

    @RequestMapping("/testModelAndView4")
    public ModelAndView testModelAndView4(){
        View view = new InternalResourceView("/index.jsp");
        ModelAndView modelAndView = new ModelAndView(view);
        User user = new User();
        user.setId(1);
        user.setName("jex");
        modelAndView.addObject("user", user);
        return modelAndView;
    }

    @RequestMapping("/testModelAndView5")
    public ModelAndView testModelAndView5(){
        Map<String,Object> map = new HashMap<String,Object>();
        User user = new User();
        user.setId(1);
        user.setName("jex");
        map.put("user", user);
        ModelAndView modelAndView = new ModelAndView("index", map);
        return modelAndView;
    }

    @RequestMapping("/testModelAndView6")
    public ModelAndView testModelAndView6(){
        Map<String,Object> map = new HashMap<String,Object>();
        User user = new User();
        user.setId(1);
        user.setName("jex");
        map.put("user", user);
        View view = new InternalResourceView("/index.jsp");
        ModelAndView modelAndView = new ModelAndView(view, map);
        return modelAndView;
    }

    @RequestMapping("/testModelAndView7")
    public ModelAndView modelAndViewTest7(){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        ModelAndView modelAndView = new ModelAndView("index", "user", user);
        return modelAndView;
    }

    @RequestMapping("/testModelAndView8")
    public ModelAndView testModelAndView8(){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        View view = new InternalResourceView("/index.jsp");
        ModelAndView modelAndView = new ModelAndView(view, "user", user);
        return modelAndView;
    }

运行:
image

HttpServletRequest

SpringMVC可以在业务方法直接获取到Servlet原生web资源,只需在方法定义时添加HttpServletRequest入参即可,在方法体中,可直接对request对象进行操作。

    @RequestMapping("testRequest")
    public String testRequest(HttpServletRequest request){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        request.setAttribute("user", user);
        return "index";
    }

运行:
image

@ModelAttribute

@ModelAttribute是方法入参标注该注解后, 入参的对象就会放到数据模型中。

使用:

1.定义一个方法,该方法用来返回要填充到模型数据中的对象
2.给该方法添加@ModelAttribute注解

**注意:**添加@ModelAttribute注解的方法并不是响应请求的业务方法,会在SpringMVC在调用任何一个业务方法之前被自动调用。

   @RequestMapping("/testModelAttribute")
    public String testModelAttribute(){
        return "index";
    }

    @ModelAttribute
    public User getUser(){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        return user;
    }

在执行modelAttributeTest业务方法之前,会先调用@ModelAttribute修饰的getUser方法,获取返回值user对象,SpringMVC框架会自动将该对象填充到模型数据中,进而绑定到域对象中。因为域对象中的数据都是以键值对(key-value)的形式保存的,所以默认会取模型数据对应类的类名首字母小写,即User类首字母小写"user",所以JSP页面中,可以直接通过"user"取值。

若getUser没有放回值,则必须使用Map或者Model手动在该方法中填充模型数据。

    @ModelAttribute
    public void getUser2(Map<String,Object> map){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        map.put("user", user);
    }

    @ModelAttribute
    public void getUser3(Model model){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        model.addAttribute("user", user);
    }

运行:
image

@SessionAttributes

默认情况下Spring MVC将模型中的数据存储到request域中,上面提到的方式全部是将模型中的数据存储到request域中。当一个请求结束后,数据就失效了。如果要跨页面使用。那么需要使用到session。而@SessionAttributes注解就可以使得模型中的数据存储一份到session域中。如果需要将模型数据绑定到session对象中,只需要在类定义处添加@SessionAttributes(value=“user”)注解即可。

参数:
1、types:根据指定参数的类型,将模型中对应类型的参数存储到session中
2、value:里面应写需要存储到session中数据的名称。

@Controller
@SessionAttributes(value = { "user" })
public class HelloController {

@SessionAttributes除了可以通过key值绑定,还可以通过模型数据的数据类型绑定

@Controller
@SessionAttributes(types=User.class)
public class HelloController {

@SessionAttributes也可以同时绑定多个模型数据

@Controller
@SessionAttributes(value={"user","address"})
public class HelloController {

或者

@Controller
@SessionAttributes(types={User.class,Address.class})
public class HelloController {

此时,无论通过上面提到的哪种方式将模型数据绑定到request对象中的同时,也会将模型数据绑定到session对象中,request和session对象中同时存在模型数据。

业务方法:

    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(ModelMap modelMap){
        User user = new User();
        user.setId(1);
        user.setName("jex");
        modelMap.addAttribute("user",user);
        return "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></title>
</head>
<body>
session中id:${sessionScope.user.id }
session中name:${sessionScope.user.name }
</body>
</html>

运行:
image

源码

链接:https://pan.baidu.com/s/14gJ-rfAir-C4jtdZ_puVmA
提取码:66vn


猜你喜欢

转载自blog.csdn.net/jex00000/article/details/86673850