Reputation: 1447
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
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