一、参数校验类注解
以一个时间校验注解为例
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = DateTimeValidator.class)
public @interface DateTime {
String message() default "格式错误";
String format() default "yyyy-MM-dd HH:mm:ss";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
@Constraint(validatedBy = DateTimeValidator.class)这里指定注解类实现方法,groups作为Validation注解中的一个属性信息作用是区分不同场景下使用注解
再看下实现类DateTimeValidator.java
其他注解参数参考链接:1、基于Validation的参数校验注解
public class DateTimeValidator implements ConstraintValidator<DateTime, String> {
private DateTime dateTime;
@Override
public void initialize(DateTime dateTime) {
this.dateTime = dateTime;
}
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
// 如果 value 为空则不进行格式验证,为空验证可以使用 @NotBlank @NotNull @NotEmpty 等注解来进行控制,职责分离
if (value == null) {
return true;
}
String format = dateTime.format();
if (value.length() != format.length()) {
return false;
}
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
try {
simpleDateFormat.parse(value);
} catch (Exception e){
return false;
}
return true;
}
}
使用testDTO.java
@Data
public class testDTO{
/**
* 开始时间
*/
@NotNull(message = "参数不能为空", groups = {Post.class})
@DateTime(format = "yyyy-MM-dd", message = "格式错误,正确格式为:yyyy-MM-dd")
private String beginTime;
/**
* 结束时间
*/
@NotNull(message = "参数不能为空", groups = {Update.class})
@DateTime(format = "yyyy-MM-dd", message = "格式错误,正确格式为:yyyy-MM-dd")
private String endTime;
}
这里是对请求的参数校验,groups可以根据情况改成自己的update、delete等
public interface Post {
}
public interface Update {
}...
因为是接口再看下controller调用的时候
public MyResp getInfo(@RequestBody @Validated({
Post.class })testDTO testDTO) {
....}
public MyResp updateInfo(@RequestBody @Validated({
Update.class })testDTO testDTO) {
....}
二、方法拦截类注解
主要是通过AOP实现方法拦截
以请求校验访问次数为例:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AccessLimit {
long limitTime() default 60000L;
int num() default 10;
}
拦截方法AccessLimitAop.java
@Aspect
@Component
public class AccessLimitAop {
@Autowired
private AccessLimitHandle accessLimitHandle;
private final static String PRE_ACCESS_LIMIT = "access_limit_";
/**
* 定义切入点
*/
@Pointcut("execution(* com.web.controller.*.*(..))")
public void cutPoint(){
}
/**
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("cutPoint()")
public Object limit(ProceedingJoinPoint joinPoint) throws Throwable{
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
if(method.isAnnotationPresent(AccessLimit.class)){
AccessLimit accessLimit = method.getAnnotation(AccessLimit.class);
long limitTime = accessLimit.limitTime();
int num = accessLimit.num();
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
String ip = IpUtil.getIpAddr(request);
String requestURI = request.getRequestURI();
//这里是校验访问次数的方法,这里就不都粘出来啦
boolean flag = accessLimitHandle.limitRequest(num,limitTime);
if (!flag){
return MyResp.result(Resp.ACCESS_LIMIT_ERR);
}
}
//验证通过进行放行
return joinPoint.proceed();
}
}
再看在controller调用
@AccessLimit(limitTime=60000L,num=5)
public void test(){
...
}
网友评论