[英]Provide some value to @Valid annotation and using that value change validation in isValid() method
我在我的項目中使用兩個數據庫,並在驗證請求正文中提供的過濾器時,對於某些請求,我需要來自 db1 的驗證,而對於某些請求,我需要來自 db2 的驗證。 我在一個枚舉中映射了值及其對應的類型。 但是我如何確定必須為請求正文中提供的特定過濾器使用哪個映射。
下面是我的 controller 演示:
@PostMapping(path = "/v1/abc")
public PageableDto getAll{Something}(
@RequestAttribute UserClaim userClaim,
@Valid SearchParametersDto searchParametersDto,
@RequestBody @Valid List<FilterDto> filters)
這需要使用 DB1 進行驗證。
@PostMapping(path = "/v1/xyz")
public PageableDto getAll{Something}(
@RequestAttribute UserClaim userClaim,
@Valid SearchParametersDto searchParametersDto,
@RequestBody @Valid List<FilterDto> filters)
這需要使用 DB2 進行驗證。
在 FilterDto class 中,我創建了注釋。
@Getter
@Setter
@FilterValidatorBehaviour
public class FilterDto {
String name;
String operation;
String value;
@JsonIgnore
public DataBaseTypeObject getObjectWithFieldName(MappingEnum mapping) {
//return get map with enum name map
return mapping.getMappingMap().get(name);
}
}
在注釋實現 class。 我已經覆蓋了 isValid 方法,如下所示。
@Override
public boolean isValid(FilterDto filterDto, ConstraintValidatorContext ctx) {
return filterDto.getValue().getClass().equals(
filterDto.getObjectWithFieldName(MappingEnum.DB1_MAPPING).getType());
}
下面是 MappingEnum class:
@RequiredArgsConstructor
@Getter
public enum MappingEnum {
DB1_MAPPING(Map.ofEntries(
Map.entry("field1",new DB1Object("field1", String.class)),
Map.entry("field2",new DB1Object("field2", String.class)),
Map.entry("field3",new DB1Object("field3", String.class)),
)),
DB2_MAPPING(Map.ofEntries(
Map.entry("field1",new DB2Object("field1", String.class)),
Map.entry("field2",new DB2Object("field2", String.class)),
Map.entry("field3",new DB2Object("field3", String.class)),
)),
private final Map<String, ? extends DataBaseTypeObject> mappingMap;
這里 DB1Object 和 DB2Object 是 DataBaseTypeObject 的子類。
在解決方案方向上的任何幫助都會有很大幫助?
一種可能的解決方案是將@FilterValidatorBehaviour
注釋從FilterDto
移動到 controller 本身。 缺點是因為您傳遞了一個列表,所以您必須重構驗證器以接受List<FilterDto>
而不僅僅是一個FilterDto
。
好處是您可以將自定義屬性添加到@FilterValidatorBehaviour
注釋。 例如,您可以創建一個包含MappingEnum
的屬性:
@Documented
@Retention(RUNTIME)
@Target({PARAMETER}) // Make sure to set PARAMETER
@Constraint(validatedBy = FilterValidatorBehaviourValidator.class)
public @interface FilterValidatorBehaviour {
MappingEnum value(); // Add this
String message() default "{filterValidatorBehaviour}";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
要讀取此value
屬性,您可以在ConstraintValidator
中實現initialize()
方法並將其設置為字段:
@Override
public void initialize(FilterValidatorBehaviour constraintAnnotation) {
this.mappingEnum = constraintAnnotation.value(); // Read mappingEnum from annotation
}
現在您可以在isValid()
方法中使用this.mappingEnum
。 確保不要忘記您必須將驗證器從ConstraintValidator<FilterValidatorBehaviour, FilterDto>
重構為ConstraintValidator<FilterValidatorBehaviour, List<FilterDto>>
。
之后,您可以在 controller 中使用@FilterValidatorBehaviour(MappingEnum.DB1_MAPPING)
或@FilterValidatorBehaviour(MappingEnum.DB2_MAPPING)
。 例如:
@PostMapping(path = "/v1/abc")
public PageableDto getAll{Something}(
@RequestAttribute UserClaim userClaim,
@Valid SearchParametersDto searchParametersDto,
// Add the @FilterValidatorBehaviour annotation
@RequestBody @Valid @FilterValidatorBehaviour(MappingEnum.DB1_MAPPING) List<FilterDto> filters) {
// TODO: implement
return null;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.