自定义注解使用
1:元注解
java.lang.annotation 下定义了元注解
2:元注解 @Retention 生命周期
3:元注解 @Target 作用范围
4:新建java类选择注解@Annitation
5:示例建立MyAnnitation注解
需求:自定义注解校验请求参数只能是指定值
比如 请求接口 type 参数 只能是"1"、“2”、“3”
方法:
1:引入validation校验jar包
org.springframework.boot
spring-boot-starter-validation
2:建立自定义注解
自定义注解范围 :字段、枚举的常量、方法参数
使用@Constraint 指定校验逻辑的类
@Target({ElementType.PARAMETER,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = EnumRangeValidator.class)
public @interface CheckEnum {
// 校验能输入的值
String[] rang();
// 错误提示
String message() default "输入的内容不在规定范围";
// 名称固定参数:校验分组信息
Class>[] groups() default {};
// 名称固定参数:加载的负载
Class extends Payload>[] payload() default {};
}
3:建立校验逻辑的类EnumRangeValidator
public class EnumRangeValidator implements ConstraintValidator {
private String[] range;
@Override
public void initialize(CheckEnum constraintAnnotation) {
// 初始化将注解中的枚举内容放数组range
range=constraintAnnotation.rang();
}
@Override
public boolean isValid(String request, ConstraintValidatorContext constraintValidatorContext) {
// 判断输入的值在不在 注解设置的范围
if(StringUtils.isNotBlank(request)){
if(range!=null && range.length>0){
return Arrays.asList(range).contains(request);
}
}
return false;
}
}
4:全局异常监听控制返回
这里简单返回String 实际开发中应该定义全局返回对象
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler({MethodArgumentNotValidException.class})
private String argumentsNotValid(MethodArgumentNotValidException e) {
try {
var fieldError = e.getBindingResult().getFieldError();
var defaultMessage = fieldError.getDefaultMessage();
log.error("参数校验不通过 ", e);
return defaultMessage;
} catch (NullPointerException exception) {
log.error("fieldError 为空", e);
return "参数异常";
}
}
@ResponseBody
@ResponseStatus(HttpStatus.OK)
@ExceptionHandler(ConstraintViolationException.class)
private String multiArgumentNotValid(ConstraintViolationException e) {
var constraintViolations = e.getConstraintViolations();
var reduce =
constraintViolations.stream()
.map(ConstraintViolation::getMessage)
.reduce((x, y) -> x + " " + y)
.orElse("");
log.error("参数校验不通过 ", e);
return reduce;
}
}
5:请求入参对象EnumValidRequest
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EnumValidRequest {
/**
* @NotBlank 不能为空校验
*/
@NotBlank(message = "id不能为空!")
private String id;
private String name;
/**
* 设置类型 值只能是1、2、3
* 使用自定义枚举校验 类型只能传值1、2、3
*/
@CheckEnum(rang = {"1","2","3"})
private String type;
}
6:请求接口test/check/enum
使用定义的EnumValidRequest 作为参数
@Slf4j
@RestController
@RequestMapping("/test")
@Validated
public class RequestController {
@PostMapping("/check/enum")
public String getA(@Valid @RequestBody EnumValidRequest request){
log.debug("a请求执行:{}",request);
return "A";
}
}
7:启动项目 访问接口test/check/enum