首页 文章

如何禁用分块编码并为Jersey 1使用缓冲?

提问于
浏览
3

在我的应用程序中执行对第三方服务的调用时,我遇到了411响应状态,需要411长度 .

问题似乎与 chuncked encoding 有关,将其切换为 buffered 可以解决问题 . Jersey2有一个解决方案:Jersey Http Client replying with 411 on POST request

但是由于一些遗留问题,我们在应用程序中使用Jersey1,我们无法在不久的将来执行迁移 .

我试图找出问题所在 . 这是最小的代码:

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());
  }

}

这是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'
}

我试过的是添加将切换到缓冲调用的配置:

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

我引用该 properties 的文件 PROPERTY_CHUNKED_ENCODING_SIZE

如果该属性不存在,则不会使用分块编码 . 值<= 0声明chunked编码将与默认块大小一起使用 . 值> 0表示将使用chunked编码将该值作为声明的块大小 .

即使我设置了这个属性,我仍然会收到411响应状态,需要411长度 .

Later edit: 我的电话没有离开本地机器 . 当它这样做时,我应该收到401 Unauthorized,因为我需要添加一个带有auth密钥的标头 . 然而,这不是这个问题的焦点,但是如果有人认为更好地添加如何获得这个的详细信息,请发表评论,我将描述更多 .

1 回答

  • 3

    首先

    您无需设置标志 ClientConfig.PROPERTY_CHUNKED_ENCODING_SIZE ,请查看here或上面的报价 .

    Jersey客户端默认情况下将 Content-Type 设置为 application/json (本质上),因此您应该已经传递了空白的json对象以使用http请求传递 Content-length 正确 .

    因此,为了使其工作,您应该__37621_一个空白 json 对象而不设置 Content-Length Headers .

    这是工作代码,您将获得 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());
      }
    }
    

相关问题