Spring MVC响应处理
使用SpringMVC提供的方式来获取请求信息,然后根据功能需求,声明请求处理的逻辑代码,进行请求的处理。当请求处理完成后,我们需要将此次请求的处理结果响应给浏览器,那么springmvc对应响应的处理方式主要包含一下几个:
一、控制器方法返回值为void
1.在com.augus.controller下面创建ResponseController
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class ResponseController { /** * 控制器方法返回值为void,没有指定返回值,就会以方法名和前置后缀进行拼接 * */ @RequestMapping("/testReturnVoid") public void testReturnVoid(){ System.out.println("执行了testReturnVoid"); } }
2.重新部署项目,访问http://localhost:8080/springmvc_01_war_exploded/testReturnVoid,如下:
需要注意的是在SpringMVC中如果对于当前的控制单元,没有写对应的返回值,这个时候SpringMVC就会找和自己控制单元名称一致的页面展示,如果没有配置视图解析器的前缀和后缀是没有产生404,
二、转发和重定向
1.ServletAPI 实现转发和重定向
1.1.在view下创建index.jsp和main.jsp
<%-- Created by IntelliJ IDEA. User: Augus Date: 2022/9/6 Time: 12:28 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html lang="en"> <head> <meta charset="UTF-8"> <title>springmvc学习网站</title> </head> <body> <h1>欢迎您来到springmvc学习网站</h1> </body> </html>
<%-- Created by IntelliJ IDEA. User: Augus Date: 2022/9/6 Time: 12:28 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html lang="en"> <head> <meta charset="UTF-8"> <title>springmvc学习网站</title> </head> <body> <h1>注册成功</h1> </body> </html>
1.2.com.augus.controller下面创建ResponseController
分别设置三个方法:testIndex、testMain和testServletForwardRedirect,其中访问testServletForwardRedirect的时候testIndex、testMain分别作为请求转发、响应重定向的方法地址
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Controller public class ResponseController {//请求转发时的控制器方法 @RequestMapping("/testIndex") public String testIndex(){ System.out.println("执行了testReturnVoid"); return "index"; } //响应重定向时的控制器方法 @RequestMapping("/testMain") public String testMain(){ System.out.println("执行了testReturnVoid"); return "main"; } /** * ServletAPI 实现转发和重定向 */ @RequestMapping("/testServletForwardRedirect") public void testServletForwardRedirect(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //请求转发:让他跳转到另一个控制器方法 //request.getRequestDispatcher("/testIndex").forward(request,response); //响应重定向 response.sendRedirect(request.getContextPath()+"/testMain"); } }
1.3.部署项目访问http://localhost:8080/springmvc_01_war_exploded/testServletForwardRedirect如下
需要注意的是:响应重定向和请求转发,两者之间在同一个控制器方法中只能使用一个
2.使用forward和redirect关键字实现转发和重定向
2.1.在view下创建index.jsp和main.jsp
利用上一小节中创建的index.jsp和main.jsp
2.2.com.augus.controller下面创建ResponseController
分别设置四个方法:
- testIndex:forward关键实现请求转发跳转的控制器方法
- testMain:redirect关键实现响应重定向时跳转的控制器方法
- testForward:测试forward关键实现请求转发
- testRedirect:测试redirect关键实现响应重定向
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Controller public class ResponseController {
//请求转发时的控制器方法 @RequestMapping("/testIndex") public String testIndex(){ System.out.println("执行了testIndex"); return "index"; } //响应重定向时的控制器方法 @RequestMapping("/testMain") public String testMain(){ System.out.println("执行了testMain"); return "main"; }/** * forward实现请求转发 * 返回字符串告诉DispatcherServlet跳转的路径 */ @RequestMapping("/testForward") public String testForward(){ return "forward:/testIndex"; } /** * redirect关键字实现响应重定向 * 返回字符串告诉DispatcherServlet跳转的路径 */ @RequestMapping("/testRedirect") public String testRedirect(){ return "redirect:/testMain"; } }
2.3.重新部署项目
访问地址:http://localhost:8080/springmvc_01_war_exploded/testForward,如下:
访问地址:http://localhost:8080/springmvc_01_war_exploded/testForward,如下:
2.4.对于forward(转发) 与 redirect(重定向) 是 servlet 提供的两种跳转方式。这两种跳转方式的具体区别如下表所述:
forward | redirect | |
---|---|---|
地址栏 | forword是服务器内部的重定向,即服务器直接访问目标地址的 url,并把其中的内容作为响应结果返回给浏览器,所以浏览器的地址栏不会发生变化。 | 服务器发送给浏览器一个 302 状态码,让其请求新的地址,所以地址栏中的地址会显示为新的地址。 |
共享数据 | 由于在服务器内部重定向的过程中,用的是同一个request,因此这个 request 可以带给其它 servlet 中供其使用,即共享数据。 | 不能 |
应用场景 | 一般用于用户登录时,根据角色权限跳转到相应模块 | 一般用于用户注销登录时,返回主页面或跳转到其他网站 |
效率 | 高 | 低 |
本质 | 服务器行为 | 客户端行为 |
请求次数 | 1次 | 2次。比如客户端请求 A 地址,服务端让其重定向到 B 地址,客户端请求 B 地址。 |
3.使用View视图实现转发和重定向
3.1.在view下创建index.jsp和main.jsp
利用上一小节中创建的index.jsp和main.jsp
3.2.com.augus.controller下面创建ResponseController
分别设置四个方法:
- testIndex:forward关键实现请求转发跳转的控制器方法
- testMain:redirect关键实现响应重定向时跳转的控制器方法
- testView:测试view实现请求转发和响应重定向
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.InternalResourceView; import org.springframework.web.servlet.view.RedirectView; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Controller public class ResponseController { //请求转发时的控制器方法 @RequestMapping("/testIndex") public String testIndex(){ System.out.println("执行了testIndex"); return "index"; } //响应重定向时的控制器方法 @RequestMapping("/testMain") public String testMain(){ System.out.println("执行了testMain"); return "main"; }
/** * 使用spring中提供的view视图实现请求转发和重定向 */ @RequestMapping("/testView") public View testView(HttpServletRequest request){ View view = null; //实现请求转发 //view = new InternalResourceView("/testIndex"); //响应重定向 view = new RedirectView(request.getContextPath()+"/testMain"); return view; } }
RedirectView中所做的操作最终的实现是在renderMergedOutputModel中完成实现的,简单来说RedirectView实现了链接的重定向,并且将数据保存到FlashMap中,这样在跳转后的链接中可以获取一些数据.
2.3.重新部署项目
访问地址:http://localhost:8080/springmvc_01_war_exploded/testView,如下:
4使用ModelAndView转发重定向
4.1.在view下创建index.jsp和main.jsp
利用上一小节中创建的index.jsp和main.jsp
4.2.com.augus.controller下面创建ResponseController
分别设置四个方法:
- testIndex:forward关键实现请求转发跳转的控制器方法
- testMain:redirect关键实现响应重定向时跳转的控制器方法
- testModelAndView:测试ModelAndView实现请求转发和响应重定向
package com.augus.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.InternalResourceView; import org.springframework.web.servlet.view.RedirectView; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @Controller public class ResponseController {//请求转发时的控制器方法 @RequestMapping("/testIndex") public String testIndex(){ System.out.println("执行了testIndex"); return "index"; } //响应重定向时的控制器方法 @RequestMapping("/testMain") public String testMain(){ System.out.println("执行了testMain"); return "main"; } @RequestMapping("/testModelAndView") public ModelAndView testModelAndView(HttpServletRequest request){ ModelAndView modelAndView = new ModelAndView(); /* * 下面实现请求转发和相应重定向,分别有两种不同的方式,任选其一即可 * */ //请求转发 //modelAndView.setViewName("forward:/testIndex"); //modelAndView.setView(new InternalResourceView("/testIndex")); //重定向 //modelAndView.setViewName("redirect:/testMain"); modelAndView.setView(new RedirectView(request.getContextPath()+"/testMain")); return modelAndView; } }
ModelAndView中的Model代表模型,View代表视图,这个名字就很好地解释了该类的作用。业务处理器调用模型层处理完用户请求后,把结果数据存储在该类的model属性中,把要返回的视图信息存储在该类的view属性中,然后让该ModelAndView返回该Spring MVC框架。
4.3.重新部署项目
访问http://localhost:8080/springmvc_01_war_exploded/testMain
三、响应JSON格式
为了实现浏览器与控制器类之间的 JSON 数据交互,Spring MVC 提供了一个默认的 MappingJackson2HttpMessageConverter 类,来处理 JSON 格式请求和响应。通过它,我们既可以将 Java 对象转换为 JSON 数据,也可以将 JSON 数据转换为 Java 对象。
3.1.引入依赖包
导入jackson的jar
<!--引入对于JSON格式的支持--> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.13.3</version> </dependency>
以上这些 Jackson 的开源依赖包都可以通过“https://mvnrepository.com/artifact/com.fasterxml.jackson.core”下载得到。
3.2.JSON 转换注解
Spring MVC 为我们提供了两个十分重要的与 JSON 格式转换相关的注解,它们分别是 @RequestBody 和 @ResponseBody。
注解 | 位置 | 说明 |
---|---|---|
@RequestBody | 方法的形参上 | 该注解用于将请求体中的数据绑定到控制器方法的形参上。 |
@ResponseBody | 方法上 | 该注解用于将控制器方法的返回值,直接作为响应报文的响应体响应到 浏览器上。 |
3.3.声明单元方法处理ajax请求,并在单元方法上新增注解@ResponseBody
package com.augus.controller; import com.augus.pojo.Pet; import com.fasterxml.jackson.core.JsonProcessingException; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class JsonController { /* * @ResponseBody方法返回值,你再作为接界面跳转的地址,直接作为界面跳转的数据 * 将方法的返回的数据自动转换为JSON,底层就是通过一下代码实现的转换 * * //将对象转换为JSON字符串 * ObjectMapper objectMapper = new ObjectMapper() * String s = objectMapper.writeValueAsString(pet); * */ @ResponseBody @RequestMapping("/testJsonResp") public Object testJsonResp() throws JsonProcessingException { Pet pet = new Pet("tom","cat"); //将对象转换为JSON字符串 // ObjectMapper objectMapper = new ObjectMapper(); // String s = objectMapper.writeValueAsString(pet); return pet; } }
3.4.在ajax的回调函数中,无需再次使用eval函数将响应数据转换为json对象
再webapp下创建ajax.jsp文件内容如下
<%-- Created by IntelliJ IDEA. User: Augus Date: 2023/7/25 Time: 17:29 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script> <script> $(function(){ $("#btn").click(function(){ /*当点击id为btn的按钮的时候,获取testJsonResp这个地址返回的JSON格式*/ $.get("testJsonResp",{pname:"晓明",page:"10"},function(data){ console.log(data.petName) console.log(data.petType) }) }) }) </script> </head> <body> <h1>helloworld</h1> <input id="btn" type="button" value="testJson"> </body> </html>
3.5.重新部署项目
浏览器访问:http://localhost:8080/springmvc_01_war_exploded/ajax.jsp,在控制台可以看到返回的JSON数据
3.6.@RestController注解
@RestController相当于@Controller+@ResponseBody两个注解的结合,返回json数据不需要在方法前面加@ResponseBody注解了,但使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
@RestController public class JsonController { /* * @ResponseBody方法返回值,你再作为接界面跳转的地址,直接作为界面跳转的数据 * 将方法的返回的数据自动转换为JSON,底层就是通过一下代码实现的转换 * * //将对象转换为JSON字符串 * ObjectMapper objectMapper = new ObjectMapper() * String s = objectMapper.writeValueAsString(pet); * */ @RequestMapping("/testJsonResp") public Object testJsonResp() throws JsonProcessingException { Pet pet = new Pet("tom","cat"); //将对象转换为JSON字符串 // ObjectMapper objectMapper = new ObjectMapper(); // String s = objectMapper.writeValueAsString(pet); return pet; } }