SpringBoot使用validation

网友投稿 614 2023-03-17

SpringBoot使用validation

SpringBoot使用validation

前言

之前写了一个博客是关于使用SpringBoot使用validation-api实现参数校验,当时使用的注解都是validation-api自带的注解只能完成对空值、长度等简单的校验,在我们日常的使用当中会遇到对参数是否在枚举值类的校验,针对这种情况我们怎么来实现呢?

SpringBoot使用validation-api实现参数校验可参考我的博客:SpringBoot使用validation-api实现参数校验

正文

SpringBoot使用validation-api实现对枚举类参数校验

ValidationApi框架就是用来解决参数校验中代码冗余问题,ValidationApi框架提供一些注解用来帮助我们对请求参数进行校验。

Maven依赖

javax.validation

validation-api

2.0.1.Final

org.apache.commons

commons-lang3

3.3.2

org.projectlombok

lombok

1.18.2

true

com.github.xiaoymin

knife4j-spring-boot-starter

2.0.4

EnumValidate:用于对枚举校验的接口

/**

* 用于实现枚举类的校验

*/

public interface EnumValidate {

/**

* 校验枚举值是否存在

*/

boolean existValidate(T value);

}

ActionTypeEnumValid:用于对枚举类校验的自定义注解

@Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Constraint(validatedBy = {ActionTypeEnumValidator.class})

@Documented

public @interface ActionTypeEnumValid {

String message() default "";

Class>[] groups() default {};

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

Class>[] target() default {};

/**

* 允许的枚举

*

* @return

*/

Class extends Enum>> enumClass();

}

ActionTypeEnumValidator:枚举校验器

/**

* 用于校验ActionTypeEnumValidator

*/

public class ActionTypeEnumValidator implements ConstraintValidator {

private Class extends Enum> enumClass;

@Override

public void initialize(ActionTypeEnumValid actionTypeEnumValid) {

enumClass = actionTypeEnumValid.enumClass();

}

@Override

public boolean isValid(String value, ConstraintValidatorContext context) {

if (value == null || "".equals(value)) {

return true;

}

EnumValidate[] enums = (EnumValidate[]) enumClass.getEnumConstants();

if(enums ==null || enums.length == 0){

return false;

}

return enums[0].existValidate(value);

}

}

ActionTypeEnum:枚举类

@Getter

public enum ActionTypeEnum implements EnumValidate {

ACTION_INVOKR("invoke", "invoke"),

UNKNOWN_ERROR("no", "no");

/**

* 状态值

*/

private String couponType;

/**

* 状态描述

*/

private String couponTypeDesc;

AcomWonMnQFctionTypeEnum(String couponType, String couponTypeDesc) {

this.couponType = couponType;

this.couponTypeDesc = couponTypeDesc;

}

public static String getDescByType(String couponType) {

for (ActionTypeEnum type : ActionTypeEnum.values()) {

if (type.couponType.equals(couponType) ) {

return type.couponTypeDesc;

}

}

return null;

}

/**

* 判断是否在枚举类当中

* @param value

* @return

*/

@Override

public boolean existValidate(String value) {

if (value == null || "".equals(value)) {

return false;

}

for (ActionTypeEnum testEnum : ActionTypeEnum.values()) {

if (testEnum.getCouponType().equalsIgnoreCase(value)) {

return true;

}

}

return false;

}

public String getcouponTypeStr() {

return String.valueOf(this.couponType);

}

}

GlobalExceptionHandler:使用SpringMVC提供的异常处理机制,对ValidationApi的异常进行封装

@RestControllerAdvice

@Slf4j

public class GlobalExceptionHandler {

/**

* 忽略参数异常处理器

*

* @param e 忽略参数异常

* @return Response

*/

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler(MissingServletRequestParameterException.class)

public ResponseResult parameterMissingExceptionHandler(MissingServletRequestParameterException e) {

log.error("参数异常", e);

return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "请求参数 " + e.getParameterName() + " 不能为空");

}

/**

* 缺少请求体异常处理器

*

* @param e 缺少请求体异常

* @return Response

*/

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler(HttpMessageNotReadableException.class)

public ResponseResult parameterBodyMissingExceptionHandler(HttpMessageNotReadableException e) {

log.error("缺少请求体异常", e);

return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), "参数体不能为空");

}

/**

* 参数效验异常处理器

*

* @param e 参数验证异常

* @return ResponseInfo

*/

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler(MethodArgumentNotValidException.class)

public ResponseResult parameterExceptionHandler(MethodArgumentNotValidException e) {

log.error("参数验证异常", e);

// 获取异常信息

BindingResult exceptions = e.getBindingResult();

// 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息

if (exceptions.hasErrors()) {

List errors = exceptions.getAllErrors();

if (!errors.isEmpty()) {

// 这里列出了全部错误参数,按正常逻辑,只需要第一条错误即可

FieldError fieldError = (FieldError) errors.get(0);

return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), fieldError.getDefaultMessage());

}

}

return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR);

}

/**

* 自定义参数错误异常处理器

*

* @param e 自定义参数

* @return ResponseInfo

*/

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler({BusinessException.class})

public ResponseResult paramExceptionHandler(BusinessException e) {

log.error("业务异常", e);

// 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息

if (!StringUtils.isEmpty(e.getMessage())) {

return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR.getcouponTypeStr(), e.getMessage());

}

return new ResponseResult(CouponTypeEnum.PARAMETER_ERROR);

}

/**

* 其他异常

*

* @param e

* @return

*/

@ResponseStatus(HttpStatus.BAD_REQUEST)

@ExceptionHandler({Exception.class})

public ResponseResult otherExceptionHandler(Exception e) {

log.error("其他异常", e);

// 判断异常中是否有错误信息,如果存在就使用异常中的消息,否则使用默认消息

if (!StringUtils.isEmpty(e.getMessage())) {

return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR.getcouponTypeStr(), e.getMessage());

}

return new ResponseResult(CouponTypeEnum.UNKNOWN_ERROR);

}

}

验证

请求的封装类

/**

* 指令的封装类

*/

@Getter

@Setter

@ToString

public class CommandPOJO implements Serializable {

private static final long serialVersionUID = -8497328408069586664L;

//指令

@NotNull(message = "指令为必填项,不得为空")

@ActionTypeEnumValid(message = "该指令暂不支持,暂时只支持invoke", enumClass = ActionTypeEnum.class)

private String action ="invoke";

}

请求接口

@Valid 用于开启请求参数校验

@RestController

@Slf4j

@Api(value = "远程调用模块")

@RequestMapping("/xiyuanrpc")

public class RPCController {

@PostMapping("/rpcNettybyInvoke")

@ApiOperation(value = "rpc远程调用")

@InvokeParameterCheck

@MethodLogPrint

public ResponseResult rpcNettybyInvoke(@Valid @RequestBody CommandPOJO pojo) {

return NettyClientUtil.rpcNetty(pojo);

}

}

通过Knife4j访问对应接口

源码

项目源码可从的我的github中获取:github源码地址

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:uniapp小程序支付功能(uniapp小程序支付)
下一篇:app 跳转小程序(uniapp跳转小程序)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~