Spring's @RequestParam with Enum

|▌冷眼眸甩不掉的悲伤 提交于 2019-11-27 17:58:05
Strelok

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
       }
    }
}

you need to do the following

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

refer the following : https://machiel.me/post/java-enums-as-request-parameters-in-spring-4/

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

user3862533

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:

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,

2nd Define a custom property editor that will be used to translate from String to enum:

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);
        }
    }
}

3rd Register the property editor with the controller:

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

Translations from string to enum should happen perfectly now.

you can use String instead of SortEnum param

@RequestParam(name = "sort", required = false) String sort

and convert it using

SortEnum se;
try {
   se = SortEnum.valueOf(source);
} catch(IllegalArgumentException e) {
   se = null;
}

inside of getEvents(...) endpoint method losing elegance but gaining more control over conversion and possible error handling.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!