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数据,不返回页面,那就不需要视图解析器!所以,视图解析器,相对其他的组件不是必须的![财务]
1.快速体验使用MVC接收数据
-
在Maven项目中新建模块并转换成Web项目
-
导入依赖
<properties><spring.version>6.0.6</spring.version><servlet.api>9.1.0</servlet.api><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties><dependencies><!-- springioc相关依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><!-- web相关依赖 --><!-- 在 pom.xml 中引入 Jakarta EE Web API 的依赖 --><!--在 Spring Web MVC 6 中,Servlet API 迁移到了 Jakarta EE API, 因此在配置 DispatcherServlet 时需要使用Jakarta EE 提供的相应类库和命名空间。--><dependency><groupId>jakarta.platform</groupId><artifactId>jakarta.jakartaee-web-api</artifactId><version>${servlet.api}</version><scope>provided</scope></dependency><!-- springwebmvc相关依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency></dependencies>
-
创建Controller类
@Controller @RequestMapping("param") public class ParamController {//后端直接接收// /param/data?name=root&age=18// 形参列表,填写对应名称的参数即可! 请求参数名 = 形参参数名即可!// 1. 名称相同 2.可以不传递 不报错@RequestMapping("data")@ResponseBodypublic String data(String name,int age){System.out.println("接收到:name = " + name + ", age = " + age);return "成功给前端返回:name = " + name + ", age = " + age;} }
-
Spring MVC核心组件配置类
@Configuration @ComponentScan("com.example") public class MvcConfig {//@Bean方式配置handlerMapper和handlerAdapter@Beanpublic RequestMappingHandlerMapping handlerMapping(){return new RequestMappingHandlerMapping();}@Beanpublic RequestMappingHandlerAdapter handlerAdapter(){return new RequestMappingHandlerAdapter();} }
-
SpringMVC环境搭建
/*** description: 可以被web项目加载,会初始化ioc容器,会设置dispatcherServlet的地址* @author UserName*/ public class SpringMvcInit extends AbstractAnnotationConfigDispatcherServletInitializer {// service mapper层的ioc容器的配置@Overrideprotected Class<?>[] getRootConfigClasses() {return new Class[0];}// 设置我们项目对应的配置 springmvc controller@Overrideprotected Class<?>[] getServletConfigClasses() {return new Class[]{MvcConfig.class};}// 配置springmvc内部自带servlet 的访问地址 !@Overrideprotected String[] getServletMappings() {return new String[]{ "/"};} }
-
运行测试
2.SpringMVC数据接收
@ResponseBody注解
用来标识方法或者方法返回值,表示方法的返回值是要直接返回给客户端的数据,而不是由视图解析器来解析并渲染生成响应体(viewResolver没用)。
1.访问路径设置
1.1 在@RequestMapping注解指定精确地址匹配。
@Controller
public class HelloController {@RequestMapping("springmvc/hello") //对外访问的地址 到handlerMapping注册的注解@ResponseBody //直接返回字符串给前端,不要找视图解析器!!!public String hello(){System.out.println("HelloController.hello");//返回给前端return "hello springmvc!!";}
}
1.2 通过使用通配符,匹配多个类似的地址。
@Controller
public class HelloController {@RequestMapping("springmvc/*")@ResponseBody //直接返回字符串给前端,不要找视图解析器!!!public String handleAllBooks() {// 匹配所有以 /books/ 开头的路径System.out.println("匹配到一层springmvc/*");return "一层springmvc/*";}@RequestMapping("springmvc/**")@ResponseBody //直接返回字符串给前端,不要找视图解析器!!!public String handleBookDetails() {// 匹配所有以 /books/ 开头的路径及其子路径System.out.println("匹配到多层springmvc/**");return "多层springmvc/**";}
}
运行访问:
###
GET http://localhost:8080/springmvc/aaa
###
GET http://localhost:8080/springmvc/aaa/bb//输出:
springmvc/*
springmvc/**
1.3 标记类+标记handler方法
@Controller
@RequestMapping("springmvc")
public class HelloController {@RequestMapping("hello")//底层是字符串拼接,但mvc会自动加“/”号@ResponseBody //直接返回字符串给前端,不要找视图解析器!!!public String hello() {System.out.println("hello mvc");return "hello mvc";}
}
运行访问:
###
GET http://localhost:8080/springmvc/aaa/bb//输出:
hello mvc
1.4 附带请求方式限制
默认情况下:@RequestMapping("/logout") 任何请求方式都可以访问!
@RequestMapping(value="/login",method=RequestMethod.GET)
等于->
@GetMapping(value="/login")
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
可以特定指定,但违背请求方式,会出现405异常!!!:
@Controller
public class UserController {/*** method = RequestMethod.POST 可以指定单个或者多个请求方式!* 注意:违背请求方式会出现405异常!*/@RequestMapping(value = {"/user/login"} , method = RequestMethod.POST)@ResponseBodypublic String login(){System.out.println("UserController.login");return "login success!!";}
// @PostMapping(value = {"/user/login"})
// @ResponseBody
// public String login1(){
// System.out.println("UserController.login");
// return "login success!!";
// }@RequestMapping(value = {"/user/register"},method = {RequestMethod.POST, RequestMethod.GET})@ResponseBodypublic String register(){System.out.println("UserController.register");return "register success!!";}}
2.param参数接收
@Controller
@RequestMapping("param")
public class ParamController {//后端直接接收// /param/data?name=root&age=18// 形参列表,填写对应名称的参数即可! 请求参数名 = 形参参数名即可!// 1. 名称相同 2.可以不传递 不报错@RequestMapping("data")@ResponseBodypublic String data(String name,int age){System.out.println("name = " + name + ", age = " + age);return "成功给后台返回:name = " + name + ", age = " + age;}//注解指定//指定任意的请求参数名 要求必须传递 要求不必须传递 给与一个默认值// /param/data1?account=root&page=1// account必须传递 page可以不必须传递,如果不传递默认值就是1/*** @RequestParam -> 形参列表 指定请求参数名 或者是否必须传递 或者 非必须传递设置默认值* 用法: @RequestParam(value="指定请求参数名,如果形参名和请求参数名一致,可以省略!",* required = false 前端是否必须传递此参数,默认是必须 , 不传400异常!,* defaultValue = "1" 当非必须传递 false ,可以设置默认值)*/@GetMapping("data1")@ResponseBodypublic String data1(@RequestParam(value = "account") String username,@RequestParam(required = false,defaultValue = "1") int page){System.out.println("username = " + username + ", page = " + page);return "username = " + username + ", page = " + page;}//特殊值// 一名多值 key=1&key=2 直接使用集合接值即可//param/data2?hbs=吃&hbs=玩&hbs=学习//不加注解@RequestParam 将 hbs对应的一个字符串直接赋值给集合! 类型异常!//加了注解,经理就会将集合 add加入对应的字符串@GetMapping("data2")@ResponseBodypublic String data2(@RequestParam List<String> hbs){System.out.println("hbs = " + hbs);return "ok";}//使用实体对象接值 用户注册(用户的信息) -》 对应的实体类 -》 插入到数据库 表//param/data3?name=二狗子&age=18 准备一个对应属性和get|set方法的实体类即可! -> 形参列表声明对象参数即可!@RequestMapping("data3")@ResponseBodypublic String data3(User user){System.out.println("user = " + user);return user.toString();}
}
测试data3:
3. 动态路径参数接收
动态路径设计: /user/{动态部分}/{动态部分}
@Controller
@RequestMapping("path")
@ResponseBody
public class PathController {// path/账号/密码//动态路径设计 {key} = * {key} 在形参列表获取传入的参数//接受路径参数 String account,String password -> 接受param格式参数// 必须使用 @PathVariable@RequestMapping("{account}/{password}")public String login(@PathVariable(value = "account") String username, @PathVariable String password){System.out.println("username = " + username + ", password = " + password);return "username = " + username + ", password = " + password;}
}
运行测试:
4. JSON参数接收
前端传递 JSON 数据时,Spring MVC 框架可以使用 @RequestBody 注解来将 JSON 数据转换为 Java 对象。@RequestBody 注解表示当前方法参数的值应该从请求体中获取,并且需要指定 value 属性来指示请求体应该映射到哪个参数上
实体类:
public class Person {private String name;private int age;private String gender;// getter 和 setter 略
}
使用 @RequestBody 注解
@RequestMapping(value = "json")
@Controller
@ResponseBody
public class JsonController {@PostMapping("data")public String data(@RequestBody Person person) {System.out.println("person = " + person);return person.toString();}
}
pom.xml 加入jackson依赖
<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.0</version>
</dependency>
使用@EnableWebMvc配置
/*TODO: 导入handlerMapping和handlerAdapter的三种方式
1.自动导入handlerMapping和handlerAdapter [推荐]
2.可以不添加,springmvc会检查是否配置handlerMapping和handlerAdapter,没有配置默认加载
3.使用@Bean方式配置handlerMapper和handlerAdapter
*/
@EnableWebMvc//handlerAdapter配置了json转化器
@Configuration
@ComponentScan("com.example")
public class MvcConfig {//@Bean//public RequestMappingHandlerMapping handlerMapping(){// return new RequestMappingHandlerMapping();//}//@Bean//public RequestMappingHandlerAdapter handlerAdapter(){// return new RequestMappingHandlerAdapter();//}
}
运行测试:
或者前端使用Axios:
axios.post('/json/datas', {name: "Lucy",age: 18,gender: "man"
})
5.Cookie参数接收
1. 定义向响应中添加Cookie数据的方法。创建了一个名为 "cookieName"
,值为 "root"
的Cookie,并通过 response.addCookie(cookie)
将其添加到响应中,成功后返回“ok”。
2.使用 @CookieValue
注解来接收名为 "cookieName"
的Cookie的值。
@Controller
@RequestMapping("cookie")
@ResponseBody
public class CookieController {@GetMapping("save")public String save(HttpServletResponse response){Cookie cookie = new Cookie("cookieName","这是一个cookieName");response.addCookie(cookie);return "ok";}@RequestMapping("data")public String data(@CookieValue(value = "cookieName") String value){System.out.println("value = " + value);return value;}
}
运行测试:
6. 请求头数据接收
@Controller
@RequestMapping("header")
@ResponseBody
public class HeaderController {@GetMapping("data")public String data(@RequestHeader("Host") String host){System.out.println("host = " + host);return "host = " + host;}
}