4
votes

I'm trying to create an HTTP POST request from a simple Java Project.

I need to keep session and cookies through two requests, so I opted for the 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).

Can anybody tell me what's wrong with my code, please?

Thanks

1

1 Answers

4
votes

By default, only GET requests resulting in a redirect are automatically followed. If a POST requests is answered with either HTTP 301 Moved Permanently or with 302 Found, the redirect is not automatically followed.

This is specified by the 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.

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.

So you can create the CloseableHttpClient instance with a method like the follow:

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

And use it to manage the POST request.