一、项目搭建
1、使用springboot搭建一个web工程
建web工程,不使用骨架创建maven的Java工程即可,不需要创建maven的web工程。
2、添加父工程坐标和添加web启动器
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>RELEASE</version> <scope>compile</scope> </dependency> </dependencies>
查看spring-boot-starter-web依赖,发现web模块默认使用了hibernate-validator:
3、创建启动类
@SpringBootApplication public class MySpringBootApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class); } }
4、创建实体类Agent
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @Data public class Agent { /** * 代理人姓名 */ @NotNull(message = "姓名不能为空") private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; }
注意:一定要加@Data注解,否则无法获取请求体中的值,即使请求体中参数不为空,也会校验失败。
注意:如果使用@NotNull,如果是空字符串就不会报错。而用NotBlank,空字符串也会报错。
通过注释名即可推断出校验的内容,message用作校验失败时的提示信息。
5、编写controller
@RestController public class TestController { @PostMapping( "/test") public String add(@RequestBody @Validated Agent agent) { return "你好"; } }
6、使用postman发起请求
结果如下:
{ "timestamp": "2022-09-07T03:48:12.999+0000", "status": 400, "error": "Bad Request", "errors": [ { "codes": [ "NotBlank.agent.email", "NotBlank.email", "NotBlank.java.lang.String", "NotBlank" ], "arguments": [ { "codes": [ "agent.email", "email" ], "arguments": null, "defaultMessage": "email", "code": "email" } ], "defaultMessage": "邮箱不能为空", "objectName": "agent", "field": "email", "rejectedValue": "", "bindingFailure": false, "code": "NotBlank" } ], "message": "Validation failed for object='agent'. Error count: 1", "path": "/test" }
二、统一异常处理
1、异常捕获类
经过对校验异常的debug发现,该异常为MethodArgumentNotValidException
import com.zwh.entity.RsData; import org.springframework.util.CollectionUtils; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.RestController; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.StringJoiner; @ControllerAdvice @RestController public class ExceptionHandler { private String paramValid = "参数不合法:"; /** * 用来处理validation异常,捕获post请求Body实体属性参数校验异常信息 * * @param ex * @return */ @org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class) public RsData resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) { List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors(); if (!CollectionUtils.isEmpty(objectErrors)) { StringJoiner msgJoiner = new StringJoiner(","); Set<String> errors = new HashSet<>(objectErrors.size() / 2); for (ObjectError objectError : objectErrors) { errors.add(objectError.getDefaultMessage()); } for (String error : errors) { msgJoiner.add(error); } String errorMessage = msgJoiner.toString(); return RsData.fail(paramValid + errorMessage); } return RsData.fail(paramValid + ex.getMessage()); } }
2、返回的响应体类
@Data public class RsData { private static final String SUCCESS = "0"; private static final String FAIL = "1"; private String code; private Object result; private String message; public static RsData success(String msg) { RsData rs = new RsData(); rs.setCode(SUCCESS); rs.setMessage(msg); return rs; } public static RsData success(String msg, Object result) { RsData rs = new RsData(); rs.setCode(SUCCESS); rs.setMessage(msg); rs.setResult(result); return rs; } public static RsData error(String msg) { RsData rs = new RsData(); rs.setCode(FAIL); rs.setMessage(msg); return rs; } public static RsData error(String msg, Object result) { RsData rs = new RsData(); rs.setCode(FAIL); rs.setMessage(msg); rs.setResult(result); return rs; } public static RsData fail(String result) { RsData rs = new RsData(); rs.setCode(FAIL); rs.setMessage("失败"); rs.setResult(result); return rs; } }
3、修改Controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
4、postman访问
三、分组校验
当我们遇到不同场景需要有不同的校验规则时候,我们可以使用分组校验。如:一个请求只校验姓名,一个请求只校验email
1、创建分组接口
名称自定义,也不需要实现,只是能做区分分组就行
FirstGroup.class
public interface FirstGroup { }
SecondGroup.class
public interface SecondGroup { }
2、实体类中使用分组
import javax.validation.constraints.NotBlank; @Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空",groups = SecondGroup.class) private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空",groups = FirstGroup.class) private String email; }
注意:如果将email划入FirstGroup,将name划到SecondGroup,而@Validated注解不指定分组(默认为Default),
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
此时由于Default分组没有要校验的属性,相当于不校验,结果如下:
{ "code": "0", "result": null, "message": "success" }
3、修改controller
(1)、当指定FirstGroup时:
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated(FirstGroup.class) Agent agent) { return RsData.success("success"); } }
结果如下:
{ "code": "1", "result": "参数不合法:邮箱不能为空", "message": "失败" }
(2)、当指定SecondGroup时
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated(SecondGroup.class) Agent agent) { return RsData.success("success"); } }
结果如下:
{ "code": "1", "result": "参数不合法:姓名不能为空", "message": "失败" }
(3)、当不指定分组时
当然不写时会有一个默认分组,所有不指定分组的属性都划到这个分组
实体类:
@Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空") private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空") private String email; }
controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated Agent agent) { return RsData.success("success"); } }
测试
{ "code": "1", "result": "参数不合法:邮箱不能为空,姓名不能为空", "message": "失败" }
修改实体类:
import javax.validation.constraints.NotBlank; import javax.validation.groups.Default; @Data public class Agent { /** * 代理人姓名 */ @NotBlank(message = "姓名不能为空",groups = Default.class) private String name; /** * 联系人邮箱 */ @NotBlank(message = "邮箱不能为空",groups = Default.class) private String email; }
修改controller
@RestController public class TestController { @PostMapping( "/test") public RsData add(@RequestBody @Validated(Default.class) Agent agent) { return RsData.success("success"); } }
结果:
{ "code": "1", "result": "参数不合法:邮箱不能为空,姓名不能为空", "message": "失败" }
四、JSR提供的校验注解API
@Null 被注释的元素必须为 null @NotNull 被注释的元素必须不为 null @AssertTrue 被注释的元素必须为 true @AssertFalse 被注释的元素必须为 false @Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值 @DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值 @Size(max=, min=) 被注释的元素的大小必须在指定的范围内 @Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内 @Past 被注释的元素必须是一个过去的日期 @Future 被注释的元素必须是一个将来的日期 @Pattern(regex=,flag=) 被注释的元素必须符合指定的正则表达式
Hibernate Validator提供的校验注解
@NotBlank(message =) 验证字符串非null,且长度必须大于0 @Email 被注释的元素必须是电子邮箱地址 @Length(min=,max=) 被注释的字符串的大小必须在指定的范围内 @NotEmpty 被注释的字符串的必须非空 @Range(min=,max=,message=) 被注释的元素必须在合适的范围内
标签:hibernate,springboot,rs,class,validator,message,RsData,public,String From: https://www.cnblogs.com/zwh0910/p/16664602.html