OpenAPITools / OpenAPITools/openapi-generator
[BUG] Method ApiClient.setObjectMapper() does not properly set a custom ObjectMapper in the Feing client
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 26.8k
- Forks
- 7.7k
- PR merge metrics
- PR metrics pending
Description
Description
I would like to use a ObjectMapper with custom configuration , but when I try to set it with method ApiClient.setObjectMapper() the Feign Client does not take it.
The problem happens inside the generated code - class ApiClient.
The Feign Client is created in the constructor:
public ApiClient() {
this.basePath = "https://localhost:8080/users";
this.objectMapper = this.createObjectMapper();
this.apiAuthorizations = new LinkedHashMap();
this.feignBuilder = Feign.builder().client(new OkHttpClient()).encoder(new FormEncoder(new JacksonEncoder(this.objectMapper))).decoder(new ApiResponseDecoder(this.objectMapper)).logger(new Slf4jLogger());
}
and so if you call method setObjectMapper() after that, it is not applied:
public void setObjectMapper(ObjectMapper objectMapper) {
this.objectMapper = objectMapper;
}
the method buildClient() uses the Feign Client with default ObjectMapper:
public <T extends ApiClient.Api> T buildClient(Class<T> clientClass) {
return (ApiClient.Api)this.feignBuilder.target(clientClass, this.basePath);
}
openapi-generator version
These are the related dependencies for both generator and client application:
<openapi-generator-maven-plugin.version>6.2.1</openapi-generator-maven-plugin.version>
<feign.version>10.11</feign.version>
<feign-form.version>3.8.0</feign-form.version>
<jackson.version>2.13.4</jackson.version>
<jackson-databind-nullable.version>0.2.4</jackson-databind-nullable.version>
<jackson-databind.version>2.13.4.2</jackson-databind.version>
Generation Details
The code is generated with OpenAPI Maven Plugin with this configuration:
<build>
<plugins>
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator-maven-plugin.version}</version>
<executions>
<execution>
<id>generate-api-code-client-java</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<inputSpec>${project.basedir}/../openapi.yaml</inputSpec>
<generatorName>java</generatorName>
<configOptions>
<invokerPackage>${project.groupId}.${project.artifactId}</invokerPackage>
<apiPackage>${project.groupId}.${project.artifactId}.api</apiPackage>
<modelPackage>${project.groupId}.${project.artifactId}.model</modelPackage>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<sourceFolder>src/gen/java/main</sourceFolder>
<dateLibrary>java8</dateLibrary>
<library>feign</library>
<java8>true</java8>
</configOptions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Steps to reproduce
The next code snippet illustrates the error:
// This is the ObjectMapper with custom config
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
objectMapper.configure(DeserializationFeature.ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT, false);
objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.coercionConfigDefaults().setCoercion(CoercionInputShape.EmptyString, CoercionAction.AsEmpty);
objectMapper.coercionConfigDefaults().setCoercion(CoercionInputShape.EmptyArray, CoercionAction.AsEmpty);
objectMapper.coercionConfigDefaults().setCoercion(CoercionInputShape.EmptyObject, CoercionAction.AsNull);
// This is the ApiClient creation and setup
ApiClient defaultClient = new ApiClient();
defaultClient.setBasePath(baseURL);
defaultClient.setObjectMapper(objectMapper); // here the mapper should be set
UsersApi = defaultClient.buildClient(UsersApi.class);
api.getUsers(); // here the mapper should be used but throws error as custom config is not applied
// i.e. com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot coerce empty String ("")
Suggest a fix
I think the method setObjectMapper() or the method buildClient() should force the rebuild of Feign Client when a custom mapper has been set.
The only workaround I found is creating a new Feign Client and setting it with method setFeignBuilder():
Builder feignBuilder = Feign.builder().client(new OkHttpClient()).encoder(new FormEncoder(new JacksonEncoder(objectMapper))).decoder(new ApiResponseDecoder(objectMapper)).logger(new Slf4jLogger());
defaultClient.setFeignBuilder(feignBuilder);
I think this is not a proper solution as the only part that needs to be set is the ObjectMapper.
Maybe there is an easier way to do it but I have not found it, I appreciate any help with this.
Thanks in advance!
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the generated ApiClient constructor, setObjectMapper(), and buildClient() shown in the issue, then locate the Java Feign generator template that produces them. Reproduce the custom ObjectMapper setup and verify that a client built afterward uses it instead of the default mapper.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- api
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100