I would like to send http requests with a lowercase value where in the path variable, the value is taken from an Enum with uppercase values.
On a very simple code:
@HttpExchange(accept = "application/json")
public interface FooHttpExchange {
@GetExchange("/api/1.1/{day}/dosomething")
String doSomethingWithDayOfWeek(@PathVariable("day") Day day);
with the Enum:
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
As you can see, all values of the enum are uppercase, to respect Java conventions on enumeration.
But also, I do get the Enums from third-party libraries as well. I cannot change the content of the Enum.
I would expect to send this as a request (taking Monday as an example):
http://example.com/api/1.1/monday/dosomething
Unfortunately, it is sending this instead:
http://example.com/api/1.1/MONDAY/dosomething
And on the server side, there is a parsing, meaning, it is expectign things in lower case.
The request fails
If I were to change the enum to full lowercase, I can confirm the request is then working.
And sometimes, I get the Enum directly from a third-party library, where I cannot change the code.
However, this breaks the Java enum convention to have them as uppercase in the code.
How to have the Java enum as uppercase, but be able to send it as lowercase when sending the http request?
Enum#toString
and String#toLowercase
Let's configure an HTTP interface client to convert values of the Day enum to lowercase strings.
Register a Converter bean that accesses the name of the enum, then converts to lowercase strings.
@Component
public class DayToStringConverter implements Converter<Day, String> {
@Override
public String convert(Day source) {
return source.toString().toLowerCase(Locale.ROOT);
}
}
Spring Boot detects Converter beans and registers them in a ConversionService. An HTTP interface client invokes a ConversionService to format input values as strings. However, the default ConversionService used by an HTTP interface client is not the ConversionService that Spring Boot configured. You must set the ConversionService in the HTTP interface client:
@Bean
FooHttpExchange fooHttpExchange(ConversionService conversionService) {
// ...
return HttpServiceProxyFactory.builderFor(RestClientAdapter.create(restClient))
.conversionService(conversionService)
// ...
.build()
.createClient(FooHttpExchange.class);
}