Spring boot AspectJ自定义参数注释在Spring Boot中不起作用

Spring boot AspectJ自定义参数注释在Spring Boot中不起作用,spring-boot,java-8,aspectj,Spring Boot,Java 8,Aspectj,我正在尝试创建一个名为@ValidDate的自定义注释,以检查给定的日期对象是否不超过一周 这是注释定义 package com.verimi.kitchenservice.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotat

我正在尝试创建一个名为
@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行为定义类

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<>();
    ...
}
@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);
    }
}
如果它可以像上面那样工作,为什么不为
@annotation
工作呢

我还具有以下依赖关系:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-aop</artifactId>
        <version>2.4.3</version>
    </dependency>

org.springframework.boot
弹簧启动机aop
2.4.3

首先,您必须将验证启动程序添加到pom.xml中:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

org.springframework.boot
弹簧启动启动器验证
接下来,您必须创建自己的验证注释:

@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 {};
}
@已记录
@约束(validatedBy=DateValidator.class)
@目标({ElementType.PARAMETER})
@保留(RetentionPolicy.RUNTIME)
public@interface ValidDate{
String message()默认为“日期不是上周”;
类[]组()默认值{};

ClassI注意到您正在注释参数而不是方法,您是否可以尝试注释一个方法以查看它是否有效?我的印象是,这对于参数是不可能的,但不要引用this@dreamcrash瞧!当我将注释移动到方法级别时,它就工作了。但是为什么不能将它作为参数呢表示法?将其作为参数级别更为合理。我认为这只是AspectJ的一个限制。为什么不使用Bean验证来支持这一开箱即用的方法呢?非常感谢您的详细回答。感谢SO上的人的方法是将他们的答案标记为已接受。如果您的问题仍然没有解决,请在com中解释为了激励其他人回答这个问题。
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);
    }
}