Перейти к основному содержимому

Использование Enums в качестве параметров запроса в Spring

· 3 мин. чтения

1. Введение

В большинстве типичных веб-приложений нам часто нужно ограничить параметр запроса набором предопределенных значений. Перечисления — отличный способ сделать это.

В этом кратком руководстве мы покажем, как использовать перечисления в качестве параметров веб-запроса в Spring MVC.

2. Используйте перечисления в качестве параметров запроса

Давайте сначала определим перечисление для наших примеров:

public enum Modes {
ALPHA, BETA;
}

Затем мы можем использовать это перечисление как RequestParameter в контроллере Spring:

@GetMapping("/mode2str")
public String getStringToMode(@RequestParam("mode") Modes mode) {
// ...
}

Или мы можем использовать его как PathVariable :

@GetMapping("/findbymode/{mode}")
public String findByEnum(@PathVariable("mode") Modes mode) {
// ...
}

Когда мы делаем веб-запрос, такой как /mode2str?mode=ALPHA , параметр запроса представляет собой объект String . Spring может попытаться преобразовать этот объект String в объект Enum , используя его класс StringToEnumConverterFactory .

Во внутреннем преобразовании используется метод Enum.valueOf . Следовательно, входная строка имени должна точно совпадать с одним из объявленных значений перечисления .

Когда мы делаем веб-запрос со строковым значением, которое не соответствует одному из наших значений перечисления , например, /mode2str?mode=unknown, Spring не сможет преобразовать его в указанный тип перечисления. В этом случае мы получим ConversionFailedException .

3. Пользовательский конвертер

В Java считается хорошей практикой определять значения перечисления заглавными буквами, поскольку они являются константами. Однако мы можем захотеть поддерживать строчные буквы в URL-адресе запроса.

В этом случае нам нужно создать собственный конвертер:

public class StringToEnumConverter implements Converter<String, Modes> {
@Override
public Modes convert(String source) {
return Modes.valueOf(source.toUpperCase());
}
}

Чтобы использовать наш пользовательский конвертер, нам нужно зарегистрировать его в конфигурации Spring :

@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToEnumConverter());
}
}

4. Обработка исключений

Метод Enum.valueOf в StringToEnumConverter вызовет исключение IllegalArgumentException , если наше перечисление Modes не имеет совпадающей константы. Мы можем обрабатывать это исключение в нашем пользовательском конвертере по-разному, в зависимости от требований.

Например, мы можем просто заставить наш преобразователь возвращать null для несовпадающих String s:

public class StringToEnumConverter implements Converter<String, Modes> {
@Override
public Modes convert(String source) {
try {
return Modes.valueOf(source.toUpperCase());
} catch (IllegalArgumentException e) {
return null;
}
}
}

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

Например, мы можем использовать глобальный класс обработчика исключений:

@ControllerAdvice
public class GlobalControllerExceptionHandler {
@ExceptionHandler(ConversionFailedException.class)
public ResponseEntity<String> handleConflict(RuntimeException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}

5. Вывод

В этой статье мы показали, как использовать перечисления в качестве параметров запроса в Spring с некоторыми примерами кода.

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

Наконец, мы обсудили, как обрабатывать исключение, выдаваемое Spring при обнаружении неизвестной входной строки.

Как всегда, исходный код руководства доступен на GitHub .