简体   繁体   English

使用CloseableHttpClient发出POST请求

[英]POST Request with CloseableHttpClient

I'm trying to create an HTTP POST request from a simple Java Project. 我正在尝试从简单的Java项目创建HTTP POST请求。

I need to keep session and cookies through two requests, so I opted for the Apache HttpClient . 我需要通过两个请求保持会话和cookie,所以我选择了Apache HttpClient

The code compiles with no errors and runs, but it returns a zero-length content and I can't understand why. 代码编译没有错误并运行,但它返回零长度内容,我无法理解为什么。

public class Test {

    private static final String CONTENT_TYPE = "Content-Type";
    private static final String FORM_URLENCODED = "application/x-www-form-urlencoded";

    public static void main(String[] args) {

        try {

            CloseableHttpClient httpClient = HttpClients.createDefault();

            BasicHttpContext httpCtx = new BasicHttpContext();
            CookieStore store = new BasicCookieStore();
            httpCtx.setAttribute(HttpClientContext.COOKIE_STORE, store);

            String url = "http://myhost:port/app/";
            String body = "my body string";

            HttpPost httpPost = new HttpPost(url);
            httpPost.setHeader(CONTENT_TYPE, FORM_URLENCODED);
            StringEntity entity = new StringEntity(body);

            httpPost.setEntity(entity);
            CloseableHttpResponse response = httpClient.execute(httpPost, httpCtx);
            HttpEntity respentity = response.getEntity();

            System.out.println("respentity: " + respentity);

            System.out.println("EntityUtils.toString(respentity): " + EntityUtils.toString(respentity));

            EntityUtils.consume(respentity);

            System.out.println("respentity: " + respentity);
            System.out.println("EntityUtils.toString(respentity): " + EntityUtils.toString(respentity));

        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

}

The result is: 结果是:

respentity: [Content-Length: 0,Chunked: false]
EntityUtils.toString(respentity): 
respentity: [Content-Length: 0,Chunked: false]
EntityUtils.toString(respentity): 

Updated: I found out the response status is 302 (Found) , when I do the same request from Postman it's 200 (OK) . 更新:我发现响应状态是302(Found) ,当我从Postman做同样的请求时它是200(OK)

Can anybody tell me what's wrong with my code, please? 有人能告诉我我的代码有什么问题吗?

Thanks 谢谢

By default, only GET requests resulting in a redirect are automatically followed. 默认情况下,仅自动遵循导致重定向的GET请求。 If a POST requests is answered with either HTTP 301 Moved Permanently or with 302 Found , the redirect is not automatically followed. 如果使用HTTP 301 Moved Permanently或使用302 Found回答POST请求,则不会自动遵循重定向。

This is specified by the HTTP RFC 2616: 这由HTTP RFC 2616指定:

If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued. 如果收到301状态代码以响应GET或HEAD以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变发出请求的条件。

With HttpClient 4.2 (or higher) , we can set the Redirect Strategy to LaxRedirectStrategy , this strategy relaxes restrictions on automatic redirection of POST methods imposed by the HTTP specification. 使用HttpClient 4.2(或更高版本) ,我们可以将重定向策略设置为LaxRedirectStrategy ,这种策略放宽了对HTTP规范强加的POST方法自动重定向的限制。

So you can create the CloseableHttpClient instance with a method like the follow: 因此,您可以使用CloseableHttpClient方法创建CloseableHttpClient实例:

private CloseableHttpClient createHttpClient() {
    HttpClientBuilder builder = HttpClientBuilder.create();
    return builder.setRedirectStrategy(new LaxRedirectStrategy()).build();
}

And use it to manage the POST request. 并使用它来管理POST请求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM