I have spring's open feign client configurations like the following:
public class AppFeignConfiguration
{
@Bean
public ErrorDecoder errorDecoder()
{
return new FeignErrorDecoder();
}
@Bean
public Logger.Level logger()
{
return Logger.Level.FULL;
}
@Bean
public Request.Options options()
{
return new Request.Options( 30000, 30000 );
}
}
and I provide it as a configuration in the @FeignClient
as the following
@FeignClient ( value = "apigateway-service", configuration = AppFeignConfiguration.class)
I believe FeignClient has its default configuration for deserializing the response (maybe an ObjectMapper with some properties).
All good so far. Everything was working as expected.
Then I created a custom object mapper and returned it as a bean like the following:
@Configuration
public class ObjectMapperConfig
{
@Bean ( name = "plainObjectMapper")
public ObjectMapper plainObjectMapper()
{
return new ObjectMapper();
}
}
The problem now is, this is messing with the default deserializing configurations of FeignClient
.
Meaning, without the custom plainObjectMapper
, it used to work fine without any json parsing errors. But after creating the custom plainObjectMapper
as a bean, FeignClient
is throwing exceptions saying some unknown properties or something.
nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized field "xyz" (class abc.def.ghi.class), not marked as ignorable; nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException
I confirmed this by removing the custom plainObjectMapper
and it worked fine just as it used to before.
This seems to be strange! I have given the bean a custom name which should not mess with the bean created by springboot.
How can I overcome this conflict?
This is not completely correct.
If you look at FeignClientsConfiguration
source, you can see that its encoders rely on HttpMessageConverters
class.
Then, HttpMessageConvertersAutoConfiguration
(source) itself depends on JacksonAutoConfiguration
.
The latter creates the default ObjectMapper
bean only if there is no manually created object mapper in context (see @ConditionalOnMissingBean
on the corresponding method) - the different bean name doesn't matter in this case.
So, it happens that Feign is implicitly relying on this auto-configured ObjectMapper
but only until you create your own. Then it starts to use yours. Same with many other spring beans.
If you really need to have your own ObjectMapper
bean, then you need to configure it properly. But you can customize the auto-configured one instead via configuration properties - see docs.