in swagger-codegen swagger java ~ read.

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 :

  1. Find Java template from here
  2. Download the whole folder
  3. In the libraries find the one you use
  4. Open ApiClient.mustache file
  5. 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 to Java 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 :)

comments powered by Disqus
comments powered by Disqus