Spring MVC 视图层解析
调用 Web 资源给域对象传值。pagerequestsessionapplication业务数据的绑定是指将业务数据绑定给 JSP 域对象,业务数据的绑定是由 ViewResolver 来完成的,开发时,我们先添加业务数据,再交给 ViewResolver 来绑定。Spring MVC 提供了以下几种方式来添加业务数据:MapModelModelAndVIew@SessionAttribute@
调用 Web 资源给域对象传值。
- page
- request
- session
- application
业务数据的绑定是指将业务数据绑定给 JSP 域对象,业务数据的绑定是由 ViewResolver 来完成的,开发时,我们先添加业务数据,再交给 ViewResolver 来绑定。
Spring MVC 提供了以下几种方式来添加业务数据:
- Map
- Model
- ModelAndVIew
- @SessionAttribute
- @ModelAttributes
- Servet API
一、业务数据绑定到 request 域对象
创建实体类 User
package com.southwind.pojo;
import lombok.Data;
@Data
public class User {
private Integer id;
private String name;
private Address address;
}
1、Map
Spring MVC 在调用业务方法之前会创建一个隐含对象作为业务数据的存储容器,设置业务方法的入参为 Map 类型,Spring MVC 会将隐含对象的引用传递给入参。
Controller代码:
@RequestMapping("/map")
public String map(Map<String, Object> map){
User user = new User();
user.setId(1);
user.setName("张三");
map.put("user",user);
return "show";
}
jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<body>
${user}
</body>
</html>
结果:
User(id=1, name=张三, address=null)
2、Model
Model 与 Map 类似,业务方法通过入参来完成业务数据的绑定。
Controller
@RequestMapping("/model")
public String model(Model model){
User user = new User();
user.setId(1);
user.setName("王五");
model.addAttribute("user", user);
return "show";
}
jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<body>
${user}
</body>
</html>
结果
User(id=1, name=王五, address=null)
3、ModelAndView
与 Map 或者 Model 不同的是,ModelAndView 不但包含业务数据,同时也封装了视图信息,如果使用 ModelAndVIew 来处理业务数据,业务方法的返回值必须是 ModelAndVIew 对象。
业务方法中对 ModelAndVIew 进行两个操作:
- 填充业务数据
- 绑定视图信息
Controller
@RequestMapping("/mav1")
public ModelAndView mav1(){
User user = new User();
user.setId(1);
user.setName("张三");
ModelAndView mav = new ModelAndView();
// 填充业务数据
mav.addObject("user", user);
// 绑定视图信息
mav.setViewName("show");
return mav;
}
@RequestMapping("/mav2")
public ModelAndView mav2(){
User user = new User();
user.setId(2);
user.setName("李四");
ModelAndView mav = new ModelAndView();
mav.addObject("user", user);
View view = new InternalResourceView("/show.jsp");
mav.setView(view);
return mav;
}
@RequestMapping("/mav3")
public ModelAndView mav3(){
ModelAndView mav = new ModelAndView("show");
User user = new User();
user.setId(1);
user.setName("张三");
mav.addObject("user", user);
return mav;
}
@RequestMapping("/mav4")
public ModelAndView mav4(){
View view = new InternalResourceView("/show.jsp");
ModelAndView mav = new ModelAndView(view);
User user = new User();
user.setId(2);
user.setName("李四");
mav.addObject("user", user);
return mav;
}
@RequestMapping("/mav5")
public ModelAndView mav5(){
User user = new User();
user.setId(1);
user.setName("张三");
Map<String, Object> map = new HashMap<>();
map.put("user", user);
ModelAndView mav = new ModelAndView("show", map);
return mav;
}
@RequestMapping("/mav6")
public ModelAndView mav6(){
View view = new InternalResourceView("/show.jsp");
User user = new User();
user.setId(2);
user.setName("李四");
Map<String, Object> map = new HashMap<>();
map.put("user", user);
ModelAndView mav = new ModelAndView(view, map);
return mav;
}
@RequestMapping("/mav7")
public ModelAndView mav7(){
View view = new InternalResourceView("/show.jsp");
User user = new User();
user.setId(1);
user.setName("张三");
ModelAndView mav = new ModelAndView(view, "user", user);
return mav;
}
@RequestMapping("/mav8")
public ModelAndView mav8(){
User user = new User();
user.setId(2);
user.setName("李四");
ModelAndView mav = new ModelAndView("show", "user", user);
return mav;
}
4、HttpServletRequest
Spring MVC 可以在业务方法中直接获取 Servlet 原生 Web 资源,只需要在方法定义时添加 HttpServletRequest 入参即可,在方法中直接使用 request 对象。
@RequestMapping("/request")
public String request(HttpServletRequest request){
User user = new User();
user.setId(1);
user.setName("张三");
request.setAttribute("user", user);
return "show";
}
5、@ModelAttribute
Spring MVC 还可以通过 @ModelAttribute 注解的方式添加业务数据,具体使用步骤如下:
- 定义一个方法,该方法用来放好要填充到业务数据中的对象
- 给该方法添加 @ModelAttribute 注解,不是响应请求的业务方法
@RequestMapping("/modelAttribute")
public String modelAttribute(){
return "show";
}
@ModelAttribute
public User getUser(){
User user = new User();
user.setId(10);
user.setName("小明");
return user;
}
@ModelAttribute 注解的作用是,当 Handler 接收到一个客户端请求之后,无论调用哪个业务方法,都会优先调用被 @ModelAttribute 注解修饰的方法,并将其返回值作为业务数据,再进入到业务方法,此时业务方法只需要返回视图信息即可,不需要返回业务数据,即使返回业务数据,也会被 @ModelAttribute 注解修饰的方法返回的数据所覆盖。
域对象中存值都是以 key-value 形式存储的,那么此时的 key 值是什么?默认值是业务数据对应的类的类名首字母小写之后的结果。
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<body>
${user}
</body>
</html>
如果 getUser 没有返回值,则必须手动在该方法中填充业务数据,使用 Map 或者 Model 即可。
@ModelAttribute
public void getUser(Model model){
User user = new User();
user.setId(122);
user.setName("小红");
model.addAttribute("user", user);
}
如果同时存在两个 @ModelAttribute 注解方法
@ModelAttribute
public User getUser(){
User user = new User();
user.setId(10);
user.setName("小明");
return user;
}
@ModelAttribute
public void getUser(Model model){
User user = new User();
user.setId(122);
user.setName("小红");
model.addAttribute("user", user);
}
直接给 Model 对象进行装载的方法优先级更高。
二、业务数据绑定到 session 域对象
1、HttpSession
Controller
@RequestMapping("/session")
public String session(HttpSession session){
User user = new User();
user.setId(11);
user.setName("王五");
session.setAttribute("user", user);
return "show";
}
jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<body>
${sessionScope.user}
</body>
</html>
2、@SessionAttributes
@SessionAttributes 注解不是给方法添加的,而是给类添加的。
Controller
@Controller
@RequestMapping("/view")
@SessionAttributes(value = "test")
public class ViewController {
@RequestMapping("/test")
public ModelAndView test(){
User user = new User();
user.setId(11);
user.setName("王五");
ModelAndView mav = new ModelAndView();
mav.addObject("test", user);
mav.setViewName("show");
return mav;
}
}
jsp
<%@page contentType="text/html; charset=UTF-8" language="java" %>
<%@page isELIgnored="false" %>
<html>
<body>
${requestScope.test} <br>
${sessionScope.test}
</body>
</html>
结果
User(id=11, name=王五, address=null)
User(id=11, name=王五, address=null)
只要给类添加了 @SessionAttributes 注解之后,无论类中的哪个业务方法被访问,将业务数据绑定到 request 域对象的同时,也会将业务数据绑定到 session 域对象中,也就是说 request 和 session 对象会同时存在业务数据,前提是 request 域中的 key 值需要和 @SessionAttributes 注解中的 value 值一致。
@SessionAttributes 除了可以通过 key 值绑定,也可以通过业务数据的数据类型进行绑定。
@Controller
@SessionAttributes(type = User.class){
...
}
@SessionAttributes 可以同时绑定多个业务数据
@Controller
@SessionAttributes(value = {"user", "address"}){
...
}
或者
@Controller
@SessionAttributes(type = {User.class, Address.class}){
...
}
更多推荐
所有评论(0)