spring Validation & Validation生效情况

使用 spring Validation

前提:springboot项目

使用 – – >springbootstartervalidation时,需要手动开启validation

1、配置类,开启validation

package com.cy.transmonitor.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;

@Configuration
@ComponentScan("com.cy.transmonitor") // 指定自定义校验注解需要扫描的包路径
public class ValidatorConfiguration {
 
    @Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        return new MethodValidationPostProcessor();
    }
}

注意可能需要补充依赖

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

2、添加配置

# 开启validation
spring:
  mvc:
    validation:
      enabled: true 

3、实体类使用校验注解

package com.cy.transmonitor.modules.trans.bean.vo;

import com.cy.transmonitor.validated.annotation.FlagValidator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("编辑请求参数实体类")
public class EntrustEditVo {

    @NotNull(message = "子账户id不能为空")
    @ApiModelProperty(value = "子账户ID", example = "987654321")
    private Long subAccountId;

    @NotBlank(message = "编号不能为空")
    @ApiModelProperty(value = "编号", example = "10001")
    private String entrustNum;
}

4、controller接口使用

使用需要进行校验入参实体需要使用@Validated装饰入参实体

    @ApiOperation(value = "修改信息", notes = "根据信息的ID,修改信息")
    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    public ResponseEntity<String> edit( @ApiParam(name = "entrustEditVo", value = "信息", required = true)@Validated @RequestBody EntrustEditVo entrustEditVo){
        ResponseEntity<String> res = new ResponseEntity<>(ResponseEnum.SUCCESS);
        try {
            entrustService.update(entrustEditVo);
        } catch (Exception e) {
            logger.error("edit 修改信息异常,入参:{}",entrustEditVo, e);
            res.setResponseCode(ResponseEnum.SYSTEM_ERROR);
            if (e instanceof TransLogicException) {
                res.setData(e.getMessage());
            }
        }
        return res;
    }

使用springboot Validation

1、引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

2、实体类使用

package com.cy.transmonitor.modules.trans.bean.vo;

import com.cy.transmonitor.validated.annotation.FlagValidator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("编辑请求参数实体类")
public class EntrustEditVo {

    @NotNull(message = "子账户id不能为空")
    @ApiModelProperty(value = "子账户ID", example = "987654321")
    private Long subAccountId;

    @NotBlank(message = "编号不能为空")
    @ApiModelProperty(value = "编号", example = "10001")
    private String entrustNum;
}

3、controller使用

使用需要进行校验的入参实体需要使用@Validated装饰入参实体

    @ApiOperation(value = "修改信息", notes = "根据信息的ID,修改信息")
    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    public ResponseEntity<String> edit( @ApiParam(name = "entrustEditVo", value = "信息", required = true)@Validated @RequestBody EntrustEditVo entrustEditVo){
        ResponseEntity<String> res = new ResponseEntity<>(ResponseEnum.SUCCESS);
        try {
            entrustService.update(entrustEditVo);
        } catch (Exception e) {
            logger.error("edit 修改信息异常,入参:{}",entrustEditVo, e);
            res.setResponseCode(ResponseEnum.SYSTEM_ERROR);
            if (e instanceof TransLogicException) {
                res.setData(e.getMessage());
            }
        }
        return res;
    }

常见注解说明

注解 描述
@Null 验证对象是否null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotEmpty 检查约束元素是否为NULL或者是EMPTY
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格
@AssertTrue 验证Boolean对象是否为true
@AssertFalse 验证Boolean对象是否为false
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定范围之内
@Length(min=, max=) 验证字符串长度
@Past 验证Date和Calendar对象是否在当前时间之前
@Future 验证Date和Calendar对象是否在当前时间之后
@Pattern 验证String对象是否符合正则表达式规则
@Min 验证Number和String对象是否大等于指定的值
@Max 验证Number和String对象是否小等于指定的值
@DecimalMax 标注的值必须不大于约束指定最大值
@DecimalMin 标注的值必须不小于约束指定最小值
@Digits 验证字符串是否是符合指定格式数字integer指定整数精度fraction指定小数精度
@Range 注释元素必须在合适的范围内

自定义校验注解

1、自定义注解类

package com.cy.transmonitor.validated.annotation;

import com.cy.transmonitor.validated.handler.FlagValidatorHandler;

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = FlagValidatorHandler.class)
public @interface FlagValidator {

    String[] value();

    String message() default "flag value is invalid";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

2、注解处理

package com.cy.transmonitor.validated.handler;

import com.cy.transmonitor.validated.annotation.FlagValidator;

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class FlagValidatorHandler implements ConstraintValidator<FlagValidator, Integer> {

    private List<Integer> values;

    @Override
    public void initialize(FlagValidator constraintAnnotation) {
        values = Arrays.stream(constraintAnnotation.value())
                .map(Integer::parseInt)
                .collect(Collectors.toList());
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
        if (values.contains(value)) {
            return true;
        }
        context.disableDefaultConstraintViolation();
        context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate())
                .addConstraintViolation();
        return false;
    }
}

3、使用注解

package com.cy.transmonitor.modules.trans.bean.vo;

import com.cy.transmonitor.validated.annotation.FlagValidator;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ApiModel("编辑请求参数实体类")
public class EntrustEditVo {

    @NotNull(message = "子账户id不能为空")
    @ApiModelProperty(value = "子账户ID", example = "987654321")
    private Long subAccountId;

    @NotBlank(message = "编号不能为空")
    @ApiModelProperty(value = "编号", example = "10001")
    private String entrustNum;

    @ApiModelProperty(value = "成交数量", example = "100.5")
    private BigDecimal dealCount;

