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 use
String
instead ofSortEnum
paramand convert it using
inside of getEvents(...) endpoint method losing elegance but gaining more control over conversion and possible error handling.
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 allConverter
's bean. Spring Boot codeDemo Project
You can create a custom converter that will return
null
instead of an exception when an invalid value is supplied.Something like this:
And a simple converter might look like this:
you need to do the following
refer the following : https://machiel.me/post/java-enums-as-request-parameters-in-spring-4/
The answers provided so far are not complete. Here is an answer example step-by-step that worked for me:-
1st Define the enum in your endpoint signature(subscription type).
Example:
2nd Define a custom property editor that will be used to translate from String to enum:
3rd Register the property editor with the controller:
Translations from string to enum should happen perfectly now.
If you are already implementing WebMvcConfigurer, instead of WebMvcConfigurationSupport, you can add new converter by implementing the method addFormatters