微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

如何解决AspectJ 自定义参数注释在 Spring Boot 中不起作用

我正在尝试创建一个名为 @ValidDate自定义注释,以检查给定的 Date 对象是否不超过一周。

这是注解定义。

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<>();
    ...
}

我的 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);
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。