I have this enum :
public enum SortEnum { asc, desc; }
That I want to use as a parameter of a rest request :
@RequestMapping(value = "/events", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public List<Event> getEvents(@RequestParam(name = "sort", required = false) SortEnum sort) {
It works fine when I send these requests
/events /events?sort=asc /events?sort=desc
But when I send :
/events?sort=somethingElse
I get a 500 response and this message in the console :
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 = <500 Internal Server Error,com.myApp.web.rest.errors.ErrorVM@1e3343c9,{}> 2016-09-29 17:20:51.601 WARN 5104 --- [ XNIO-2 task-6] .m.m.a.ExceptionHandlerExceptionResolver : 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
Is there a way to prevent spring from throwing these exceptions and set the enum to null ?
EDIT
The Strelok's accepted answer works. However, I decided to deal with handling the MethodArgumentTypeMismatchException.
@ControllerAdvice public class ExceptionTranslator { @ExceptionHandler(MethodArgumentTypeMismatchException.class) @ResponseBody public ResponseEntity<Object> 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); }
You can create a custom converter that will return null
instead of an exception when an invalid value is supplied.
Something like this:
@Configuration public class MyConfig extends WebMvcConfigurationSupport { @Override public FormattingConversionService mvcConversionService() { FormattingConversionService f = super.mvcConversionService(); f.addConverter(new MyCustomEnumConverter()); return f; } }
And a simple converter might look like this:
public class MyCustomEnumConverter implements Converter<String, SortEnum> { @Override public SortEnum convert(String source) { try { return SortEnum.valueOf(source); } catch(Exception e) { return null; // or SortEnum.asc } } }
If you are using Spring Boot, this is the reason that you should not use WebMvcConfigurationSupport
.
The best practice, you should implement interface org.springframework.core.convert.converter.Converter
, and with annotation @Component
. Then Spring Boot will auto load all Converter
's bean. Spring Boot code
@Component public class GenderEnumConverter implements Converter<String, GenderEnum> { @Override public GenderEnum convert(String value) { return GenderEnum.of(Integer.valueOf(value)); } }
Demo Project
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With