Spring Boot — перечисление проверки

avatar
Peter Kronenberg
8 августа 2021 в 17:15
267
0
1

У меня есть перечисление, которое я проверяю следующим образом:

@EnumValueValidator(enumClass = MyEnum.class)
String value

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

public MyEnum getValue()
  return MyEnum.valueOf(value)

Проблема заключается в том, что если значение не является одним из допустимых типов перечисления, проверка не выдает надлежащего сообщения об ошибке, потому что она получает исключение, вызывающее геттер для недопустимого типа. Я не хочу, чтобы проверка использовала геттер. Он должен использовать поле напрямую. Getter() следует использовать только явными вызовами в бизнес-логике. Есть ли способ сделать это?

Источник
João Dias
9 августа 2021 в 00:17
0

Есть ли какая-либо причина, по которой вы действительно хотите проверить, что String соответствует допустимому значению для вашего MyEnum вместо того, чтобы использовать MyEnumнепосредственно как тип вашего атрибута value и разрешить его автоматическую проверку?

Peter Kronenberg
9 августа 2021 в 02:29
0

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

João Dias
9 августа 2021 в 16:43
0

Дело в том, что при этом, если у вас есть документация API (например, OpenAPI), вы не предоставляете необходимую информацию вызывающим сторонам вашего API о том, какие значения действительны для этого Enum, и, таким образом, они сами по себе. угадывая, какие из них являются действительными. Кроме того, @EnumValueValidator кажется настраиваемым валидатором, и без его реализации я не могу вам больше помочь.

Peter Kronenberg
9 августа 2021 в 17:34
0

Да, это настраиваемый валидатор, потому что встроенного нет. Много примеров в сети. Создание типа Enum не выполняет никакой проверки. Если пользователь вводит неверное значение, генерируется исключение. Как вы предлагаете на самом деле проверять перечисление, учитывая, что пользователь может передать любую произвольную строку, включая null? Документация Swagger определяет допустимые поля, но это не означает, что пользователь всегда будет им следовать.

João Dias
9 августа 2021 в 17:47
0

Да, создается исключение, и вы можете использовать такое исключение для создания сообщения вызывающей стороне (с глобальным обработчиком исключений) на основе его сообщения по умолчанию. И да, вы правы, пользователь не обязан всегда использовать допустимое значение, но, по крайней мере, пользователь знает о допустимых значениях с атрибутом String, о котором пользователь может только догадываться. В конце концов, это дизайнерское решение API, и я просто предлагал другие подходы. Ваша реализация похожа на ту, что описана в funofprograming.wordpress.com/2016/09/29/java-enum-validator?

Peter Kronenberg
9 августа 2021 в 18:00
0

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

João Dias
9 августа 2021 в 19:58
0

Если это так, то мне кажется, что значение вообще не проверяется, потому что я не могу найти никакого явного вызова getValue(). Но я мог бы что-то пропустить здесь.

Peter Kronenberg
9 августа 2021 в 20:33
0

Это не явно. Spring использует его с отражением

João Dias
9 августа 2021 в 22:47
0

Но зачем Spring это делать, если у вас есть String в качестве типа атрибута? И, изучив funofprograming.wordpress.com/2016/09/29/java-enum-validator, я также не могу найти причину. Либо вы предоставляете свою полную реализацию, либо вам будет трудно помочь.

Peter Kronenberg
10 августа 2021 в 02:14
0

Я не уверен, что вы полностью понимаете, как Springboot выполняет проверку и как он использует отражение для загрузки bean-компонентов.

João Dias
10 августа 2021 в 10:35
0

С таким небольшим контекстом кода в вашем вопросе я точно этого не понимаю.

Ответы (0)