我正在開發這個 springboot 應用程式,我需要對從 http 呼叫傳遞的值進行一些驗證,并且我正在使用類級別驗證,如此處所述。
我正在使用這樣的想法:
@ValidRequest
public class EventRequest {
String date;
}
Response create(@Valid EventRequest request) {
..
}
Response update(Long entityId, @Valid EventRequest request) {
...
}
public class ValidRequestValidator
implements ConstraintValidator<ValidRequest, EventRequest> {
在我實作 ConstraintValidator 介面的 ValidRequestValidator 類中,我需要檢查資料庫中是否有另一個 Event 物體滿足欄位日期的某些條件。當我想創建一個新物體很簡單時,我會執行一個查詢,但是當我需要更新時,我需要排除我當前正在嘗試更新的物體。
有沒有辦法將 entityId 引數傳遞給 @ValidRequest 自定義驗證器?我知道一種方法是將欄位 entityId 添加到 EventRequest 類中,但我想保持這種分離,因為 entityId 來自查詢引數。
感謝您的幫助!
uj5u.com熱心網友回復:
除了 field-specific( Single Parameter Constraint) 之外,您還可以對整個方法 ( Cross-Parameter Constraint) 實施約束。這將提供將某個方法的所有引數傳遞給驗證器的能力。
Annotation 定義:
Annotation 使用了兩個驗證器,可以應用于 Method 或 Type。
@Constraint(validatedBy = {ValidRequestMethodValidator.class, ValidRequestTypeValidator.class})
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface ValidRequest {
String message() default "Request is invalid!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
ConstraintTarget validationAppliesTo() default ConstraintTarget.IMPLICIT;
}
將處理單個引數的約束驗證器:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
public class ValidRequestTypeValidator implements ConstraintValidator<ValidRequest, EventRequest> {
@Override
public boolean isValid(EventRequest request, ConstraintValidatorContext constraintValidatorContext) {
// logic here
return false;
}
}
約束驗證器,它將處理特定方法的所有引數:
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.constraintvalidation.SupportedValidationTarget;
import javax.validation.constraintvalidation.ValidationTarget;
@SupportedValidationTarget(ValidationTarget.PARAMETERS)
public class ValidRequestMethodValidator implements ConstraintValidator<ValidRequest, Object[]> {
@Override
public boolean isValid(Object[] objects, ConstraintValidatorContext constraintValidatorContext) {
Long entityId = null;
EventRequest eventRequest = null;
if (objects[0] instanceof Long) {
entityId = (Long) objects[0];
}
if (objects[0] instanceof EventRequest) {
eventRequest = (EventRequest) objects[0];
}
if (objects[1] instanceof EventRequest) {
eventRequest = (EventRequest) objects[1];
}
//logic here
return false;
}
}
請注意,我們必須對要驗證的 bean 進行注釋,并使用@org.springframework.validation.annotation.Validated注釋使方法驗證器自動作業。
使用示例:
- 混合使用,
@ValidRequest在方法和單個引數級別上定義的注釋。
@ValidRequest
public class EventRequest {
public String value;
}
@RestController
@Validated
public class Controller {
Response create(@Valid EventRequest request) {
return new Response();
}
@ValidRequest(validationAppliesTo = ConstraintTarget.PARAMETERS)
Response update(Long entityId, EventRequest request) {
return new Response();
}
}
Forcreate方法ValidRequestTypeValidator將被執行。
Forupdate方法ValidRequestMethodValidator 將被執行。
2. 只為方法定義注解
@RestController
@Validated
public class Controller {
@ValidRequest(validationAppliesTo = ConstraintTarget.PARAMETERS)
Response create(EventRequest request) {
return new Response();
}
@ValidRequest(validationAppliesTo = ConstraintTarget.PARAMETERS)
Response update(Long entityId, EventRequest request) {
return new Response();
}
}
Forcreate方法ValidRequestMethodValidator 將使用一個元素物件陣列
執行
Forupdate方法ValidRequestMethodValidator 將使用兩個元素物件陣列執行
3.同時為單個引數和方法定義注解
@ValidRequest
public class EventRequest {
public String value;
}
@RestController
@Validated
public class Controller {
@ValidRequest(validationAppliesTo = ConstraintTarget.PARAMETERS)
Response update(Long entityId, @Valid EventRequest request) {
return new Response();
}
}
首先將執行單引數驗證器ValidRequestTypeValidator。
如果它將通過驗證,則將ValidRequestMethodValidator執行第二種方法驗證器。
可能只有一種方法級別的驗證足以處理您的問題。我描述了所有變體,僅供參考,可能會有用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/475599.html
