目录
SpringMVC接收数据和响应数据
一、SpringMVC介绍
1. 概念
Spring Web MVC是基于Servlet API构建的原始Web框架,从一开始就包含在Spring Framework中。正式名称“Spring Web MVC”来自其源模块的名称( spring-webmvc
),但它通常被称为“Spring MVC”。
在控制层框架历经Strust、WebWork、Strust2等诸多产品的历代更迭之后,目前业界普遍选择了SpringMVC作为Java EE项目表述层开发的首选方案。之所以能做到这一点,是因为SpringMVC具备如下显著优势:
- Spring 家族原生产品,与IOC容器等基础设施无缝对接
- 表述层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
- 代码清新简洁,大幅度提升开发效率
- 内部组件化程度高,可插拔式组件即插即用,想要什么功能配置相应组件即可
- 性能卓著,尤其适合现代大型、超大型互联网项目要求
作用:
- 简化前端参数接收( 形参列表 )
- 简化后端数据响应(返回值)
- 以及其他…
2. 核心组件和流程
SpringMVC涉及组件理解:
- DispatcherServlet : SpringMVC提供,我们需要使用web.xml配置使其生效,它是整个流程处理的核心,所有请求都经过它的处理和分发![ CEO ]
- HandlerMapping : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,它内部缓存handler(controller方法)和handler访问路径数据,被DispatcherServlet调用,用于查找路径对应的handler![秘书]
- HandlerAdapter : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效,它可以处理请求参数和处理响应数据数据,每次DispatcherServlet都是通过handlerAdapter间接调用handler,他是handler和DispatcherServlet之间的适配器![经理]
- Handler : handler又称处理器,他是Controller类内部的方法简称,是由我们自己定义,用来接收参数,向后调用业务,最终返回响应结果![打工人]
- ViewResovler : SpringMVC提供,我们需要进行IoC配置使其加入IoC容器方可生效!视图解析器主要作用简化模版视图页面查找的,但是需要注意,前后端分离项目,后端只返回JSON数据,不返回页面,那就不需要视图解析器!所以,视图解析器,相对其他的组件不是必须的![财务]
3. SpringMVC 快速实操
-
准备创建项目,转为maven/web程序
-
导入相关依赖(spring-context、jakarta.jakartaee-web-api、spring-webmvc)
-
Controller声明(写方法)
-
写SpringMVC核心组件和配置类
@EnableWebMvc @Configuration @ComponentScan(basePackages = "com.atguigu.controller") //TODO: 进行controller扫 //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现 public class SpringMvcConfig implements WebMvcConfigurer { @Bean public HandlerMapping handlerMapping(){ return new RequestMappingHandlerMapping(); } @Bean public HandlerAdapter handlerAdapter(){ return new RequestMappingHandlerAdapter(); } }
-
搭建SpringMVC环境
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { /** * 指定service / mapper层的配置类 */ @Override protected Class<?>[] getRootConfigClasses() { return null; } /** * 指定springmvc的配置类 * @return */ @Override protected Class<?>[] getServletConfigClasses() { return new Class<?>[] { SpringMvcConfig.class }; } /** * 设置dispatcherServlet的处理路径! * 一般情况下为 / 代表处理所有请求! */ @Override protected String[] getServletMappings() { return new String[] { "/" }; } }
-
测试
二、接收数据
1. 访问路径设置
- 精准路径匹配
@RequestMapping(value = {"/user/login"})
- 模糊路径匹配
@RequestMapping(value = {"/user/**"})
- 进阶注解
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
2. 接收参数
-
param参数接收
添加@RequestParam、@RequestBody
注解@GetMapping(value="/data") @ResponseBody public Object paramForm(@RequestParam("name") String name, //将参数设置非必须,并且设置默认值 @RequestParam(value = "stuAge",required = false,defaultValue = "18") int age){ System.out.println("name = " + name + ", age = " + age); return name+age; } /** * 前端请求: http://localhost:8080/param/mul?hbs=吃&hbs=喝 * * 一名多值,可以使用集合接收即可!但是需要使用@RequestParam注解指定 */ @GetMapping(value="/mul") @ResponseBody public Object mulForm(@RequestParam List<String> hbs){ System.out.println("hbs = " + hbs); return hbs; } @Controller @RequestMapping("param") public class ParamController { @RequestMapping(value = "/user", method = RequestMethod.POST) @ResponseBody public String addUser(@RequestBody User user) { // 在这里可以使用 user 对象的属性来接收请求参数 System.out.println("user = " + user); return "success"; } }
-
路径参数接收
添加@PathVariable
注解
访问路径用大括号{}
括起来/** * 动态路径设计: /user/{动态部分}/{动态部分} 动态部分使用{}包含即可! {}内部动态标识! * 形参列表取值: @PathVariable Long id 如果形参名 = {动态标识} 自动赋值! * @PathVariable("动态标识") Long id 如果形参名 != {动态标识} 可以通过指定动态标识赋值! * * 访问测试: /param/user/1/root -> id = 1 uname = root */ @GetMapping("/user/{id}/{name}") @ResponseBody public String getUser(@PathVariable Long id, @PathVariable("name") String uname) { System.out.println("id = " + id + ", uname = " + uname); return "user_detail"; }
-
json参数接收
前端传递 JSON 数据时,Spring MVC 框架可以使用@RequestBody
注解来将 JSON 数据转换为 Java 对象。@RequestBody
注解表示当前方法参数的值应该从请求体中获取,并且需要指定 value 属性来指示请求体应该映射到哪个参数上。其使用方式和示例代码如下:@PostMapping("/person") @ResponseBody public String addPerson(@RequestBody Person person) { // 在这里可以使用 person 对象来操作 JSON 数据中包含的属性 return "success"; }
-
接收Cookie、请求头数据
@GetMapping("/demo") public void handle(@CookieValue("JSESSIONID") String cookie) { //... } @GetMapping("/demo") public void handle( @RequestHeader("Accept-Encoding") String encoding, @RequestHeader("Keep-Alive") long keepAlive) { //... }
三、响应数据
1. 方法分析
理解handler方法的作用和组成:
/**
* TODO: 一个controller的方法是控制层的一个处理器,我们称为handler
* TODO: handler需要使用@RequestMapping/@GetMapping系列,声明路径,在HandlerMapping中注册,供DS查找!
* TODO: handler作用总结:
* 1.接收请求参数(param,json,pathVariable,共享域等)
* 2.调用业务逻辑
* 3.响应前端数据(页面(不讲解模版页面跳转),json,转发和重定向等)
* TODO: handler如何处理呢
* 1.接收参数: handler(形参列表: 主要的作用就是用来接收参数)
* 2.调用业务: { 方法体 可以向后调用业务方法 service.xx() }
* 3.响应数据: return 返回结果,可以快速响应前端数据
*/
@GetMapping
public Object handler(简化请求参数接收){
调用业务方法
返回的结果 (页面跳转,返回数据(json))
return 简化响应前端数据;
}
总结: 请求数据接收,我们都是通过handler的形参列表
前端数据响应,我们都是通过handler的return关键字快速处理!
springmvc简化了参数接收和响应!
2. 页面跳转
-
准备依赖
<!-- jsp需要依赖! jstl--> <dependency> <groupId>jakarta.servlet.jsp.jstl</groupId> <artifactId>jakarta.servlet.jsp.jstl-api</artifactId> <version>3.0.0</version> </dependency>
-
jsp页面创建
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <!-- 可以获取共享域的数据,动态展示! jsp== 后台vue --> ${msg} </body> </html>
-
配置jsp视图解析器
@EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器 @Configuration @ComponentScan(basePackages = "com.atguigu.controller") //TODO: 进行controller扫描 //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现 public class SpringMvcConfig implements WebMvcConfigurer { //配置jsp对应的视图解析器 @Override public void configureViewResolvers(ViewResolverRegistry registry) { //快速配置jsp模板语言对应的 registry.jsp("/WEB-INF/views/",".jsp"); } }
-
handler返回视图
/** * 跳转到提交文件页面 /save/jump * * 如果要返回jsp页面! * 1.方法返回值改成字符串类型 * 2.返回逻辑视图名即可 * <property name="prefix" value="/WEB-INF/views/"/> * + 逻辑视图名 + * <property name="suffix" value=".jsp"/> */ @GetMapping("jump") public String jumpJsp(Model model){ System.out.println("FileController.jumpJsp"); model.addAttribute("msg","request data!!"); return "home"; }
-
转发、重定向
@RequestMapping("/redirect-demo") public String redirectDemo() { // 重定向到 /demo 路径 return "redirect:/demo"; } @RequestMapping("/forward-demo") public String forwardDemo() { // 转发到 /demo 路径 return "forward:/demo"; } //注意: 转发和重定向到项目下资源路径都是相同,都不需要添加项目根路径!填写项目下路径即可!
3. 返回JSON数据
-
添加依赖
导入jackson依赖
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.0</version> </dependency>
-
添加json数据转化器:@EnableWebMvc&
-
@ResponseBody
方法上使用@ResponseBody
可以在方法上使用
@ResponseBody
注解,用于将方法返回的对象序列化为 JSON 或 XML 格式的数据,并发送给客户端。在前后端分离的项目中使用!测试方法:
@GetMapping("/accounts/{id}") @ResponseBody public Object handle() { // ... return obj; }
具体来说,
@ResponseBody
注解可以用来标识方法或者方法返回值,表示方法的返回值是要直接返回给客户端的数据,而不是由视图解析器来解析并渲染生成响应体(viewResolver没用)。测试方法:
@RequestMapping(value = "/user/detail", method = RequestMethod.POST) @ResponseBody public User getUser(@RequestBody User userParam) { System.out.println("userParam = " + userParam); User user = new User(); user.setAge(18); user.setName("John"); //返回的对象,会使用jackson的序列化工具,转成json返回给前端! return user; }
-
@RestController
类上的 @ResponseBody 注解可以和 @Controller 注解合并为 @RestController 注解。所以使用了 @RestController 注解就相当于给类中的每个方法都加了 @ResponseBody 注解。
RestController源码:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Controller @ResponseBody public @interface RestController { /** * The value may indicate a suggestion for a logical component name, * to be turned into a Spring bean in case of an autodetected component. * @return the suggested component name, if any (or empty String otherwise) * @since 4.0.1 */ @AliasFor(annotation = Controller.class) String value() default ""; }
-
返回静态资源处理
在 SpringMVC 配置配置类:
@EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器 @Configuration @ComponentScan(basePackages = "com.atguigu.controller") //TODO: 进行controller扫描 //WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现 public class SpringMvcConfig implements WebMvcConfigurer { //配置jsp对应的视图解析器 @Override public void configureViewResolvers(ViewResolverRegistry registry) { //快速配置jsp模板语言对应的 registry.jsp("/WEB-INF/views/",".jsp"); } //开启静态资源处理 <mvc:default-servlet-handler/> @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }