添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account
Description

Generated by swagger code for android for volley library incorrect handles post requests with json body. When I use api method with json body, I receive an error response with status = 400 and message "Invalid header". The problem is in this code fragment in ApiInvoker class:

request = new PostRequest(url, headers, contentType, new StringEntity(serialize(body), "UTF-8"), stringRequest, errorListener);

By default in my case code

 new StringEntity(serialize(body), "UTF-8")

creates an entity with text/plain content type. That is wrong because server expects application/json content type.

Swagger-codegen version
Swagger declaration file content or url
Command line used for generation
Steps to reproduce
Related issues
Suggest a Fix

To fix it is sufficient to replace code

request = new PostRequest(url, headers, contentType, new StringEntity(serialize(body), "UTF-8"), stringRequest, errorListener);
StringEntity entity = new StringEntity(serialize(body),"UTF-8");
entity.setContentType("application/json");
request = new PostRequest(url, headers, contentType, entity, stringRequest, errorListener);
changed the title [Android][Volley] Post requests with json body raises exception Invalid header [Android][Volley] Post requests with json body raise exception Invalid header May 5, 2017

Having the same issue.
A simple POST that swagger.yaml declares as consumes "application/json" is sent to server with two content types.
From WireShark "copy as plain text" of the http packet:

POST /api/things HTTP/1.1
Accept: application/json
User-Agent: Swagger-Codegen/1.0.0/android
Content-Type: application/json
Content-Type: text/plain; charset=UTF-8

Debugging using Android studio, I see that for POST methods, HurlStack.addBodyIfExists() is called, and for POSTs with a body (which most POSTs have), it calls

connection.addRequestProperty(HEADER_CONTENT_TYPE, request.getBodyContentType());

request.getBodyContentType() takes the content type from the request's org.apache.http.HttpEntity . The instance of the HttpEntity is actually a StringEntity , which returns a text/plain content type by default.

the fix suggested by @rasuldev will possibly work with other servers, but does not work with swagger-generated "jaxrs" server. The reason is that there are 2 lines with Content-Type: application/json in the request.

POST /api/things HTTP/1.1
Accept: application/json
User-Agent: Swagger-Codegen/1.0.0/android
Content-Type: application/json
Content-Type: application/json

Sounds like the correct fix is to change io.swagger.client.request.PostRequest to include only one content-type. It currently has two: one in field contentType and another in field HttpEntity .

For now, I locally changed PostRequest to return the content-type of contentType when asked for the body's content-type (could have used the suggestion from @rasuldev but had to also change the contentType sent to the PostRequest c'tor to null)

replaced

public String getBodyContentType() {
    if(entity == null) {
      return null;
    return entity.getContentType().getValue();
 public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();
    if (headers == null || headers.equals(Collections.emptyMap())) {
        headers = new HashMap<String, String>();
    if (apiHeaders != null && !apiHeaders.equals(Collections.emptyMap())) {
        headers.putAll(apiHeaders);
    if(contentType != null) {
        headers.put("Content-Type", contentType);
    return headers;

with:

public String getBodyContentType() {
    if (contentType != null) {
      return contentType;
    if(entity == null) {
      return null;
    return entity.getContentType().getValue();
 public Map<String, String> getHeaders() throws AuthFailureError {
    Map<String, String> headers = super.getHeaders();
    if (headers == null || headers.equals(Collections.emptyMap())) {
        headers = new HashMap<String, String>();
    if (apiHeaders != null && !apiHeaders.equals(Collections.emptyMap())) {
        headers.putAll(apiHeaders);
    if((entity == null) && (contentType != null)) {
        headers.put("Content-Type", contentType);
    return headers;

and now it works :)

POST /api/things HTTP/1.1
Accept: application/json
User-Agent: Swagger-Codegen/1.0.0/android
Content-Type: application/json

and getting HTTP 200

@kfirwolfson description is precise. @wing328 can we re-open?

The problem is in this StringEntity constructor, where for request = new PostRequest(url, headers, contentType, new StringEntity(serialize(body), "UTF-8"), stringRequest, errorListener); ContentType.TEXT_PLAIN.getMimeType() is enforced. And then HurlStack allows two ContentType headers to be present.

I have hit this same problem. I'm using an IIS server and having two Content-Type headers throws a failure.

It would be great if this issue could be reopened and the the generated code updated so I don't have to modify it after every codegen.

Incidentally, my solution was to change:

request = new PostRequest(url, headers, contentType, new StringEntity(serialize(body), "UTF-8"), stringRequest, errorListener);
request = new PostRequest(url, headers, null, new StringEntity(serialize(body), APPLICATION_JSON), stringRequest, errorListener);

This resulted in just the one content type being added.