当前位置: 首页 > news >正文

java spring validation 自动、手动校验

目录

一、自动校验

第一步,导入依赖

第二步,统一异常处理

第三步,定义接口接收实体DTO

第四步,在Contoller接口中增加参数注解@Validated

第五步,测试结果

二、手动校验

第一步,校验工具类

第二步,测试结果


参数校验是一个常见的问题,比如字段非空,字段长度限制,邮箱格式、手机格式验证等等。

避免校验规则,写一大串步骤,繁琐重复。

Hibernate Validator为此提供了一套比较完善、便捷的验证实现方式。

一、自动校验

第一步,导入依赖

项目已经引入spring-boot-starter-web包里面有hibernate-validator包,不需要引用hibernate validator依赖。

项目还未引入spring-boot-starter-web包可以引入以下依赖:

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-validator</artifactId><version>4.3.1.Final</version>
</dependency>

第二步,统一异常处理

ValidateExceptionController

import com.central.common.model.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;import java.util.HashMap;
import java.util.Map;/*** 统一异常处理*/
@Slf4j
@RestControllerAdvice
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ValidateExceptionController {//如果能精确匹配到该异常就会执行这个方法,后续执行下面的方法@ExceptionHandler(value = MethodArgumentNotValidException.class)public Result handelValidateException(MethodArgumentNotValidException e) {log.error("数据校验出现问题:{},异常类型:{}", e.getMessage(), e.getClass());Map<String, String> map = new HashMap<>();//1.获取校验错误结果BindingResult result = e.getBindingResult();result.getFieldErrors().forEach(fieldError -> {//获取每个错误的属性名字String field = fieldError.getField();//获取每个错误提示信息String defaultMessage = fieldError.getDefaultMessage();map.put(field, defaultMessage);});return Result.failed(map, "数据校验错误");}}
第三步,定义接口接收实体DTO

定义校验规则,可以参考

Java Validation (验证注解)-CSDN博客

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;@Data
@ApiModel("售后申请接口-接收实体DTO")
public class AfterServiceApplyDTO implements Serializable {@NotBlank(message = "订单编号不为空")@ApiModelProperty(value = "订单编号", required = true)private String grandsonOrderCode;@NotNull(message = "申请售后类型不为空")@ApiModelProperty(value = "申请售后类型: 10:退货 20:换货 30:维修", required = true)private Integer customerExpect;@NotBlank(message = "产品问题描述不为空")@ApiModelProperty(value = "产品问题描述", required = true)private String questionDesc;@ApiModelProperty("问题描述图片链接地址,多个图片以“,”分隔")private String questionPic;@Valid@NotNull(message = "客户信息实体不为空")@ApiModelProperty("客户信息实体")private AfterSaleCustomerDTO asCustomerDto;@Valid@Size(min = 1, max = 1, message = "只能申请1个商品")@NotNull(message = "申请单明细列表不为空")@ApiModelProperty("申请单明细列表")private List<AfterSaleDetailDTO> asDetailDtos;}
第四步,在Contoller接口中增加参数注解@Validated

表示只校验当前参数

@Api(tags = "【售后】订单售后API接口")
@RestController
public class AfterServiceApiController {/*** 售后申请接口* @param afterServiceApplyDTO 售后申请参数* @return 操作结果*/@ApiOperation("售后申请接口")@PostMapping("/afterService/api/apply")public Result apply(@Validated @RequestBody AfterServiceApplyDTO afterServiceApplyDTO) {// todoreturn null;}}
第五步,测试结果

Postman发送错误数据触发验证测试

二、手动校验

第一步,校验工具类

ValidatorUtils

import com.central.business.afterService.dto.AfterServiceApplyDTO;
import com.central.common.model.Result;import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;/*** 校验工具类*/
public class ValidatorUtils {private static final Validator validator;// 第一种方式创建Validatorstatic {// 普通模式(默认是这个模式)// 普通模式(会校验完所有的属性,然后返回所有的验证失败信息)validator = Validation.buildDefaultValidatorFactory().getValidator();}//第二种方式创建Validator
//    static {
//        // 1.普通模式(默认是这个模式)
//        // 普通模式(会校验完所有的属性,然后返回所有的验证失败信息)
//        // .failFast(false)
//        // 或 .addProperty("hibernate.validator.fail_fast", "false")
//
//        // 2.快速失败返回模式
//        // 快速失败返回模式(只要有一个验证失败,则返回)
//        // .addProperty("hibernate.validator.fail_fast", "true")
//        // 或 .failFast(true)
//        ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class)
//                .configure()
//                .failFast(true).addProperty("hibernate.validator.fail_fast", "true")
//                .buildValidatorFactory();
//        validator = validatorFactory.getValidator();
//    }/*** 校验对象,返回校验失败List信息** @param object 对象* @param groups 组* @return 校验失败List信息*/public static List<String> validateEntity(Object object, Class<?>... groups) {List<String> list = new ArrayList<>();Set<ConstraintViolation<Object>> validate = validator.validate(object, groups);for (ConstraintViolation<Object> violation : validate) {list.add(violation.getMessage());}return list;}/*** 校验对象,返回校验失败Map信息** @param object 对象* @param groups 组* @return 校验失败Map信息,key为属性(字段名),value为校验失败信息*/public static Map<String, String> validateEntityProperty(Object object, Class<?>... groups) {Map<String, String> map = new HashMap<>();Set<ConstraintViolation<Object>> validate = validator.validate(object, groups);for (ConstraintViolation<Object> violation : validate) {map.put(violation.getPropertyPath().toString(), violation.getMessage());}return map;}/*** 校验对象,返回校验失败Result信息** @param object 对象* @param groups 组* @return 校验失败Result,校验失败返回错误信息,成功返回成功信息*/public static Result<Map<String, String>> validateEntityResult(Object object, Class<?>... groups) {Map<String, String> map = new HashMap<>();Set<ConstraintViolation<Object>> validate = validator.validate(object, groups);for (ConstraintViolation<Object> violation : validate) {map.put(violation.getPropertyPath().toString(), violation.getMessage());}if (map.size() > 0) {return Result.failed(map, "数据校验错误!");}return Result.succeed("数据校验成功!");}public static void main(String[] args) {AfterServiceApplyDTO afterServiceApplyDTO = new AfterServiceApplyDTO();System.out.println(validateEntityResult(afterServiceApplyDTO));}
}
第二步,测试结果
Result(datas={questionDesc=产品问题描述不为空, grandsonOrderCode=供应链三级订单编号不为空, reason=售后原因不为空, asCustomerDto=客户信息实体不为空, asDetailDtos=申请单明细列表不为空, businessPlatformCode=业务商城售后申请单号不为空, customerExpect=申请售后类型不为空}, resp_code=1, resp_msg=数据校验错误!)


http://www.mrgr.cn/news/25088.html

相关文章:

  • python库安装失败问题
  • 使用阿里OCR身份证识别
  • 计算机网络(Hub 集线器、交换机、路由器)
  • 在对接电影票API时如何快速进行错误处理和调试
  • 情感支持与疏导:帮助自闭症家属走出困境
  • 组件的使用
  • 项目管理:如何确保目标的实现?
  • 关于项目中的内存问题、死锁问题如何定位?——Valgrind
  • 【工资计算 / 2】
  • Python爱心射线(完整代码)
  • GaussDB关键技术原理:高弹性(四)
  • 【C++】C++ STL探索:容器适配器 Stack 与 Queue 的使用及模拟实现
  • Debezium数据同步基础概论
  • QtC++截图支持获取鼠标光标
  • 120张网络安全等保拓扑大全,零基础入门到精通,收藏这一篇就够了
  • audio耳麦拔插显示图标逻辑
  • Android 12 Launcher3 去掉Hotseat
  • 计算机深度:AI Agent - 通往AGI的核心基础
  • 【React源码解析】深入剖析Scheduler源码
  • 【课程系列12】某客时间AI大模型微调训练营