文章目录

  • SpringMVC响应和数据模型
  • 1.1 @ResponseBody
  • 1.2 数据模型
  • 1.3 SpringMVC整合模板引擎
  • 1.3.1 对默认的视图解析器进行优化
  • 1.3.2 整合freemarker


SpringMVC响应和数据模型

1.1 @ResponseBody

  1. 直接响应数据,不涉及到视图
  2. 可以是标准的字符串,也可以是结构化数据(xml/json)
  3. 会被StringHttpMessageConverter影响

1.2 数据模型

SpringMVC提供的数据模型是为了解决特定作用域内封装数据的组件

前面由于HTTP协议的无状态性,我们想去实现购物车保存数据的功能是很难的,所以之前学习的Servlet为我们提供了 3 种作用域:

  1. 请求作用域:HttpServletRequest组件中存储的数据,可以在一次请求的生命周期中存在
  2. 会话作用域:HttpSession组件中存储的数据,可以在一次会话的生命周期中存在
  3. 应用程序作用域:ServletContext组件保存的数据可以在整个应用程序生命周期中存在

在SpringMVC中提供的数据模型的组件:

  1. Model
  2. ModelMap
  3. ModelAndView

本质其实就是对HttpServletRequest对象中的存储数据的Map集合做的引用

上代码:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>成功的页面</title>
  </head>
<body>
当前用户名:${username}
</body>
</html>
@Controller
@RequestMapping("mav")
public class ModelAndViewController {

@PostMapping("/getcomplexdata")
// public String getComplexData(Form form, HttpServletRequest request){
// public String getComplexData(Form form, Model model){
// public String getComplexData(Form form, ModelMap model){
public ModelAndView getComplexData(Form form){
// String username = request.getParameter("username");
System.out.println(form);
ModelAndView modelAndView = new ModelAndView("/success.jsp");
// modelAndView.setViewName("/success.jsp");
modelAndView.addObject("username", "木子么么哒2~");
// model.addAttribute("username", "木子3");
// request.setAttribute("username","木子");
// return "/success.jsp";
return modelAndView;
}

在之前代码的基础上,去掉@ResponseBody注解,这样,SpringMVC会根据返回的String的数据,去找对应的视图

建议加上/代表使用绝对路径,如果使用相对路径,则需要在根路径下,一层一层创建对应的文件夹和文件

比如上述的例子中,如果请求要被处理,实际的请求路径是
localhost:8080/mav/getcomplexdata,是通过这个路径找到success.jsp,所以这个页面必须存在于/mav/success.jsp

还有默认情况下,响应页面都是请求转发(forward),如果想让其做重定向,可以使用redirect:前缀,告诉程序需要重定向
源码:

public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {

 //重定向的前缀
public static final String REDIRECT_URL_PREFIX = "redirect:";
//请求转发的前缀(默认)
public static final String FORWARD_URL_PREFIX = "forward:";
{

@PostMapping("/getcomplexdata")
// public String getComplexData(Form form, HttpServletRequest request){
// public String getComplexData(Form form, Model model){
public String getComplexData(Form form, ModelMap model){
// public ModelAndView getComplexData(Form form){
// String username = request.getParameter("username");
System.out.println(form);
// ModelAndView modelAndView = new ModelAndView("redirect:/success.jsp");
// modelAndView.setViewName("/success.jsp");
// modelAndView.addObject("username", "木子么么哒2~");
model.addAttribute("username", "木子3");
// request.setAttribute("username","木子");
//默认是请求转发
// return "redirect:success.jsp";
return "forward:success.jsp";
// return modelAndView;
}

默认情况下,Model,ModelMap,ModelAndView数据模型组件,其保存的数据都是在请求作用域中的

如果想提升数据的作用域,在SpringMVC中可以使用@SessionAttributes

@Controller
@RequestMapping("mav")

@SessionAttributes(names = {"username"})

public class ModelAndViewController {
@PostMapping("/getcomplexdata")
public String getComplexData(Form form, ModelMap model){
System.out.println(form);
model.addAttribute("username", "木子3");
return "forward:/success.jsp";
}
}

1.3 SpringMVC整合模板引擎

1.3.1 对默认的视图解析器进行优化

<!-- 显示的配置视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置视图名字的前缀:一般设置为存放模板引擎文件的公共目录 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 配置视图名字的后缀:一般是模板引擎的格式 -->
<property name="suffix" value=".jsp"/>
<!-- 避免中文乱码,也可以减少每次都需要在JSP头部加
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
-->
<property name="contentType" value="text/html;charset=UTF-8"/>
</bean>
@PostMapping("/getcomplexdata")
public String getComplexData(Form form, ModelMap model){
System.out.println(form);
model.addAttribute("username", "木子3");
// 根据设置的前缀后缀,实际页面的路径为
// /WEB-INF/jsp/success.jsp
// return "success";
//如果想和之前一样,自定从绝对路径或者相对路径定位完整文件路径的话
//需要加上forward: 或者 redirect 前缀,打破视图解析器的配置
return "forward:/success.jsp";
}

1.3.2 整合freemarker

<!-- freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<!-- spring-context-support包不仅仅能够帮助Spring整合第三方的模板引擎,当Spring整合缓存,定时任务的时候也需要它-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!-- 配置视图名字的后缀:一般是模板引擎的格式 -->
<property name="suffix" value=".ftl"/>
</bean>
<bean
class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<!-- 这里配置了模板引擎文件放置的位置,就不用配置视图解析器的前缀了 -->
<property name="templateLoaderPath" value="/WEB-INF/ftl/"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>

/WEB-INF/ftl/first.ftl

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Freemarker</title>
</head>
<body>
<h1>${username}</h1>
</body>
</html>
@Controller
@RequestMapping("fm")
public class FreeMarkerController {
@GetMapping("/first")
public ModelAndView test(){
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("first");
modelAndView.addObject("username", "木子");
return modelAndView;
}
}