Spring的@RequestParam与Enum

我有这个枚举:

public enum SortEnum { asc, desc; } 

我想用作rest请求的参数:

 @RequestMapping(value = "/events", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public List getEvents(@RequestParam(name = "sort", required = false) SortEnum sort) { 

我发送这些请求时工作正常

 /events /events?sort=asc /events?sort=desc 

但是当我发送时:

 /events?sort=somethingElse 

我在控制台中得到500响应和此消息:

 2016-09-29 17:20:51.600 DEBUG 5104 --- [ XNIO-2 task-6] com.myApp.aop.logging.LoggingAspect : Enter: com.myApp.web.rest.errors.ExceptionTranslator.processRuntimeException() with argument[s] = [org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type [java.lang.String] to required type [com.myApp.common.SortEnum]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam com.myApp.common.SortEnum] for value 'somethingElse'; nested exception is java.lang.IllegalArgumentException: No enum constant com.myApp.common.SortEnum.somethingElse] 2016-09-29 17:20:51.600 DEBUG 5104 --- [ XNIO-2 task-6] com.myApp.aop.logging.LoggingAspect : Exit: com.myApp.web.rest.errors.ExceptionTranslator.processRuntimeException() with result =  2016-09-29 17:20:51.601 WARN 5104 --- [ XNIO-2 task-6] .mmaExceptionHandlerExceptionResolver : Resolved exception caused by Handler execution: org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type [java.lang.String] to required type [com.myApp.common.SortEnum]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam com.myApp.common.SortEnum] for value 'somethingElse'; nested exception is java.lang.IllegalArgumentException: No enum constant com.myApp.common.SortEnum.somethingElse 

有没有办法防止spring抛出这些exception并将枚举设置为null?

编辑

Strelok接受的答案有效。 但是,我决定处理MethodArgumentTypeMismatchException。

 @ControllerAdvice public class ExceptionTranslator { @ExceptionHandler(MethodArgumentTypeMismatchException.class) @ResponseBody public ResponseEntity handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e) { Class type = e.getRequiredType(); String message; if(type.isEnum()){ message = "The parameter " + e.getName() + " must have a value among : " + StringUtils.join(type.getEnumConstants(), ", "); } else{ message = "The parameter " + e.getName() + " must be of type " + type.getTypeName(); } return buildResponse(HttpStatus.UNPROCESSABLE_ENTITY, message); } 

您可以创建一个自定义转换器,当提供无效值时,该转换器将返回null而不是exception。

像这样的东西:

 @Configuration public class MyConfig extends WebMvcConfigurationSupport { @Override public FormattingConversionService mvcConversionService() { FormattingConversionService f = super.mvcConversionService(); f.addConverter(new MyCustomEnumConverter()); return f; } } 

一个简单的转换器可能看起来像这样:

 public class MyCustomEnumConverter implements Converter { @Override public SortEnum convert(String source) { try { return SortEnum.valueOf(source); } catch(Exception e) { return null; // or SortEnum.asc } } } 

你需要做以下事情

 @InitBinder public void initBinder(WebDataBinder dataBinder) { dataBinder.registerCustomEditor(YourEnum.class, new YourEnumConverter()); } 

请参阅以下内容: https : //machiel.me/post/java-enums-as-request-parameters-in-spring-4/

到目前为止提供的答案并不完整。 以下是一个循序渐进的答案示例,对我有用: –

1st在端点签名中定义枚举(订阅类型)。
示例

 public ResponseEntity v1_getSubscriptions(@PathVariable String agencyCode, @RequestParam(value = "uwcompany", required = false) String uwCompany, @RequestParam(value = "subscriptiontype", required = false) SubscriptionType subscriptionType, @RequestParam(value = "alert", required = false) String alert, 

第2步定义将用于从String转换为枚举的自定义属性编辑器:

 import java.beans.PropertyEditorSupport; public class SubscriptionTypeEditor extends PropertyEditorSupport { public void setAsText(String text) { try { setValue(SubscriptionType.valueOf(text.toUpperCase())); } catch (Exception ex) { setValue(null); } } } 

3向控制器注册属性编辑器:

 @InitBinder ("subscriptiontype") public void initBinder(WebDataBinder dataBinder) { dataBinder.registerCustomEditor(SubscriptionType.class, new SubscriptionTypeEditor()); } 

从字符串到枚举的翻译现在应该完美地发生。