    @ApiModelProperty(value = "成交价格", example = "20.05")
    private BigDecimal dealPrice;

    @FlagValidator(value = {"1","2","4","8","16","32","64","128"}, message = "状态取值正确")
    @ApiModelProperty(value = "状态: 1-已提交 2-已挂单 4-废单 8-部分成交 16-已成交 32-待撤单 64-已撤单 128-未完成", example = "1")
    private Integer state;
}

4、controller使用

使用需要进行校验的入参实体需要使用@Validated装饰入参实体

    @ApiOperation(value = "修改信息", notes = "根据信息的ID,修改信息")
    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    public ResponseEntity<String> edit( @ApiParam(name = "entrustEditVo", value = "信息", required = true)@Validated @RequestBody EntrustEditVo entrustEditVo){
        ResponseEntity<String> res = new ResponseEntity<>(ResponseEnum.SUCCESS);
        try {
            entrustService.update(entrustEditVo);
        } catch (Exception e) {
            logger.error("edit 修改信息异常,入参:{}",entrustEditVo, e);
            res.setResponseCode(ResponseEnum.SYSTEM_ERROR);
            if (e instanceof TransLogicException) {
                res.setData(e.getMessage());
            }
        }
        return res;
    }

注意

1、分组校验的使用

1.1 实体类

package com.cy.transmonitor.modules.trans.bean.vo;

import com.cy.transmonitor.validated.annotation.Create;
import com.cy.transmonitor.validated.annotation.FlagValidator;
import com.cy.transmonitor.validated.annotation.Update;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="SecurityAccountEditVo对象", description="修改")
public class SecurityAccountEditVo {
    // 指定校验分组
    @NotNull(groups = {Update.class},message = "更新时,id不能为空")
    @ApiModelProperty(value = "ID,变更时候必传,新增时候不传", example = "1")
    private Long id;

    @ApiModelProperty(value = "名称", example = "001")
    private String name;

    @ApiModelProperty(value = "总资产", example = "1000000.00")
    private BigDecimal capitalFund;

    @FlagValidator(value = {"1","2"},message = "账户类型取值正确",groups = {Update.class, Create.class})
    @ApiModelProperty(value = "账户类型:1-普通账户,2-借出账户", example = "1")
    private Integer accountType;

    @ApiModelProperty(value = "描述", example = "这是一个普通")
    private String description;

    @FlagValidator(value = {"1","4"},message = "账户状态取值不正确",groups = {Update.class, Create.class})
    @ApiModelProperty(value = "账户状态; 1-正常 4-删除", example = "1")
    private Integer state;
}

1.2 controller使用

@RequestMapping(value = "/edit",method = RequestMethod.POST)
    @ApiOperation(value = "修改", notes = "修改")
	// @Validated(Update.class) 指定校验分组
    public ResponseEntity<String> edit(@RequestBody @Validated(Update.class) SecurityAccountEditVo securityAccountEditVo){
        ResponseEntity<String> res = new ResponseEntity<>(ResponseEnum.SUCCESS);
        try {
            SecurityAccount securityAccount = new SecurityAccount();
            BeanUtils.copyProperties(securityAccountEditVo,securityAccount);
            securityAccountService.upd(securityAccount);
        } catch (Exception e) {
            logger.error("edit 修改异常 :" ,e);
            res.setResponseCode(ResponseEnum.SYSTEM_ERROR);
        }
        return res;
    }

1.3 注解准备

自定义注解,用于自定分组情况,注解没有任何实现

package com.cy.transmonitor.validated.annotation;

public @interface Create {
}
package com.cy.transmonitor.validated.annotation;

public @interface Update {
}

1.4 注意-不生效场景

controller层指定分组之后,如果入参实体上没有生命分组,那么校验不生效如下

    @RequestMapping(value = "/edit",method = RequestMethod.POST)
    @ApiOperation(value = "xxx", notes = "xxx")
    public ResponseEntity<String> edit(@RequestBody @Validated(Update.class) SecurityAccountEditVo securityAccountEditVo){
        ResponseEntity<String> res = new ResponseEntity<>(ResponseEnum.SUCCESS);
        try {
            SecurityAccount securityAccount = new SecurityAccount();
            BeanUtils.copyProperties(securityAccountEditVo,securityAccount);
            securityAccountService.upd(securityAccount);
        } catch (Exception e) {
            logger.error("edit异常 :" ,e);
            res.setResponseCode(ResponseEnum.SYSTEM_ERROR);
        }
        return res;
    }
package com.cy.transmonitor.modules.trans.bean.vo;

import com.cy.transmonitor.validated.annotation.Create;
import com.cy.transmonitor.validated.annotation.FlagValidator;
import com.cy.transmonitor.validated.annotation.Update;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

import javax.validation.constraints.NotNull;
import java.math.BigDecimal;

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
@ApiModel(value="SecurityAccountEditVo对象", description="修改")
public class SecurityAccountEditVo {
    @NotNull(groups = {Update.class},message = "更新时,id不能为空")
    @ApiModelProperty(value = "ID,变更时候必传,新增时候不传", example = "1")
    private Long id;

    // 不生效
    @FlagValidator(value = {"1","2"},message = "账户类型取值不正确")
    @ApiModelProperty(value = "账户类型:1-普通账户,2-借出账户", example = "1")
    private Integer accountType;

    // 生效
    @FlagValidator(value = {"1","4"},message = "账户状态取值不正确",groups = {Update.class, Create.class})
    @ApiModelProperty(value = "账户状态; 1-正常 4-删除", example = "1")
    private Integer state;
}

原文地址:https://blog.csdn.net/qq_40469712/article/details/131071921

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_50218.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注