簡體   English   中英

使用Spring ConstraintValidator進行枚舉的javax.validation.UnexpectedTypeException

[英]javax.validation.UnexpectedTypeException using Spring ConstraintValidator for an enumeration

為了驗證包含枚舉的DTO,我實現了ConstraintValidator。 我遵循了這個Spring文檔

這是將應用於枚舉字段的自定義注釋:

@Target({ElementType.METHOD, ElementType.FIELD, ElementType.CONSTRUCTOR,
    ElementType.ANNOTATION_TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EnumValidator.class)
public @interface ValidEnum {

  String message() default "{com.test.validation.constraints.ValidEnum}";

  Class<?>[] groups() default {};

  Class<? extends Payload>[] payload() default {};

  Class<? extends Enum<?>> target();

}

EnumValidator看起來像這樣:

public class EnumValidator implements ConstraintValidator<ValidEnum,String> {

      private Set<String> enumValues;

      @Override
      public void initialize(ValidEnum targetEnum) {
          Class<? extends Enum> enumSelected = targetEnum.targetClassType();
          enumValues = (Set<String>) EnumSet.allOf(enumSelected).stream()
              .map(e -> ((Enum<? extends Enum<?>>) e).name()).collect(Collectors
                  .toSet());
      }

      @Override
      public boolean isValid(String value, ConstraintValidatorContext context) {
          return enumValues.contains(value);
      }
  }

這是枚舉:

public enum Gender {
  MALE,FEMALE;
}

這是要驗證的DTO:

public final class UserDTO{

  @ValidEnum(target = Gender.class)
  private Gender gender;

  @NotEmpty
  @Max(100)
  private String fullName;
}

以及正在驗證該字段的控制器:

@Controller
public class RegistrationController {

  private static final String REGISTER_USER = "/register";

  private final RegistrationService registrationService;


  @PostMapping(value = REGISTER_USER)
  @Consumes(APPLICATION_JSON)
  @Produces(APPLICATION_JSON)
  public UserRegistrationResponse register(@Valid UserDTO userRegistrationRequest) {

    return registrationService.register(userRegistrationRequest);
  }

}

看來Spring沒有檢測到驗證器,因為它拋出了這個異常:

org.springframework.web.util.NestedServletException: Request processing failed; 
nested exception is javax.validation.UnexpectedTypeException: HV000030: 

No validator could be found for constraint 'com.test.ws.web.validation.ValidEnumType' validating type 'com.test.ws.domain.model.Gender'. Check configuration for 'gender'

我正在使用Spring Boot 2.0.4,其中包括驗證所需的依賴項。

知道為什么它會失敗嗎?

您的代碼中有三個錯誤。

  1. @Max(100)此注釋不應應用於字符串字段! 僅適用於數字類型。 如果需要指定字符串大小范圍限制,則可以使用@Size(min = 2, max = 250)注釋。
  2. 您在控制器方法簽名中忘記了RequestBody批注:

register(@Valid @RequestBody UserDTO userRegistrationRequest)

  1. 枚舉驗證使用來自Rest API的字符串值,而不是枚舉本身。 這就是為什么您在這里出錯。

我已經為您創建了測試項目。 請在這里檢查它https://github.com/alex-petrov81/stackoverflow-answers/tree/master/enum-validator

暫無
暫無

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

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