springboot项目中@Valid注解的使用-笔记

springboot项目中@Valid注解的使用-笔记

@Vaild介绍

@Valid 是jdk提供的,是jsr-303规范 ,@Valid支持复合bean的嵌套校验,可以用在方法、字段、构造器和参数上

@Valid嵌套校验测试

import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.Valid;
import java.time.LocalDateTime;
import com.alibaba.fastjson.JSONPath;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.Assert;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.annotation.*;



@Slf4j
@RestController
public class Test0529Api {
    @PostMapping("/t123")
    public UserReq test123(@Valid @RequestBody UserReq req){
        log.info("req:{}",req.toString());
        return req;
    }
}

@Data
public class UserReq {
    @NotBlank
    @Size(max = 30,min = 2,message = "长度需要在2-30之间")
    private String account;

    @Email
    private String email;

    @Pattern(regexp = "(?:0|86|\\+86)?1[3-9]\\d{9}",message = "必须是手机号")
    private String phone;

    /**
     * 必须是一个过去的或当前的日期,jdk提供的
     */
    @PastOrPresent
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")  //以特定格式字符串接收请求的日期参数,jackson会自动转为LocalDateTime
    private LocalDateTime  startDt;

    /**
     * 必须是一个将来的或当前的日期,jdk提供的
     */
    @FutureOrPresent  
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endDt;

    /**
     * 嵌套校验
     */
    @Valid
    private CompanyDTO company;

    /**
     * hibernate.validator包提供的 范围限制注解 @Range ,限制数值的大小
     */
    @Range(min = 1,max = 99)
    private Integer testCount;
}


@Data
public class CompanyDTO {
    @NotNull
    private Integer id;

    @NotBlank
    @Length(max = 30,min=4,message = "长度需要在4-30之间")
    private String name;

    @Pattern(regexp ="(010|02\\d|0[3-9]\\d{2})-?(\\d{6,8})",message = "必须是国内固定电话号码")
    private String tel;
}

测试发现抛MethodArgumentNotValidException异常,经过exceptionHandler处理后,返回

@ExceptionHandler({MethodArgumentNotValidException.class})
    public ResultVO<String> MethodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
        log.error("自动抛的MethodArgumentNotValidException",e);
        // 从异常对象中拿到ObjectError对象
        ObjectError objectError = e.getBindingResult().getAllErrors().get(0);
        log.error("objectError:{}", JSONObject.toJSONString(objectError, true));
        String field = String.valueOf(JSONPath.eval(objectError, "$.field"));
        log.error("field:{}", field);
        String objName = objectError.getObjectName();
        System.err.println(objName);
        // 然后提取错误提示信息进行返回
        return new ResultVO<>(ResultCodeEnum.VALIDATE_FAILED,
                objName + "." + field + objectError.getDefaultMessage());
    }

返回json打印错误提示信息

{
    "code": 9996,
    "msg": "参数校验异常",
    "content": "userReq.testCount需要在1和99之间",
    "timestamp": 1685347134748,
    "traceDateTime": "2023-05-29 15:58:54"
}

@Valid校验,人为干预BindingResult

人为干预BindingResult的,需要人工抛出异常
/**
     * @Valid+BindingResult  人为干预Binding判断
     *
     * @param req
     * @param bindingResult  当增加了BindingResult对象后,参数校验失败时不会自动抛异常,需要人工进行异常处理
     * @return
     */
    @PostMapping("/test003")
    public UserReq test003(@Valid @RequestBody UserReq req, BindingResult bindingResult){
        log.info("req:{}",req.toString());
        //人为干预BindingResult ,人工判断参数是否合法/有错误
        if (bindingResult.hasErrors()){
            //人工抛出异常, 可以对每个参数做特殊的判断
            ObjectError objectError = bindingResult.getAllErrors().get(0);
            String field = String.valueOf(JSONPath.eval(objectError, "$.field"));
            String objName = objectError.getObjectName();
            //这里把bind的参数异常 手动抛出为非法参数异常
            throw new IllegalArgumentException(objName + "." + field + objectError.getDefaultMessage());
        }
        return req;
    }
{
    "code": 9988,
    "msg": "非法参数异常",
    "content": "userReq.testCount需要在1和99之间",
    "timestamp": 1685348120036,
    "traceDateTime": "2023-05-29 16:15:20"
}

手动抛出的异常也要在exceptionHandler里处理

/**
     * 手动抛出的或 Assert断言的 非法参数异常
     *
     * @param e IllegalArgumentException
     * @return ResultVO
     */
    @ExceptionHandler({IllegalArgumentException.class})
    public ResultVO illegalArgumentExceptionHandler(IllegalArgumentException e) {
        log.error("人工抛出异常的IllegalArgumentException",e);
        return new ResultVO<>(ResultCodeEnum.VALIDATE_FAILED,
                e.getMessage());
    }

兜底方案,就是直接捕获处理Exception.class

/**
     * 未知异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler({Exception.class})
    public ResultVO otherExceptionHandle(Exception e) {
        log.error("otherExceptionHandle", e);
        return new ResultVO(ResultCodeEnum.ERROR, e.getMessage());
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Spring Boot,可以使用 Hibernate Validator(javax.validation)库来对字段进行验证,其包括使用 @Email 注解来验证电子邮件地址的有效性。 首先,确保在项目的依赖添加了 Hibernate Validator 的相关库。可以在 Maven 添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-validation</artifactId> </dependency> ``` 然后,在需要进行验证的实体类使用 @Email 注解来标记需要验证的字段。例如: ```java import javax.validation.constraints.Email; import javax.validation.constraints.NotBlank; public class User { @NotBlank(message = "邮箱不能为空") @Email(message = "请输入有效的电子邮件地址") private String email; // 其他字段和方法... } ``` 在上面的示例,@NotBlank 注解用来验证邮箱字段不能为空,@Email 注解用来验证邮箱地址的有效性。 接下来,在需要进行验证的地方(例如控制器方法),使用 @Valid 注解对实体类进行验证。例如: ```java import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RestController; @RestController @Validated public class UserController { @PostMapping("/users") public String createUser(@RequestBody @Valid User user) { // 处理创建用户的逻辑 return "User created successfully"; } } ``` 在上面的示例,@Validated 注解用来启用验证功能,@Valid 注解用来验证传入的 User 对象。 如果传入的邮箱地址不符合有效的电子邮件格式,验证将失败,并返回相应的错误消息。 请注意,以上示例仅为演示目的,实际使用可能会有其他配置和处理方式。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ThinkPet

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值