跨境派

跨境派

跨境派,专注跨境行业新闻资讯、跨境电商知识分享!

当前位置:首页 > 综合服务 > 电商平台 > 优雅的参数校验@Validated 实战 + 统一异常处理返回前端json 最全解析

优雅的参数校验@Validated 实战 + 统一异常处理返回前端json 最全解析

时间:2024-04-28 16:15:30 来源:网络cs 作者:亙句 栏目:电商平台 阅读:

标签: 返回  处理  异常  参数  统一  实战 

数据的校验的重要性就不用说了,即使在前端对数据进行校验的情况下,我们还是要对传入后端的数据再进行一遍校验,使用@Valid和@Validated注解可以很好的避免后端代码满屏if-else。

1 引入依赖

springboot版本小于2.3时spring-boot-starter-web包含了依赖不用再引入
当springboot版本大于2.3时需要手动引入依赖

          <!--第一种方式导入校验依赖:使用springboot时,在org\springframework\spring-context\5.2.1.RELEASE\spring-context-5.2.1.RELEASE.jar--><dependency>            <groupId>org.springframework.boot</groupId>            <artifactId>spring-boot-starter</artifactId>        </dependency>        <!--第二种方式导入校验依赖-->        <dependency>            <groupId>javax.validation</groupId>            <artifactId>validation-api</artifactId>            <version>2.0.1.Final</version>        </dependency>        <!--第三种方式导入校验依赖-->        <dependency>            <groupId>org.hibernate.validator</groupId>            <artifactId>hibernate-validator</artifactId>        </dependency>

2 @Valid和@Validated的用法(区别)

二者主要作用在于 都作为标准JSR-303规范,在检验Controller的入参是否符合规范时,使用@Validated或者@Valid在基本验证功能上没有太多区别。但是在分组、注解地方、嵌套验证等功能上两个有所不同:

@Valid注解用于校验,所属包为:javax.validation.Valid。
用在方法入参上无法单独提供嵌套验证功能。**能够用在成员属性(字段)**上,提示验证框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。

@Validated是@Valid 的一次封装,是Spring提供的校验机制使用。
用在方法入参上无法单独提供嵌套验证功能。不能用在成员属性(字段)上,也无法提示框架进行嵌套验证。能配合嵌套验证注解@Valid进行嵌套验证。

3 常用校验注解

@NotEmpty 被注释的字符串的不能为 null 也不能为空
@NotBlank 被注释的字符串非 null,并且必须包含一个非空白字符
@Null 被注释的元素(数字)必须为 null
@NotNull 被注释的元素(数字)必须不为 null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Pattern(regex=,flag=)被注释的元素必须符合指定的正则表达式
@Email 被注释的元素必须是 Email 格式。
@Min(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value)被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value)被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max=, min=) 被注释的元素(集合)的大小必须在指定的范围内
@Digits (integer, fraction)被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
@Length(min=,max=) 被注释的字符串的大小必须在指定的范围内
@Range(min=,max=,message=) 被注释的元素必须在合适的范围内

4 参数校验

4.1 控制器上加校验注解

千万不要忘记在类上加@Validated注解,否则验证注解不生效

@RestController@Api("阅读记录")@RequestMapping("/record")@Validatedpublic class ReadRecordController {    @Autowired    private ReadRecordService readRecordService;    @PostMapping("/addRecord")    @ApiOperation("新增阅读记录")    public ResponseResult addRecord(@RequestBody @Valid ReadRecord readRecord){        return readRecordService.addRecord(readRecord);    }    @ApiOperation("查询阅读记录")    @GetMapping("/getReadRecord")    public ResponseResult getReadRecord(@Valid @NotBlank(message = "fileCode不能传空值") String fileCode){        return readRecordService.getReadRecord(fileCode);    }}

4.2 实体类上加校验注解

对接受实体加注解的字段进行校验,如果验证失败,它将抛出MethodArgumentNotValidException异常。

@Datapublic class ReadRecord {    private String id;    private String companyName;    private String deleteFlag;    @NotBlank(message = "loginName不能传空")    private String loginName;    @NotBlank(message = "fileCode不能传空")    private String fileCode;    }

5 自定义注解

如果在写项目的过程中,参数需要的条件注解满足不上,则我们需要自定义注解来完成

5.1 创建一个自定义的注解类

@Documented@Constraint(validatedBy = PhoneNumberValidator.class)@Target({FIELD, PARAMETER})@Retention(RUNTIME)public@interface PhoneNumber {    String message() default "Invalid phone number";    Class[] groups() default {};    Class[] payload() default {};}

5.2 创建一个逻辑处理数据的方法

publicclass PhoneNumberValidator implements ConstraintValidator<PhoneNumber,String> {    @Override    public boolean isValid(String phoneField, ConstraintValidatorContext context) {        if (phoneField == null) {            // can be null            returntrue;        }        return phoneField.matches("^1(3[0-9]|4[57]|5[0-35-9]|8[0-9]|70)\\d{8}$") && phoneField.length() > 8 && phoneField.length() < 14;    }}

5.3使用自定义注解

@PhoneNumber(message = "phoneNumber 格式不正确")@NotNull(message = "phoneNumber 不能为空")private String phoneNumber;

6 统一异常处理

我们使用了@valiated注解,也写了@NotBlank校验,控制台也打印了校验信息,但是前端就是没有收到我们返回的校验信息.是因为我们没有自定义捕获异常后的处理方式,没有返回给前端这些处理信息。

如果要将报错信息返回给前端只需要对信息做统一异常处理就好。

@ControllerAdvicepublic class CustomHandle {    @ExceptionHandler(MethodArgumentNotValidException.class)    @ResponseBody    public ResponseResult methodArgumentNotValidException(MethodArgumentNotValidException e){        List<ObjectError> allErrors = e.getAllErrors();        List<String> collect = allErrors.stream()                .map(error -> error.getDefaultMessage())                .collect(Collectors.toList());        return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,collect.toString());    }}

至此便可将报错信息返回前端

{"token": null,"code": 501,"message": "[loginName不能传空]","data": null,"status": null}

如果觉得文章对您有用,还请一键三连哦!!!更多实用文章在主页!

本文链接:https://www.kjpai.cn/news/2024-04-28/163278.html,文章来源:网络cs,作者:亙句,版权归作者所有,如需转载请注明来源和作者,否则将追究法律责任!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

文章评论