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