У меня есть конечная точка Spring Boot, у которой есть enum как параметр запроса:
@GetMapping("/example")
public List<Example> getByEnum(@RequestParam(name = "exampleEnum", required = false) ExampleEnum exampleEnum) {
// code
}
И класс перечисления:
public enum ExampleEnum {
FIRST,
SECOND,
}
Если я передаю значение перечисления в верхнем регистре в конечную точку, оно хорошо десериализуется, но выдает ошибку для нижнего регистра:
java.lang.IllegalArgumentException: No enum constant
Как десериализовать перечисление, игнорируя регистр в конечной точке Spring Boot Rest?
Этот вопрос не повторяется, потому что он связан с десериализацией параметров запроса.
ВЗДОХ - оба ответа неверны, и я не могу дать правильный ответ, так как вопрос был закрыт как дубликат людьми, которые не знают, о чем они говорят.
@Dave Я изменил вопрос. Не могли бы вы повторно открыть под вопросом?
@Dave, пожалуйста, опубликуйте ответ




Обновлено: Ответ ниже неверен. Вы должны определить собственный PropertyEditor и зарегистрировать его в Spring @InitBinder, который я объяснил в этом посте. Спасибо @Dave за указание на это в комментариях.
Spring Boot 2.0 использует Jackson 2.9 с функцией ACCEPT_CASE_INSENSITIVE_ENUMS. Вы должны иметь возможность включить его, установив
spring.jackson.mapper.ACCEPT_CASE_INSENSITIVE_ENUMS = true
собственность согласно документы, Приложение A.
Добавлено свойство и objectMapper.enable (MapperFeature.ACCEPT_CASE_INSENSITIVE_EN UMS); но все же получить java.lang.IllegalArgumentException: нет константы перечисления
Скорее всего, настраиваемый вами objectMapper не тот, который используется веб-слоем. Используйте свойства Spring Boot, как в моем примере, а затем проверьте. См. Класс Jackson2ObjectMapperBuilder.
Я использовал как свойство загрузки: spring, так и включенное в пользовательском картографе объектов. Настраиваемая конфигурация ObjectMapper помечена как \ @Bean \ @Primary, поэтому она должна работать для всех слоев.
Джексон даже не заглянул сюда, потому что мы не десериализуем тело сообщения - Spring MVC вместо этого является параметром запроса преобразование. Для этой цели Spring использует зарегистрированные PropertyEditors DataBinder или, в противном случае, соответствующий TypeConverter из веб-службы ConversionService. Чтобы решить эту проблему, вы должны расширить PropertyEditorSupport и добавить аннотированный метод @InitBinder, который регистрирует его на вашем контроллере.
import com.fasterxml.jackson.annotation.JsonCreator;
import java.util.Arrays;
import java.util.Optional;
public enum ExampleEnum {
FIRST,
SECOND;
@JsonCreator
public static ExampleEnum setValue(String key) {
return Arrays.stream(ExampleEnum.values())
.filter(exampleEnum -> exampleEnum.toString().equals(key.toUpperCase()))
.findAny()
.orElse(null);
}
Все еще используете такие опции, да? должно было быть необязательным. orElse (null). См. Доклад Стюарта Марка youtube.com/watch?v=Ej0sss6cq14
затем используйте orElse (null) вместо if else
Вы можете сделать общий конвертер для всех перечислений
package ru.grancall.kb.logging.service.dto.converter;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.EnumUtils;
import java.beans.PropertyEditorSupport;
@AllArgsConstructor
public class EnumConverter extends PropertyEditorSupport {
private Class type;
public void setAsText(String text) {
setValue(EnumUtils.getEnum(type, text.toUpperCase()));
}
}
А затем в любом из ваших контроллеров используйте его:
@InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(YourEnum.class, new EnumConverter(YourEnum.class));
}
Не дубликат, поскольку вопрос относится конкретно к параметрам строки запроса, которые обрабатываются иначе, чем атрибуты тела сообщения.