I have a spring boot controller, one of my parameters is an Enum. The enum has a string value. I want to pass as the parameter the value of the enum and the controller to give me the Enum. Can this be done?
@RequestMapping(value = "/")
public MyResponse getResponse ( @RequestParam(value = "version") final ProjectVersion version ) {
...bla bla bla...
}
public enum ProjectVersion {
VERSION_1 ("1.00")
VERSION_2 ("2.00")
private final String version;
ProjectVersion ( String version ) {
this.version = version;
}
@Override
public String toString() {
return this.version;
}
}
I want to be able to make a request as follows:
http://myhost.com/mypath?version=1.00
And get in the controller the ProjectVersion.VERSION_1
Any ideas?
Use Enums as Request Parameters mode=ALPHA, the request parameter is a String object. Spring can try to convert this String object to an Enum object by using its StringToEnumConverterFactory class. The back-end conversion uses the Enum. valueOf method.
An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it.
Yes, you can pass enum constants to methods, but you shouldn't use the 'enum' keyword in the method declaration, just like you don't use the 'class' keyword in a method declaration.
You can assign different values to enum member. A change in the default value of an enum member will automatically assign incremental values to the other members sequentially.
This is not possible as is. You have to create your custom converter to convert from a String
to ProjectVersion
.
For example first defines the converter from a String
to ProjectVersion
:
public class ProjectVersionConverter implements ConditionalGenericConverter {
@Override
public boolean matches(TypeDescriptor sourceType, TypeDescriptor targetType) {
return targetType.getType().equals(ProjectVersion.class);
}
@Override
public Set<ConvertiblePair> getConvertibleTypes() {
return Collections.singleton(new ConvertiblePair(String.class , ProjectVersion.class));
}
@Override
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
return ProjectVersion.findByVersion((String)source);
}
}
Then register it:
@Configuration
public class CustomWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new ProjectVersionConverter());
}
}
You can skip the registration if you define ProjectVersionConverter
as a Spring bean. (This code has not be tested).
Because you need to pass (for each request) the argument to the Controller
method, the clean solution would be to use HandlerMethodArgumentResolver, so that
Spring container can dynamically inject your ProjectVersion argument to the Controller method as shown below:
ProjectVersionArgumentResolver
class:
public class ProjectVersionArgumentResolver implements
HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(ProjectVersion.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter,
ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest,
WebDataBinderFactory webDataBinderFactory) throws Exception {
return ProjectVersion.fromString(nativeWebRequest.getParameter("version"));
}
}
Spring-boot ApplicationLauncher class:
public class MyProjectApplicationLauncher extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver>
argumentResolvers) {
//add the new resolver
argumentResolvers.add(new MyMethodArgumentResolver());
}
public static void main(String[] args) {
SpringApplication.run(MyProjectApplicationLauncher.class, args);
}
}
ProjectVersion
class:
public enum ProjectVersion {
//add your existing code
//Add fromString method to convert string to enum
public static ProjectVersion fromString(String input) {
for (ProjectVersion projectVersion : ProjectVersion.values()) {
if (projectVersion.version.equals(input)) {
return projectVersion;
}
}
return null;
}
}
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