13

I need to send an HTTP cookie, I'm using RestTemplate:

HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.add("Cookie", "SERVERID=c52");
HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
ResponseEntity responses = restTemplate.exchange(webService.getValidateUserUrl(),
       HttpMethod.POST, requestEntity,  String.class, mapValidateUser);

However, the receiving server doesn't see the cookie.

kryger
  • 12,906
  • 8
  • 44
  • 65
Ilkar
  • 2,113
  • 9
  • 45
  • 71
  • and where is the serverside code? -- Have you used a tool (like wireshark) to verify what is really send to the server? – Ralph Apr 17 '12 at 11:08
  • 2
    Which `ClientHttpRequestFactory` generated your `RestTemplate`? Depending on the factory, there could be a cookie store that you can add cookies to that will be added to your request automatically. This might be overriding your set header. – yincrash Apr 22 '12 at 23:02

2 Answers2

25

The default rest template does not use a persistent connetion, here is what I use.

public class StatefullRestTemplate extends RestTemplate
{
    private final HttpClient httpClient;
    private final CookieStore cookieStore;
    private final HttpContext httpContext;
    private final StatefullHttpComponentsClientHttpRequestFactory statefullHttpComponentsClientHttpRequestFactory;

    public StatefullRestTemplate()
    {
        super();
        HttpParams params = new BasicHttpParams();
        HttpClientParams.setRedirecting(params, false);

        httpClient = new DefaultHttpClient(params);
        cookieStore = new BasicCookieStore();
        httpContext = new BasicHttpContext();
        httpContext.setAttribute(ClientContext.COOKIE_STORE, getCookieStore());
        statefullHttpComponentsClientHttpRequestFactory = new StatefullHttpComponentsClientHttpRequestFactory(httpClient, httpContext);
        super.setRequestFactory(statefullHttpComponentsClientHttpRequestFactory);
    }

    public HttpClient getHttpClient()
    {
        return httpClient;
    }

    public CookieStore getCookieStore()
    {
        return cookieStore;
    }

    public HttpContext getHttpContext()
    {
        return httpContext;
    }

    public StatefullHttpComponentsClientHttpRequestFactory getStatefulHttpClientRequestFactory()
    {
        return statefullHttpComponentsClientHttpRequestFactory;
    }

}


public class StatefullHttpComponentsClientHttpRequestFactory extends HttpComponentsClientHttpRequestFactory
{
    private final HttpContext httpContext;

    public StatefullHttpComponentsClientHttpRequestFactory(HttpClient httpClient, HttpContext httpContext)
    {
        super(httpClient);
        this.httpContext = httpContext;
    }

    @Override
    protected HttpContext createHttpContext(HttpMethod httpMethod, URI uri)
    {
        return this.httpContext;
    }
}
ams
  • 60,316
  • 68
  • 200
  • 288
  • I got a weird bug due to this code when using this with parallel requests. I modified it to share the CookieStore but to create a new HttpContext each time, now the problem is gone. – Balázs Németh Oct 24 '19 at 13:27
10

You can also extend the RestTemplate:

public class CookieRestTemplate extends RestTemplate {

  @Override
  protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOException {
    ClientHttpRequest request = super.createRequest(url, method);

    request.getHeaders().add("Cookie", "SERVERID=c52");
    return request;
  }

}

ticktock
  • 1,593
  • 3
  • 16
  • 38
  • how is this different from the original code? I think the key here is, as stated in the most voted answer, the non-persistent nature of the HTTP connection when using the regular RestTemplate. – Clint Eastwood Mar 15 '16 at 17:58
  • The original code didn't set the cookie you needed to set... since you have to define the cookie with each request.. here ya go. – ticktock Mar 15 '16 at 20:47
  • 1
    fair enough. Will change my downvote. Thanks for the explanation. – Clint Eastwood Mar 15 '16 at 20:49