原文:https://www.lvcc.top/article-detail/1281756787720060930
介绍
在大多数典型的web应用程序中,我们通常需要将请求参数限制为一组预定义的值,使用枚举是一种很好的方法。
在本快速教程中,我们将展示如何在Spring MVC中使用枚举作为web请求参数。
使用枚举作为请求参数
定义一个枚举
public enum Modes {
ALPHA, BETA;
}
在spring controller中使用枚举作为请求参数
@GetMapping("/mode2str")
public String getStringToMode(@RequestParam("mode") Modes mode) {
// ...
}
也可以在路径参数中使用枚举
@GetMapping("/findbymode/{mode}")
public String findByEnum(@PathVariable("mode") Modes mode) {
// ...
}
当我们发起一个web请求, 比如 /mode2str?mode=ALPHA , 请求参数是一个String。 Spring 会自动将String转换为对应的枚举对象,实现这一功能的类是StringToEnumConverterFactory。
背后的转换功能使用的是Enum.valueOf方法,因此,请求参数必须完全和枚举名称一致。
当请求参数与枚举名称不一样时,比如 /mode2str?mode=unknown, 这时转换就会失败, 并获得一个ConversionFailedException。
自定义转换器
在java中,通常把枚举定义为大写字母比较好,因为它们是常量, 但是在请求中,我们通常使用小写字母,这种情况下,需要使用一个自定义转换器。
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());
}
}
异常处理
StringToEnumConverter中的Enum.valueOf方法在出错时会抛出IllegalArgumentException异常,我们可以捕获然后自定义处理,根据实际需求。例如,我们在转换失败时返回一个null:
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异常到Controller层, 这里也有许多办法处理这个异常,比如定义一个全局的异常处理类:
@ControllerAdvice
public class GlobalControllerExceptionHandler {
@ExceptionHandler(ConversionFailedException.class)
public ResponseEntity<String> handleConflict(RuntimeException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}