Fixing "io.swagger.client.ApiException: Content type "text/plain" is not supported" problem
Let's say we have a endpoint definition in swagger like this :
/hello:
post:
summary: Say hello
description: ''
operationId: sayHello
consumes:
- text/plain
produces:
- application/json
parameters:
- in: body
name: body
required: false
schema:
type: string
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Hello'
You will be able to to generate ApiClient
for this swagger with swagger-codegen easily. The problem will be when you will try to make Api call to /hello
endpoint. Most probably you will get this error:
io.swagger.client.ApiException: Content type "text/plain" is not supported
at io.swagger.client.ApiClient.serialize(ApiClient.java:749)
at io.swagger.client.ApiClient.buildRequest(ApiClient.java:994)
at io.swagger.client.ApiClient.buildCall(ApiClient.java:945)
at io.swagger.client.api.DefaultApi.addTodoCall(DefaultApi.java:103)
Unfortunately it's not yet fixed in swagger-codegen itself, so you will have to use custom template to generate your clients from now on. Here's how you do it :
- Find Java template from here
- Download the whole folder
- In the
libraries
find the one you use - Open
ApiClient.mustache
file - Update
serialize
method to this :
/**
* Serialize the given Java object into request body according to the object's
* class and the request Content-Type.
*
* @param obj The Java object
* @param contentType The request Content-Type
* @return The serialized request body
* @throws ApiException If fail to serialize the given object
*/
public RequestBody serialize(Object obj, String contentType) throws ApiException {
if (obj instanceof byte[]) {
// Binary (byte array) body parameter support.
return RequestBody.create(MediaType.parse(contentType), (byte[]) obj);
} else if (obj instanceof File) {
// File body parameter support.
return RequestBody.create(MediaType.parse(contentType), (File) obj);
} else if (isJsonMime(contentType)) {
String content;
if (obj != null) {
content = json.serialize(obj);
} else {
content = null;
}
return RequestBody.create(MediaType.parse(contentType), content);
} else {
throw new ApiException("Content type \"" + contentType + "\" is not supported");
}
}
Now, in order to get correctly generated api client you have to generate your clients with this command :
swagger-codegen generate -i swagger.yml -c swagger-codegen-config.json -o api-client -l java -t {path_to_downloaded_java_template}/Java --artifact-version "1.0.0-` date '+%Y-%m-%d-%H-%M-%S'`" && cd api-client && mvn deploy && cd .. && rm -rf api-client
Where :
-i swagger
- path to your swagger file-ั swagger-codegen-config.json
- path to swagger codegen config. Very handy, but if you want to keep it simple, you can ommit it-0 api-client
- output path. Here your generated client will be stored-l java
- in which language to generate-t {path_to_downloaded_java_template}/Java
- path toJava
folder we downloaded and modified--artifact-version
- version of the artifact :)&& cd api-client && mvn deploy && cd .. && rm -rf api-client
- this is a shortcut i'm using for deploying generated client right away. It will basically deploy the client i need and then cleanup after itself.
If you want to use swagger-codegen-config
, here's an example of how i use it :
{
"groupId": "io.example",
"artifactId": "helloService",
"artifactDescription": "Swagger generated API Client for Hello Service API",
"artifactUrl": "https://github.com/hello",
"developerName": "hello",
"developerEmail": "info@hello.com",
"developerOrganization": "Hello",
"developerOrganizationUrl": "https://hello.com",
"apiPackage": "com.hello.service",
"modelPackage": "com.hello.service.models",
"performBeanValidation": false,
"useBeanValidation": false,
"java8": "true",
"dateLibrary": "java8",
"library": "okhttp-gson"
}
Ok, that should be enough. If you have any questions - leave a comment below.
Happy coding :)