1. 簡介
在大多數典型 Web 應用程序中,我們經常需要將請求參數限制為一組預定義的選項。枚舉(Enum)是實現這一目標的一種有效方法。
在本快速教程中,我們將演示如何在 Spring MVC 中使用枚舉作為 Web 請求參數。
2. 使用枚舉作為請求參數
首先,讓我們為我們的示例定義一個枚舉:
public enum Modes {
ALPHA, BETA;
}
我們可以使用這個枚舉作為 Spring 控制器中的 RequestParameter:
@GetMapping("/mode2str")
public String getStringToMode(@RequestParam("mode") Modes mode) {
// ...
}
我們也可以將其用作 PathVariable:
@GetMapping("/findbymode/{mode}")
public String findByEnum(@PathVariable("mode") Modes mode) {
// ...
}
當我們發起一個 Web 請求,例如 /mode2str?mode=ALPHA,請求參數是一個 String 對象。Spring 可以嘗試使用其 StringToEnumConverterFactory 類將其轉換為一個 Enum 對象。
後端轉換使用 Enum.valueOf 方法。因此,輸入名稱字符串必須與已聲明的枚舉值完全匹配。
當我們使用與我們枚舉值不匹配的字符串值發起 Web 請求時,例如 /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 中如果我們的 Modes 枚舉中沒有匹配的常量,將會拋出 IllegalArgumentException。我們可以根據我們的需求,在自定義轉換器中以不同的方式處理此異常。
例如,我們可以簡單地讓轉換器對於不匹配的 String 返回 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 異常。 可以通過多種方式處理該異常。
例如,我們可以使用全局異常處理類:
@ControllerAdvice
public class GlobalControllerExceptionHandler {
@ExceptionHandler(ConversionFailedException.class)
public ResponseEntity<String> handleConflict(RuntimeException ex) {
return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);
}
}5. 結論
在本文中,我們學習瞭如何使用枚舉作為請求參數在 Spring 中,並提供了相應的代碼示例。
我們還提供了自定義轉換器示例,該示例可以將輸入字符串映射到枚舉常量。
最後,我們討論了當 Spring 遇到未知輸入字符串時,如何處理拋出的異常。