Search code examples
javaspringspring-bootenums

Can an enum constant be specified in both upper and lower case in a Spring endpoint?


One of my Springboot controller's endpoints is defined as:

    @GetMapping(path = "/{custId}/items", produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    @AuthorizationValidationStrategy
    public List<ItemDTO> getCustItemsByItemType(@PathVariable @SecureResource(CUST) Long custId, @RequestParam("itemType") List<ItemType> itemTypes) {
        return this.myFeignClient.findItemsByCustIdAndItemTypes(custId, itemTypes);
    }

where ItemType is an enum that follows our department's coding conventions such that all enum constants ("enum instances") are to be named ALL_UPPER_CASE.

This endpoint works well when the query specifies item type in UPPER CASE.

If the item type is specified in lower case, then Spring throws an exception right off the bat, without any chance to uppercase it before handing it over to the Feign client. That's expected and I understand why.

Is there a way to make such an endpoint "flexible" in the sense that it can accept both lowercase and uppercase enum constants equally?

For example:

  http://127.0.0.1:8080/1.0/custs/2/items?itemType=bread
  http://127.0.0.1:8080/1.0/custs/2/items?itemType=BREAD

I actually implemented this enum with the well known @JsonCreator technique whereas its comparison is case insensitive, but the HTTP request never gets to this stage.


Solution

  • In Java, it’s considered good practice to define enum values with uppercase letters, as they are constants. However, we may want to support lowercase letters in the request URL.

    In this case, we need to create a custom converter:

    public class StringToEnumConverter implements Converter<String, Modes> {
        @Override
        public Modes convert(String source) {
            return Modes.valueOf(source.toUpperCase());
        }
    }

    Modes is my enum. you can replace with your enum here.

    To use our custom converter, we need to register it in the Spring configuration:

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addFormatters(FormatterRegistry registry) {
            registry.addConverter(new StringToEnumConverter());
        }
    }