AspectJ 自定义参数注释在 Spring 引导中不起作用
AspectJ custom parameter annotation not working in Spring Boot
我正在尝试创建一个名为 @ValidDate
的自定义注释来检查给定的日期对象是否不早于一周。
这是注释定义。
package com.verimi.kitchenservice.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface ValidDate {
}
这是 AspectJ 行为定义 class。
package com.verimi.kitchenservice.validators;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DateValidator {
@Before(value = "@annotation(com.verimi.kitchenservice.annotations.ValidDate)")
public Object before(JoinPoint parameter) {
System.out.println( "called here" + parameter.toString() );
return null;
}
}
这是我的 RestController 中的用法:
@GetMapping("/week_plan")
public List<DayOfService> all(@RequestParam("date") @DateTimeFormat(pattern="yyyy-MM-dd") @ValidDate Date requestedDate) {
List<DayOfService> dayOfServiceList = new ArrayList<>();
...
}
我的 System.out.println 没有被调用。当我如下更改方面时,它从启动 Spring Boot.
开始就到达 System.out.println 行
@Before("execution(* *(..))")
如果它像上面那样工作,为什么不对 @annotation
工作?
我也有以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.4.3</version>
</dependency>
首先,您必须将验证启动器添加到您的 pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
接下来您必须创建自己的验证注释:
@Documented
@Constraint(validatedBy = DateValidator.class)
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidDate {
String message() default "Date is not of last week";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
那么你需要一个验证器:
public class DateValidator implements ConstraintValidator<ValidDate, LocalDate> {
@Override
public boolean isValid(LocalDate value, ConstraintValidatorContext context) {
return dateIsOfLastWeek(value);
}
private boolean dateIsOfLastWeek(LocalDate value) {
return value.isAfter(LocalDate.now().plusDays(7)) && value.isBefore(LocalDate.now());
}
}
最后你必须给控制器添加注解:
@Validated // Will validate in this controller
@RestController
public class ValidController {
@GetMapping("validation")
public String get(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") @ValidDate LocalDate requestedDate) {
return "valid";
}
// The exception handler is need to return a status 400 instead of 500
// plus the message in the body of the response
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<String> onValidationError(Exception e) {
return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST);
}
}
我正在尝试创建一个名为 @ValidDate
的自定义注释来检查给定的日期对象是否不早于一周。
这是注释定义。
package com.verimi.kitchenservice.annotations;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
public @interface ValidDate {
}
这是 AspectJ 行为定义 class。
package com.verimi.kitchenservice.validators;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.stereotype.Component;
@Aspect
@Component
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DateValidator {
@Before(value = "@annotation(com.verimi.kitchenservice.annotations.ValidDate)")
public Object before(JoinPoint parameter) {
System.out.println( "called here" + parameter.toString() );
return null;
}
}
这是我的 RestController 中的用法:
@GetMapping("/week_plan")
public List<DayOfService> all(@RequestParam("date") @DateTimeFormat(pattern="yyyy-MM-dd") @ValidDate Date requestedDate) {
List<DayOfService> dayOfServiceList = new ArrayList<>();
...
}
我的 System.out.println 没有被调用。当我如下更改方面时,它从启动 Spring Boot.
开始就到达 System.out.println 行@Before("execution(* *(..))")
如果它像上面那样工作,为什么不对 @annotation
工作?
我也有以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<version>2.4.3</version>
</dependency>
首先,您必须将验证启动器添加到您的 pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
接下来您必须创建自己的验证注释:
@Documented
@Constraint(validatedBy = DateValidator.class)
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidDate {
String message() default "Date is not of last week";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
那么你需要一个验证器:
public class DateValidator implements ConstraintValidator<ValidDate, LocalDate> {
@Override
public boolean isValid(LocalDate value, ConstraintValidatorContext context) {
return dateIsOfLastWeek(value);
}
private boolean dateIsOfLastWeek(LocalDate value) {
return value.isAfter(LocalDate.now().plusDays(7)) && value.isBefore(LocalDate.now());
}
}
最后你必须给控制器添加注解:
@Validated // Will validate in this controller
@RestController
public class ValidController {
@GetMapping("validation")
public String get(@RequestParam("date") @DateTimeFormat(pattern = "yyyy-MM-dd") @ValidDate LocalDate requestedDate) {
return "valid";
}
// The exception handler is need to return a status 400 instead of 500
// plus the message in the body of the response
@ExceptionHandler(ConstraintViolationException.class)
public ResponseEntity<String> onValidationError(Exception e) {
return new ResponseEntity(e.getMessage(), HttpStatus.BAD_REQUEST);
}
}