Flowryn
Flowryn

Reputation: 1447

How to disable chunked encoding and use buffered for Jersey 1?

I am encountering a HTTP response status of 411 Length Required when performing a call to a 3rd party service in my application.

The problem seems to be related to chuncked encoding, switching it to buffered would solve the problem. There is a solution here for Jersey2: Jersey Http Client replying with 411 on POST request

However due to some legacy, we are using Jersey1 in our application and we can not perform a migration in the close future.

I tried to isolate the problem. Here is the minimal code:

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.json.JSONConfiguration;


/**
 * Main
 */
public class Main {

  public static void main(String[] args) {
    ClientConfig clientConfig = new DefaultClientConfig();
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    clientConfig.getProperties().put(ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, null);
    Client client = Client.create(clientConfig);

    String postURL = "https://api.napster.com/v2.2/me/library/tracks?id=tra.169783383,tra.30621111";
    WebResource webResourcePost = client.resource(postURL);
    webResourcePost.header("Content-Length", 0);
    ClientResponse response = webResourcePost.type("application/json").post(ClientResponse.class);
    System.out.println(response.getStatus());
  }

}

Here is build.gradle:

apply plugin: 'application'
apply plugin: 'java'

repositories {
  mavenCentral()
  mavenLocal()
}

mainClassName = "Main"

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.11'
    compile group: 'com.sun.jersey.contribs', name: 'jersey-apache-client', version: '1.19.4'
    compile group: 'com.sun.jersey', name: 'jersey-json', version: '1.19.4'
}

What I have tried is to add the configuration which would switch to a buffered call:

clientConfig.getProperties().put(ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, null);

I quote from the documentation of the property PROPERTY_CHUNKED_ENCODING_SIZE

If the property is absent then chunked encoding will not be used. A value < = 0 declares that chunked encoding will be used with the default chunk size. A value > 0 declares that chunked encoding will be used with the value as the declared chunk size.

Even if I set this property I still receive the HTTP response status of 411 Length Required.

Later edit: My call does not leave the the local machine. When it does so I am expected to receive a 401 Unauthorized, since I will need to add a header with an auth key. Yet this is not the focus of this question, however if anyone considers is better to add details on how to obtain this, please leave a comment and I will describe more.

Upvotes: 4

Views: 4228

Answers (1)

Rishikesh Darandale
Rishikesh Darandale

Reputation: 3310

To start with

You do not have to set flag ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, please check here or in your quote above.

Jersey Client by default will set the Content-Type as application/json (by nature), thus you should have passed the blank json object to get the Content-length correct passed in with http request.

Thus to get it work, you should post a blank json object without setting the Content-Length Header.

Here is the working code, where you will get HTTP 401

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;
import com.sun.jersey.api.client.filter.LoggingFilter;
import com.sun.jersey.api.json.JSONConfiguration;

/**
 * Main
 */
public class Main {

    public static void main(String[] args) {
    ClientConfig clientConfig = new DefaultClientConfig();
    clientConfig.getFeatures().put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE);
    //clientConfig.getProperties().put(ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE, null);
    Client client = Client.create(clientConfig);
    client.addFilter(new LoggingFilter(System.out));

    String postURL = "https://api.napster.com/v2.2/me/library/tracks?id=tra.169783383,tra.30621111";
    WebResource webResourcePost = client.resource(postURL);
    //webResourcePost.header("Content-Length", 0);
    ClientResponse response = webResourcePost.type("application/json").post(ClientResponse.class, "{}");
    System.out.println(response.getStatus());
  }
}

Upvotes: 4

Related Questions