目录
功能
简化前端参数接收( 形参列表 )
简化后端数据响应(返回值)
接收数据
访问路径设置
@RequestMapping注解的作用就是将请求的 URL 地址和处理请求的方式(handler方法)关联起来,建立映射关系。
SpringMVC 接收到指定的请求,就会来找到在映射关系中对应的方法来处理这个请求。
精准路径匹配
在@RequestMapping注解指定 URL 地址时,不使用任何通配符,按照请求地址进行精确匹配。
@Controller
public class UserController {
/**
* 精准设置访问地址 /user/login
*/
@RequestMapping(value = {"/user/login"})
@ResponseBody
public String login(){
System.out.println("UserController.login");
return "login success!!";
}
/**
* 精准设置访问地址 /user/register
*/
@RequestMapping(value = {"/user/register"})
@ResponseBody
public String register(){
System.out.println("UserController.register");
return "register success!!";
}
}
模糊路径匹配
在@RequestMapping注解指定 URL 地址时,通过使用通配符,匹配多个类似的地址。
@Controller
public class ProductController {
/**
* 路径设置为 /product/*
* /* 为单层任意字符串 /product/a /product/aaa 可以访问此handler
* /product/a/a 不可以
* 路径设置为 /product/**
* /** 为任意层任意字符串 /product/a /product/aaa 可以访问此handler
* /product/a/a 也可以访问
*/
@RequestMapping("/product/*")
@ResponseBody
public String show(){
System.out.println("ProductController.show");
return "product show!";
}
}
/*:只能匹配URL地址中的一层,如果想准确匹配两层,那么就写"/*/*"以此类推。 /**:可以匹配URL地址中的多层。
类和方法级别区别
-
设置到类级别:`@RequestMapping` 注解可以设置在控制器类上,用于映射整个控制器的通用请求路径。这样,如果控制器中的多个方法都需要映射同一请求路径,就不需要在每个方法上都添加映射路径。
-
设置到方法级别:`@RequestMapping` 注解也可以单独设置在控制器方法上,用于更细粒度地映射请求路径和处理方法。当多个方法处理同一个路径的不同操作时,可以使用方法级别的 `@RequestMapping` 注解进行更精细的映射。
附带请求方式限制
HTTP 协议定义了八种请求方式,在 SpringMVC 中封装到了下面这个枚举类:
public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}
@Controller
public class UserController {
/**
* 精准设置访问地址 /user/login
* method = RequestMethod.POST 可以指定单个或者多个请求方式!
* 注意:违背请求方式会出现405异常!
*/
@RequestMapping(value = {"/user/login"} , method = RequestMethod.POST)
@ResponseBody
public String login(){
System.out.println("UserController.login");
return "login success!!";
}
/**
* 精准设置访问地址 /user/register
*/
@RequestMapping(value = {"/user/register"},method = {RequestMethod.POST,RequestMethod.GET})
@ResponseBody
public String register(){
System.out.println("UserController.register");
return "register success!!";
}
}
进阶注解
还有 `@RequestMapping` 的 HTTP 方法特定快捷方式变体:
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
注意:进阶注解只能添加到handler方法上,无法添加到类上
接收参数
Para和json参数比较
在 HTTP 请求中,我们可以选择不同的参数类型,如 param 类型和 JSON 类型。下面对这两种参数类型进行区别和对比:
- 参数编码:
param 类型的参数会被编码为 ASCII 码。例如,假设 `name=john doe`,则会被编码为 `name=john%20doe`。而 JSON 类型的参数会被编码为 UTF-8。
- 参数顺序:
param 类型的参数没有顺序限制。但是,JSON 类型的参数是有序的。JSON 采用键值对的形式进行传递,其中键值对是有序排列的。
- 数据类型:
param 类型的参数仅支持字符串类型、数值类型和布尔类型等简单数据类型。而 JSON 类型的参数则支持更复杂的数据类型,如数组、对象等。
- 嵌套性:
param 类型的参数不支持嵌套。但是,JSON 类型的参数支持嵌套,可以传递更为复杂的数据结构。
- 可读性:
param 类型的参数格式比 JSON 类型的参数更加简单、易读。但是,JSON 格式在传递嵌套数据结构时更加清晰易懂。
Para参数接受
直接接收
只要形参数名和类型与传递参数相同,即可自动接收
@Controller
@RequestMapping("param")
public class ParamController {
/**
* 前端请求: http://localhost:8080/param/value?name=xx&age=18
*
* 可以利用形参列表,直接接收前端传递的param参数!
* 要求: 参数名 = 形参名
* 类型相同
* 出现乱码正常,json接收具体解决!!
* @return 返回前端数据
*/
@GetMapping(value="/value")
@ResponseBody
public String setupForm(String name,int age){
System.out.println("name = " + name + ", age = " + age);
return name + age;
}
}
@RequestParam注解
可以使用 `@RequestParam` 注释将 Servlet 请求参数(即查询参数或表单数据)绑定到控制器中的方法参数。
`@RequestParam`使用场景:
指定绑定的请求参数名
要求请求参数必须传递
为请求参数提供默认值
/**
* 前端请求: http://localhost:8080/param/data?name=xx&stuAge=18
*
* 使用@RequestParam注解标记handler方法的形参
* 指定形参对应的请求参数@RequestParam(请求参数名称)
*/
@GetMapping(value="/data")
@ResponseBody
public Object paramForm(@RequestParam("name") String name,
@RequestParam("stuAge") int age){
System.out.println("name = " + name + ", age = " + age);
return name+age;
}
默认情况下,使用此批注的方法参数是必需的,但您可以通过将 `@RequestParam` 批注的 `required` 标志设置为 `false`
将参数设置非必须,并且设置默认值:
@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;
}
特殊场景接值
一名多值
多选框,提交的数据的时候一个key对应多个值,我们可以使用集合进行接收
/**
* 前端请求: 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;
}
实体接收
public class User {
private String name;
private int age = 18;
// getter 和 setter 略
}
@Controller
@RequestMapping("param")
public class ParamController {
@RequestMapping(value = "/user", method = RequestMethod.POST)
@ResponseBody
public String addUser(User user) {
// 在这里可以使用 user 对象的属性来接收请求参数
System.out.println("user = " + user);
return "success";
}
}
将请求参数name和age映射到实体类属性上,要求属性名必须等于参数名!否则无法映射
路径参数接受
路径传递参数是一种在 URL 路径中传递参数的方式。在 RESTful 的 Web 应用程序中,经常使用路径传递参数来表示资源的唯一标识符或更复杂的表示方式。而 Spring MVC 框架提供了 `@PathVariable` 注解来处理路径传递参数。
`@PathVariable` 注解允许将 URL 中的占位符映射到控制器方法中的参数。
/**
* 动态路径设计: /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 属性来指示请求体应该映射到哪个参数上。
前端发送 JSON 数据的示例:
{
"name": "张三",
"age": 18,
"gender": "男"
}
定义一个用于接收 JSON 数据的 Java 类
public class Person {
private String name;
private int age;
private String gender;
// getter 和 setter 略
}
在控制器中,使用 @RequestBody 注解来接收 JSON 数据,并将其转换为 Java 对象
@PostMapping("/person")
@ResponseBody
public String addPerson(@RequestBody Person person) {
// 在这里可以使用 person 对象来操作 JSON 数据中包含的属性
return "success";
}
@RequestBody 注解将请求体中的 JSON 数据映射到 Person 类型的 person 参数上,并将其作为一个对象来传递给 addPerson() 方法进行处理。
但会出现:

原因:
不支持json数据类型处理
没有json类型处理的工具(jackson)
解决:
//TODO: SpringMVC对应组件的配置类 [声明SpringMVC需要的组件信息]
//TODO: 导入handlerMapping和handlerAdapter的三种方式
//1.自动导入handlerMapping和handlerAdapter [推荐]
//2.可以不添加,springmvc会检查是否配置handlerMapping和handlerAdapter,没有配置默认加载
//3.使用@Bean方式配置handlerMapper和handlerAdapter
@EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器
@Configuration
@ComponentScan(basePackages = "com.controller") //TODO: 进行controller扫描
//WebMvcConfigurer springMvc进行组件配置的规范,配置组件,提供各种方法! 前期可以实现
public class SpringMvcConfig implements WebMvcConfigurer {
}
pom.xml 加入jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.0</version>
</dependency>
注意:@EnableWebMvc会自动配置handlermapping和handleradapter还有json转换器
接受cookie
可以使用 `@CookieValue` 注释将 HTTP Cookie 的值绑定到控制器中的方法参数。
JSESSIONID=415A4AC178C59DACE0B2C9CA727CDD84
如何获取 cookie 值
@GetMapping("/demo")
public void handle(@CookieValue("JSESSIONID") String cookie) {
//...
}
接受请求头数据
可以使用 @RequestHeader 批注将请求标头绑定到控制器中的方法参数。
Host localhost:8080
Accept text/html,application/xhtml+xml,application/xml;q=0.9
Accept-Language fr,en-gb;q=0.7,en;q=0.3
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
获取 Accept-Encoding 和 Keep-Alive 标头的值
@GetMapping("/demo")
public void handle(
@RequestHeader("Accept-Encoding") String encoding,
@RequestHeader("Keep-Alive") long keepAlive) {
//...
}
原生Api对象操作
| Controller method argument 控制器方法参数 | Description |
|---|---|
jakarta.servlet.ServletRequest, jakarta.servlet.ServletResponse |
请求/响应对象 |
jakarta.servlet.http.HttpSession |
强制存在会话。因此,这样的参数永远不会为 null 。 |
java.io.InputStream, java.io.Reader |
用于访问由 Servlet API 公开的原始请求正文。 |
java.io.OutputStream, java.io.Writer |
用于访问由 Servlet API 公开的原始响应正文。 |
@PathVariable |
接收路径参数注解 |
@RequestParam |
用于访问 Servlet 请求参数,包括多部分文件。参数值将转换为声明的方法参数类型。 |
@RequestHeader |
用于访问请求标头。标头值将转换为声明的方法参数类型。 |
@CookieValue |
用于访问Cookie。Cookie 值将转换为声明的方法参数类型。 |
@RequestBody |
用于访问 HTTP 请求正文。正文内容通过使用 HttpMessageConverter 实现转换为声明的方法参数类型。 |
java.util.Map, org.springframework.ui.Model, org.springframework.ui.ModelMap |
共享域对象,并在视图呈现过程中向模板公开。 |
Errors, BindingResult |
验证和数据绑定中的错误信息获取对象 |
获取原生对象
/**
* 如果想要获取请求或者响应对象,或者会话等,可以直接在形参列表传入,并且不分先后顺序!
* 注意: 接收原生对象,并不影响参数接收!
*/
@GetMapping("api")
@ResponseBody
public String api(HttpSession session , HttpServletRequest request,
HttpServletResponse response){
String method = request.getMethod();
System.out.println("method = " + method);
return "api";
}
共享域对象操作
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在同一 Web 应用程序的多个组件中进行共享和访问。常见的共享域有四种:`ServletContext`、`HttpSession`、`HttpServletRequest`、`PageContext`。
-
`ServletContext` 共享域:`ServletContext` 对象可以在整个 Web 应用程序中共享数据,是最大的共享域。一般可以用于保存整个 Web 应用程序的全局配置信息,以及所有用户都共享的数据。在 `ServletContext` 中保存的数据是线程安全的。
-
`HttpSession` 共享域:`HttpSession` 对象可以在同一用户发出的多个请求之间共享数据,但只能在同一个会话中使用。比如,可以将用户登录状态保存在 `HttpSession` 中,让用户在多个页面间保持登录状态。
-
`HttpServletRequest` 共享域:`HttpServletRequest` 对象可以在同一个请求的多个处理器方法之间共享数据。比如,可以将请求的参数和属性存储在 `HttpServletRequest` 中,让处理器方法之间可以访问这些数据。
-
`PageContext` 共享域:`PageContext` 对象是在 JSP 页面Servlet 创建时自动创建的。它可以在 JSP 的各个作用域中共享数据,包括`pageScope`、`requestScope`、`sessionScope`、`applicationScope` 等作用域。
共享域的作用是提供了方便实用的方式在同一 Web 应用程序的多个组件之间传递数据,并且可以将数据保存在不同的共享域中,根据需要进行选择和使用。
Request级别
使用原生 request 对象
@RequestMapping("/attr/request/original")
@ResponseBody
public String testAttrOriginalRequest(
// 拿到原生对象,就可以调用原生方法执行各种操作
HttpServletRequest request) {
request.setAttribute("requestScopeMessageOriginal", "i am very happy[original]");
return "target";
}
Session级别
@RequestMapping("/attr/session")
@ResponseBody
public String testAttrSession(HttpSession session) {
//直接对session对象操作,即对会话范围操作!
return "target";
}
Application级别
springmvc会在初始化容器的时候,会将servletContext对象存储到ioc容器中
@Autowired
private ServletContext servletContext;
@RequestMapping("/attr/application")
@ResponseBody
public String attrApplication() {
servletContext.setAttribute("appScopeMsg", "i am hungry...");
return "target";
}
响应数据
一个controller的方法是控制层的一个处理器,我们称为handler
@GetMapping
public Object handler(简化请求参数接收){
调用业务方法
返回的结果 (页面跳转,返回数据(json))
return 简化响应前端数据;
}
返回模板视图
依赖导入
<!-- jsp需要依赖! jstl-->
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
</dependency>
jsp页面创建
建议位置:/WEB-INF/下,避免外部直接访问
<%@ 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.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";
}
转发和重定向
在 Spring MVC 中,Handler 方法返回值来实现快速转发,可以使用 redirect 或者 forward 关键字来实现重定向。
@RequestMapping("/redirect-demo")
public String redirectDemo() {
// 重定向到 /demo 路径
return "redirect:/demo";
}
@RequestMapping("/forward-demo")
public String forwardDemo() {
// 转发到 /demo 路径
return "forward:/demo";
}
//注意: 转发和重定向到项目下资源路径都是相同,都不需要添加项目根路径!填写项目下路径即可!
将方法的返回值,设置String类型
转发使用forward关键字,重定向使用redirect关键字
关键字: /路径
注意:如果是项目下的资源,转发和重定向都一样都是项目下路径,都不需要添加项目根路径
返回json数据
导入jackson依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.0</version>
</dependency>
添加json数据转化器
@EnableWebMvc
方法上使用@ResponseBody
可以在方法上使用 @ResponseBody注解,用于将方法返回的对象序列化为 JSON 或 XML 格式的数据,并发送给客户端。
具体来说,@ResponseBody 注解可以用来标识方法或者方法返回值,表示方法的返回值是要直接返回给客户端的数据,而不是由视图解析器来解析并渲染生成响应体(viewResolver没用)。
类上使用@ResponseBody
如果类中每个方法上都标记了 @ResponseBody 注解,那么这些注解就可以提取到类上。
类上的 @ResponseBody 注解可以和 @Controller 注解合并为 @RestController 注解。所以使用了 @RestController 注解就相当于给类中的每个方法都加了 @ResponseBody 注解。
返回静态资源处理
在 SpringMVC 配置配置类:
@EnableWebMvc //json数据处理,必须使用此注解,因为他会加入json处理器
@Configuration
@ComponentScan(basePackages = "com.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();
}
}
全局异常处理机制
声明异常处理控
声明异常处理控制器类
/**
* projectName: com.atguigu.execptionhandler
*
* description: 全局异常处理器,内部可以定义异常处理Handler!
*/
/**
* @RestControllerAdvice = @ControllerAdvice + @ResponseBody
* @ControllerAdvice 代表当前类的异常处理controller!
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
}
声明异常处理hander方法
异常处理handler方法和普通的handler方法参数接收和响应都一致
只不过异常处理handler方法要映射异常,发生对应的异常调用
普通的handler方法要使用@RequestMapping注解映射路径,发生对应的路径调用
/**
* 异常处理handler
* @ExceptionHandler(HttpMessageNotReadableException.class)
* 该注解标记异常处理Handler,并且指定发生异常调用该方法!
*
*
* @param e 获取异常对象!
* @return 返回handler处理结果!
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
public Object handlerJsonDateException(HttpMessageNotReadableException e){
return null;
}
/**
* 当发生空指针异常会触发此方法!
* @param e
* @return
*/
@ExceptionHandler(NullPointerException.class)
public Object handlerNullException(NullPointerException e){
return null;
}
/**
* 所有异常都会触发此方法!但是如果有具体的异常处理Handler!
* 具体异常处理Handler优先级更高!
* 例如: 发生NullPointerException异常!
* 会触发handlerNullException方法,不会触发handlerException方法!
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
public Object handlerException(Exception e){
return null;
}
配置文件扫描控制器类配置
<!-- 扫描controller对应的包,将handler加入到ioc-->
@ComponentScan(basePackages = {"com.controller",
"com.exceptionhandler"})
拦截器
在程序中,使用拦截器在请求到达具体 handler 方法前,统一执行检测
拦截器 Springmvc VS 过滤器 javaWeb:
相似点
拦截:必须先把请求拦住,才能执行后续操作
过滤:拦截器或过滤器存在的意义就是对请求进行统一处理
放行:对请求执行了必要操作后,放请求过去,让它访问原本想要访问的资源
不同点
工作平台不同
过滤器工作在 Servlet 容器中
拦截器工作在 SpringMVC 的基础上
拦截的范围
过滤器:能够拦截到的最大范围是整个 Web 应用
拦截器:能够拦截到的最大范围是整个 SpringMVC 负责的请求
IOC 容器支持
过滤器:想得到 IOC 容器需要调用专门的工具方法,是间接的
拦截器:它自己就在 IOC 容器中,所以可以直接从 IOC 容器中装配组件,也就是可以直接得到 IOC 容器的支持
拦截器的使用
创建拦截器类
public class Process01Interceptor implements HandlerInterceptor {
// if( ! preHandler()){return;}
// 在处理请求的目标 handler 方法前执行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("request = " + request + ", response = " + response + ", handler = " + handler);
System.out.println("Process01Interceptor.preHandle");
// 返回true:放行
// 返回false:不放行
return true;
}
// 在目标 handler 方法之后,handler报错不执行!
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("request = " + request + ", response = " + response + ", handler = " + handler + ", modelAndView = " + modelAndView);
System.out.println("Process01Interceptor.postHandle");
}
// 渲染视图之后执行(最后),一定执行!
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("request = " + request + ", response = " + response + ", handler = " + handler + ", ex = " + ex);
System.out.println("Process01Interceptor.afterCompletion");
}
}
修改配置类添加拦截器
//添加拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
//将拦截器添加到Springmvc环境,默认拦截所有Springmvc分发的请求
registry.addInterceptor(new Process01Interceptor());
//精准匹配,设置拦截器处理指定请求 路径可以设置一个或者多个,为项目下路径即可
//addPathPatterns("/common/request/one") 添加拦截路径
registry.addInterceptor(new Process01Interceptor()).addPathPatterns("/common/request/one","/common/request/tow");
//排除匹配,排除应该在匹配的范围内排除
//addPathPatterns("/common/request/one") 添加拦截路径
//excludePathPatterns("/common/request/tow"); 排除路径,排除应该在拦截的范围内
registry.addInterceptor(new Process01Interceptor())
.addPathPatterns("/common/request/one","/common/request/tow")
.excludePathPatterns("/common/request/tow");
}
多个拦截器执行顺序
-
preHandle() 方法:SpringMVC 会把所有拦截器收集到一起,然后按照配置顺序调用各个 preHandle() 方法。
-
postHandle() 方法:SpringMVC 会把所有拦截器收集到一起,然后按照配置相反的顺序调用各个 postHandle() 方法。
-
afterCompletion() 方法:SpringMVC 会把所有拦截器收集到一起,然后按照配置相反的顺序调用各个 afterCompletion() 方法。
参数校验
在 Web 应用三层架构体系中,表述层负责接收浏览器提交的数据,业务逻辑层负责数据的处理。为了能够让业务逻辑层基于正确的数据进行处理,我们需要在表述层对数据进行检查,将错误的数据隔绝在业务逻辑层之外。
JSR 303
| 注解 | 规则 |
|---|---|
| @Null | 标注值必须为 null |
| @NotNull | 标注值不可为 null |
| @AssertTrue | 标注值必须为 true |
| @AssertFalse | 标注值必须为 false |
| @Min(value) | 标注值必须大于或等于 value |
| @Max(value) | 标注值必须小于或等于 value |
| @DecimalMin(value) | 标注值必须大于或等于 value |
| @DecimalMax(value) | 标注值必须小于或等于 value |
| @Size(max,min) | 标注值大小必须在 max 和 min 限定的范围内 |
| @Digits(integer,fratction) | 标注值值必须是一个数字,且必须在可接受的范围内 |
| @Past | 标注值只能用于日期型,且必须是过去的日期 |
| @Future | 标注值只能用于日期型,且必须是将来的日期 |
| @Pattern(value) | 标注值必须符合指定的正则表达式 |
SR 303 只是一套标准,需要提供其实现才可以使用。Hibernate Validator 是 JSR 303 的一个参考实现,除支持所有标准的校验注解外,它还支持以下的扩展注解:
| 注解 | 规则 |
|---|---|
| 标注值必须是格式正确的 Email 地址 | |
| @Length | 标注值字符串大小必须在指定的范围内 |
| @NotEmpty | 标注值字符串不能是空字符串 |
| @Range | 标注值必须在指定的范围内 |
导入依赖
<!-- 校验注解 -->
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-web-api</artifactId>
<version>9.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 校验注解实现-->
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.0.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator-annotation-processor -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
<version>8.0.0.Final</version>
</dependency>
应用校验注解
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.Min;
import org.hibernate.validator.constraints.Length;
public class User {
//age 1 <= age < = 150
@Min(10)
private int age;
//name 3 <= name.length <= 6
@Length(min = 3,max = 10)
private String name;
//email 邮箱格式
@Email
private String email;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
handler标记和绑定错误收集
@RestController
@RequestMapping("user")
public class UserController {
/**
* @Validated 代表应用校验注解! 必须添加!
*/
@PostMapping("save")
public Object save(@Validated @RequestBody User user,
//在实体类参数和 BindingResult 之间不能有任何其他参数, BindingResult可以接受错误信息,避免信息抛出!
BindingResult result){
//判断是否有信息绑定错误! 有可以自行处理!
if (result.hasErrors()){
System.out.println("错误");
String errorMsg = result.getFieldError().toString();
return errorMsg;
}
//没有,正常处理业务即可
System.out.println("正常");
return user;
}
}
@NotNull、@NotEmpty、@NotBlank 都是用于在数据校验中检查字段值是否为空的注解,但是它们的用法和校验规则有所不同。
@NotNull (包装类型不为null)
@NotEmpty (集合类型长度大于0)
@NotBlank (字符串,不为null,且不为" "字符串)
RESTFul风格要求
HTTP协议请求方式要求
| 操作 | 请求方式 |
|---|---|
| 查询操作 | GET |
| 保存操作 | POST |
| 删除操作 | DELETE |
| 更新操作 | PUT |
URL路径风格要求
| 操作 | 传统风格 | REST 风格 |
|---|---|---|
| 保存 | /CRUD/saveEmp | URL 地址:/CRUD/emp 请求方式:POST |
| 删除 | /CRUD/removeEmp?empId=2 | URL 地址:/CRUD/emp/2 请求方式:DELETE |
| 更新 | /CRUD/updateEmp | URL 地址:/CRUD/emp 请求方式:PUT |
| 查询 | /CRUD/editEmp?empId=2 | URL 地址:/CRUD/emp/2 请求方式:GET |