【问题标题】:Apache HttpComponents ignoring POST data on redirect (HTTP 302)Apache HttpComponents 忽略重定向时的 POST 数据 (HTTP 302)
【发布时间】:2018-08-31 17:19:48
【问题描述】:

我正在使用 Apache HttpComponents 连接到另一家公司的 API。

这家公司服务器正在将我的 POST 请求重定向到另一个位置,因此我必须配置 HttpComponents 以允许循环重定向:

private RequestConfig defaultRequestConfig = RequestConfig.custom()
    .setCookieSpec(CookieSpecs.DEFAULT)
    .setCircularRedirectsAllowed(true)
    .build();

private CloseableHttpClient httpclient = HttpClients.custom()
    .setDefaultRequestConfig(defaultRequestConfig)
    .setRedirectStrategy(CustomRedirectStrategy.INSTANCE)
    .build();

GET 请求工作正常,但是当我尝试 POST 时,似乎 HttpComponents 忽略了我尝试发送的正文。 Bellow 是我用于 POST 的代码以及 HttpComponents 生成的(恢复的)日志:

public CloseableHttpResponse doPOST(String url, String stringEntity) throws IOException {
    HttpPost request = new HttpPost(url);
    request.setEntity(new StringEntity(stringEntity));
    request.setHeader("Accept", "application/json;");
    request.setHeader("Content-type", "application/json;");
    return httpclient.execute(request);
}

-> POST (http://some-server.com/api/test)       (Content-Length: 65)
<-  302 (https://some-server.com/api/test)

-> POST (https://some-server.com/api/test)      (Content-Length: 0)
<-  302 (http://some-server.com/api/test)

-> POST (http://some-server.com/api/test)       (Content-Length: 0)
<-  302 (https://some-server.com/api/test)

-> POST (https://some-server.com/api/test)      (Content-Length: 0)
<-  404 (Not Found)

-&gt; 用于我发送的消息,&lt;- 用于接收的消息

我看到第一个 POST 的 Content-Length 为 65,但重定向后的 POST 没有。

重定向后 HttpComponents 是否忽略了我的 POST 实体?如果是这样,我如何配置它以即使在重定向时也发送此数据?

Obs.:CustomRedirectStrategy 是我创建的一个类,它从 LaxRedirectStrategy 扩展并覆盖 #getRedirect 以将 POST 方法重定向到 POST,而不是 GET。

【问题讨论】:

    标签: java http post apache-httpcomponents


    【解决方案1】:

    要将原始 POST 中的数据重新发布到重定向,我们可以实现特定的重定向策略,覆盖 #getRedirect

    @Contract(threading = ThreadingBehavior.IMMUTABLE)
    public class CustomRedirectStrategy extends LaxRedirectStrategy {
    
        public static final CustomRedirectStrategy INSTANCE = new CustomRedirectStrategy();
    
        @Override
        public HttpUriRequest getRedirect(
                final HttpRequest request,
                final HttpResponse response,
                final HttpContext context) throws ProtocolException {
            final URI uri = getLocationURI(request, response, context);
            final String method = request.getRequestLine().getMethod();
            if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
                return new HttpHead(uri);
            } else if (method.equalsIgnoreCase(HttpGet.METHOD_NAME)) {
                return new HttpGet(uri);
            } else if (method.equalsIgnoreCase(HttpPost.METHOD_NAME)) {
                return RequestBuilder.copy(request).setUri(uri).build(); // Here
            } else {
                final int status = response.getStatusLine().getStatusCode();
                if (status == HttpStatus.SC_TEMPORARY_REDIRECT) {
                    return RequestBuilder.copy(request).setUri(uri).build();
                } else {
                    return new HttpGet(uri);
                }
            }
        }
    
    }
    

    对于 POST 方法,根据原始请求返回一个请求。

    为此,您必须在 HttpClient 实例上设置此重定向策略:

    public CloseableHttpClient getHttpClient() {
        return HttpClients.custom()
                .setDefaultRequestConfig(defaultRequestConfig)
                .setRedirectStrategy(CustomRedirectStrategy.INSTANCE) // Here
                .build();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-25
      • 1970-01-01
      • 2023-04-01
      相关资源
      最近更新 更多