数据校验JSR303入门实践

数据校验JSR303入门实践

1 基础校验

1.引入pom

javax.validation
validation-api
2.0.1.Final

2.在Controller入口处增加@Valid
3.在实体属性上增加校验规则注解 如@NotBlank和 @URL(是hibernate提供的注解,实现了JSR303规范)
3.1使用@URL 需要引入hibernate pom

org.hibernate.validator
hibernate-validator
6.2.0.Final

2 分组校验

1.在Controller入口处替换@Valid为@Validated 并指定分组接口,如@Validated(value = UpdateValidateGroup.class)
2.在实体属性校验规则注解中设置groups参数,指定为分组接口类,如
@NotNull(groups = {UpdateValidateGroup.class}) 更新操作不能为null
@Null(groups = {AddValidateGroup.class}) 新增操作必须为null
3.测试生效

3 自定义校验

1.创建校验组件接口ListValue
2.创建自定义校验器 ListValueValidatorForInteger
3.在组件接口中指定自定义校验器,如@Constraint(validatedBy = {ListValueValidatorForInteger.class})
4.注解到实体属性上 如 @ListValue(value = {0, 1}, message = “仅支持0和1”, groups = AddValidateGroup.class)
5.测试生效

4 上code

4.1 导入POM

        <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>
            <version>6.2.0.Final</version>
        </dependency>

4.2 定义实体类

import com.iosc.bcmls.bcmlsps1.validate.ListValue;
import com.iosc.bcmls.bcmlsps1.validate.group.AddValidateGroup;
import com.iosc.bcmls.bcmlsps1.validate.group.UpdateValidateGroup;
import lombok.Data;
import org.hibernate.validator.constraints.URL;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Pattern;
import java.io.Serializable;

@Data
public class BrandEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    @NotNull(groups = {UpdateValidateGroup.class})
    @Null(groups = {AddValidateGroup.class})
    private Long brandId;

    /**
     * 约束name不能为null,且至少有一个非空字符
     */
    @NotBlank(message = "品牌名必须提交", groups = {AddValidateGroup.class})
    private String name;

    /**
     * URL是hibernate提供的注解,实现了JSR303规范。约束如果logo不为null的话,必须符合url格式
     */
    @NotBlank(message = "logo不能为空")
    @URL(message = "logo格式不符")
    private String logo;

    private String desc;
    /**
     * 自定义校验组件 ListValue
     *
     * @Pattern(regexp = "[0-1]")
     * pattern不支持Integer
     */
    @ListValue(value = {0, 1}, message = "仅支持0和1", groups = AddValidateGroup.class)
    private Integer showStatus;

    /**
     * 使用正则表达式约束字段
     */
    @Pattern(regexp = "^[a-zA-Z]$", message = "首字母必须是一个字母")
    private String firstLetter;

    @Min(value = 0, message = "排序字段必须大于等于0")
    private Integer sort;
}

4.3 controller入口类

import com.alibaba.cola.dto.SingleResponse;
import com.iosc.bcmls.bcmlsps1.domain.BrandEntity;
import com.iosc.bcmls.bcmlsps1.validate.group.AddValidateGroup;
import com.iosc.bcmls.bcmlsps1.validate.group.UpdateValidateGroup;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;

@RestController
@RequestMapping("/validate")
public class Jsr303Controller {

    /**
     * 【基础校验】
     * 1.引入pom
     *         <dependency>
     *             <groupId>javax.validation</groupId>
     *             <artifactId>validation-api</artifactId>
     *             <version>2.0.1.Final</version>
     *         </dependency>
     * 2.在Controller入口处增加@Valid
     * 3.在实体属性上增加校验规则注解 如@NotBlank和 @URL(是hibernate提供的注解,实现了JSR303规范)
     * 3.1使用@URL 需要引入hibernate pom
     *        <dependency>
     *             <groupId>org.hibernate.validator</groupId>
     *             <artifactId>hibernate-validator</artifactId>
     *             <version>6.2.0.Final</version>
     *         </dependency>
     *
     * 【分组校验】
     * 1.在Controller入口处替换@Valid为@Validated 并指定分组接口,如@Validated(value = UpdateValidateGroup.class)
     * 2.在实体属性校验规则注解中设置groups参数,指定为分组接口类,如
     *     @NotNull(groups = {UpdateValidateGroup.class})   更新操作不能为null
     *     @Null(groups = {AddValidateGroup.class})         新增操作必须为null
     * 3.测试生效
     *
     * 【自定义校验组件】
     * 1.创建校验组件接口ListValue
     * 2.创建自定义校验器 ListValueValidatorForInteger
     * 3.在组件接口中指定自定义校验器,如@Constraint(validatedBy = {ListValueValidatorForInteger.class})
     * 4.注解到实体属性上 如 @ListValue(value = {0, 1}, message = "仅支持0和1", groups = AddValidateGroup.class)
     * 5.测试生效
     *
     *
     * @param brandEntity
     * @return
     */
    @PostMapping("base")
    public SingleResponse base(@RequestBody @Valid BrandEntity brandEntity) {
        return SingleResponse.of("base validate ok!");
    }

    @PostMapping("update")
    public SingleResponse update(@RequestBody @Validated(value = UpdateValidateGroup.class) BrandEntity brandEntity) {
        return SingleResponse.of("update validate ok!");
    }


    @PostMapping("add")
    public SingleResponse add(@RequestBody @Validated(value = AddValidateGroup.class) BrandEntity brandEntity) {
        return SingleResponse.of("add validate ok!");
    }
}

4.4 全局异常处理

import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.util.NestedServletException;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * description: 全局异常处理
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 参数校验异常
     *
     * @param exception
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public Response handleArgumentException(MethodArgumentNotValidException exception) {
        BindingResult bindingResult = exception.getBindingResult();
        List<FieldError> fieldErrors = bindingResult.getFieldErrors();
        Map<String, String> map = new HashMap<>();
        for (FieldError fieldError : fieldErrors) {
            map.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        SingleResponse response = new SingleResponse();
        response.setData(map);
        response.setCode("10001");
        response.setMsg("请求参数不合法");
        return response;
    }


    /**
     * 未知异常
     *
     * @param exception
     * @param webRequest
     * @return
     */
    @ExceptionHandler({Exception.class, NestedServletException.class, IllegalStateException.class})
    public Response handleOtherException(Exception exception, WebRequest webRequest) {
        log.error("global exception handleOtherException", exception);
        return SingleResponse.buildFailure("10000", exception.getMessage());
    }
}

4.5 分组校验

public interface AddValidateGroup {
}
public interface UpdateValidateGroup {
}

4.6 自定义校验组件

定义注解

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Retention(RUNTIME)
@Documented
@Constraint(validatedBy = {ListValueValidatorForInteger.class})
public @interface ListValue {
    String message() default "{com.validate.group.ListValue.message}";

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

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

    int[] value() default {};
}

定义校验器

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.HashSet;

public class ListValueValidatorForInteger implements ConstraintValidator<ListValue, Integer> {

    private HashSet<Integer> set = new HashSet<>();

    @Override
    public void initialize(ListValue listValue) {
        int[] value = listValue.value();
        for (int i : value) {
            set.add(i);
        }
    }

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return set.contains(value);
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值