Проверка Enum с ошибками проверки Springframework - PullRequest
0 голосов
/ 28 ноября 2018

TL; DR: ошибки десериализации перечисления не регистрируются org.springframework.validation.Errors в контроллере покоя

Для справки: мы еще не нашли чистого решения, так какнаконец решил, что никто не должен называть нас безумным перечислением


У меня есть контроллер покоя, который использует org.springframework.validation.Errors для проверки параметров:

@RequestMapping(value = "/vol1/frodo")
public ResponseEntity<Object> simpleMethodUsingPost(
        HttpServletRequest httpServletRequest,
        @Valid @RequestBody MySimpleObject simpleObject,
        Errors errors) {

    /* If an error occured, I need to log the object */
    if (errors.hasErrors()) {
        List<FieldError> fields = errors.getFieldErrors();
        doSomething(fields , simpleObject);
    }
}

Мой класс MySimpleObject выглядит так:

public class MySimpleObject {
    @Valid
    @NotNull(message = "anObjectField is a mandatory field")
    private EmbeddedObject anObjectField = null;

    @Valid
    @NotNull(message = "aStringField is a mandatory field")
    private String aStringField = null;

    @Valid
    private MySimpleEnum aSimpleEnum = null;
}

И мой перечислимый класс MySimpleEnum в основном представляет собой класс с двумя значениями:

public enum MySimpleEnum{

  ORC("ORC"),
  URUK("URUK");

  private String value;

  MySimpleEnum(String value) {
    this.value = value;
  }

  @Override
  public String toString() {
    return String.valueOf(value);
  }
}

Проверка этого объекта (и внедрение ошибокв Springframework Error объект) хорошо работает, когда он находится на String или Object, но он не пройдет валидацию enum (следовательно, объект, содержащий перечисление с допустимым аннотированием, тоже потерпит неудачу).

Сбой при попытке привести JSON String к перечислению, когда значение недопустимо:

org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: 
Cannot deserialize value of type 'lotr.middleearth.model.MySimpleEnum' from String "HOBBIT"

Эта ошибка десериализации обнаруживается, если я использую ResponseEntityExceptionHandler и переопределяю handleHttpMessageNotReadable но у меня нет доступа к другим параметрам и я не могу использоватьих.

Как настроить Validator , enum или Springframe Error , чтобы это исключение было перехвачено и использовано в моем теле контроллера

Ответы [ 3 ]

0 голосов
/ 08 февраля 2019

В итоге я сделал что-то подобное для извлечения проблемного поля в запросе:

int start = ex.getMessage().indexOf("[\"");
int end = ex.getMessage().indexOf("\"]");
String fieldName = exception.getMessage().substring(start + 2, end)

Поле находится в конце сообщения в скобках.

IЯ не очень горжусь этим, это грязно, но, кажется, это единственный способ с перечислениями.

Полагаю, что было бы лучше использовать строки и правильную проверку Spring, поскольку это слишком сильно зависит от реализации и может порвать с будущими обновлениями.

0 голосов
/ 12 июня 2019

Я только что столкнулся с той же проблемой, но мне не понравилась идея дать пользователю неформатированное «некрасивое» сообщение об ошибке проверки.

Во-первых, я сделал свойство enum недопустимым в pojo.

@NotNull(message = "Type must be NEW_APPLICATION or RENEWAL")
private RegistrationSubmissionTypeEnum type;

Затем я изменил установщик, чтобы в основном проверить ввод (как строку) и посмотреть, соответствует ли он одному изперечисления.Если нет, я ничего не делаю, свойство остается пустым, и оно возвращается как одно из сообщений об ошибках проверки (используя текст сообщения, используемый в аннотации @NotNull).

public void setType(Object typeInput) {
    for (RegistrationSubmissionTypeEnum typeEnum : RegistrationSubmissionTypeEnum.values()) {
        if (typeEnum.getKey().equalsIgnoreCase(typeInput.toString())) {
            this.type=RegistrationSubmissionTypeEnum.valueOf(typeInput.toString());
        }
    }
}

Это действительно ключ.Нормальное поведение, которое мы все презираем, генерирует ужасное сообщение об ошибке, но оно также делает это таким образом, чтобы это сообщение об ошибке отображалось отдельно.Лично мне нравится массово отправлять обратно все ошибки.

Я не фанат жесткого кодирования значений перечисления в сообщении @NotNull, но в данном конкретном случае (небольшое количество значений перечисления) предпочтительнее сообщения об ошибке сериализации перечисления по умолчанию и поведенияодноразовое изолированное сообщение об ошибке.

Я рассматривал пользовательский валидатор, но это начинало казаться тяжелым.Может быть, кто-то может улучшить это.

0 голосов
/ 29 ноября 2018

Проблема заключается в том, что в enum MySimpleEnum нет константы "HOBBIT", возможны "ORC" и "URUK", в вопросе проверки можно использовать просто, как в примере:

@NotNull(message = "Custom message")
private MySimpleEnum aSimpleEnum
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...