簡體   English   中英

我可以使用在 javax.validation.constraints.Max 中的 application.yml 中定義的自動裝配變量嗎?

[英]Can I use an autowired variable that's defined in application.yml in javax.validation.constraints.Max?

這是一個相當小眾的問題,但希望有人知道答案:

我有一個帶有 GetMapping 的 SpringFramework RestController,它使用 javax.validation 注釋進行了一些參數驗證。 我想使用 application.yml 中定義的屬性作為 url 參數的最大值,但我得到編譯器錯誤,即變量應該是常量。 見代碼:

@RestController
@Validated
public class AssetController {
  
    private final int maxWaitMillis;

    @Autowired
    public AssetController(@Value("${maxWaitMillis}") int maxWaitMillis) {
        this.maxWaitMillis = maxWaitMillis;
    }

    @GetMapping(value = "/asset", produces = MediaType.IMAGE_JPEG_VALUE)
    @ResponseBody
    public ResponseEntity<byte[]> getAsset(@RequestParam
                                           @NotBlank(message = "id should not be empty") String id,
                                           @RequestParam(defaultValue = "100", name = "timeout-ms")
                                           @Min(value = 0, message = "minimum timeout is 0 ms")
                                           @Max(value = maxWaitMillis, message = "max timeout is " + 

maxWaitMillis) int timeoutMs) {
... 
}

應用程序.yml:

maxWaitMillis: 5000

在 @Max(value = maxWaitMillis 它說 maxWaitMillis 應該是常量,因為我猜注釋中的檢查是在構造函數從 application.yml 獲取值之前完成的。

如果我在構造函數或方法主體中檢查maxWaitMillis的值,它的值確實為 5000。

有誰知道是否有辦法在驗證注釋中使用 application.yml 中的值?

謝謝!

創建一個自定義驗證器,如下所示

@Target({ElementType.PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = MaxWaitMillisValidator.class)
@Documented
public @interface MaxWaitMillis {
    String message() default "Invalid max wait";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class MaxWaitMillisValidator implements ConstraintValidator<MaxWaitMillis, Integer> {
    @Value("${maxWaitMillis}")
    private int maxWaitMillis;

    @Override
    public boolean isValid(Integer value, ConstraintValidatorContext context) {
        return value <= maxWaitMillis;
    }
}

然后,您可以在 controller 中使用 @MaxWaitMillis 代替 @Max。

annotationvalue必須是編譯時間常數,因此沒有簡單的方法可以做您想做的事情。

這是一個常量變量,一種常量表達式

private final int maxWaitMillis = 5000;

這不是:

private final int maxWaitMillis;

@Autowired
public AssetController(@Value("${maxWaitMillis}") int maxWaitMillis) {
    this.maxWaitMillis = maxWaitMillis;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM