RestTemplate client with cookies

后端 未结 7 691
谎友^
谎友^ 2020-12-08 15:08

I\'m writing a simple client in Java to allow reusable use of proprietary virus scanning software accessible through a RESTful API. To upload a file for scanning the API req

相关标签:
7条回答
  • 2020-12-08 15:36

    You need to use exchange method of RestTemplate of Java Spring framework.

    Read this tutorial: http://codeflex.co/java-rest-client-get-cookie/

    0 讨论(0)
  • 2020-12-08 15:38

    I've solved the problem by creating an interceptor which stores a cookie and puts it in next requests.

    public class StatefulRestTemplateInterceptor implements ClientHttpRequestInterceptor {
        private String cookie;
    
        @Override
        public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
            if (cookie != null) {
                request.getHeaders().add(HttpHeaders.COOKIE, cookie);
            }
            ClientHttpResponse response = execution.execute(request, body);
    
            if (cookie == null) {
                cookie = response.getHeaders().getFirst(HttpHeaders.SET_COOKIE);
            }
            return response;
        }
    }
    

    Set the interceptor for your RestTemplate:

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder templateBuilder) {
        return templateBuilder
                .requestFactory(new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory()))
                .interceptors(new StatefulRestTemplateInterceptor())
                .build();
    }
    
    0 讨论(0)
  • 2020-12-08 15:39

    RestTemplate has a method in which you can define Interface ResponseExtractor<T>, this interface is used to obtain the headers of the response, once you have them you could send it back using HttpEntity and added again.

     .add("Cookie", "SERVERID=c52");
    

    Try something like this.

    String cookieHeader = null;
    
    new ResponseExtractor<T>(){
          T extractData(ClientHttpResponse response) {
            response.getHeaders();
          }
    }
    

    Then

      HttpHeaders headers = new HttpHeaders();
      headers.add("Cookie", cookieHeader );
    
      ResponseEntity<byte[]> response = restTemplate.exchange("http://example.com/file/123",
          GET,
          new HttpEntity<String>(headers),
          byte[].class);
    

    Also read this post

    0 讨论(0)
  • 2020-12-08 15:40

    i've wrote a simple class that extends RestTemplate and handles cookies.

    import java.io.IOException;
    import java.net.URI;
    import java.util.List;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.client.ClientHttpRequest;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.ClientHttpResponse;
    import org.springframework.web.client.RequestCallback;
    import org.springframework.web.client.ResponseExtractor;
    import org.springframework.web.client.RestClientException;
    import org.springframework.web.client.RestTemplate;
    
    public class RestTemplateWithCookies extends RestTemplate {
    
        private List<String> cookies = null;
    
        public RestTemplateWithCookies() {
        }
    
        public RestTemplateWithCookies(ClientHttpRequestFactory requestFactory) {
            super(requestFactory);
        }
    
        private synchronized List<String> getCoookies() {
            return cookies;
        }
    
        private synchronized void setCoookies(List<String> cookies) {
            this.cookies = cookies;
        }
    
        public synchronized void resetCoookies() {
            this.cookies = null;
        }
    
        private void processHeaders(HttpHeaders headers) {
            final List<String> cookies = headers.get("Set-Cookie");
            if (cookies != null && !cookies.isEmpty()) {
                setCoookies(cookies);
            }
        }
    
        @Override
        protected <T extends Object> T doExecute(URI url, HttpMethod method, final RequestCallback requestCallback, final ResponseExtractor<T> responseExtractor) throws RestClientException {
            final List<String> cookies = getCoookies();
    
            return super.doExecute(url, method, new RequestCallback() {
                @Override
                public void doWithRequest(ClientHttpRequest chr) throws IOException {
                    if(cookies != null) {
                        for(String cookie : cookies) {
                            chr.getHeaders().add("Cookie", cookie);
                        }
                    }
                    requestCallback.doWithRequest(chr);
                }
    
            }, new ResponseExtractor<T>() {
                @Override
                public T extractData(ClientHttpResponse chr) throws IOException {
                    processHeaders(chr.getHeaders());
                    return responseExtractor.extractData(chr);
                }
            });
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 15:46

    Small update to handle sessions in a complete test with 'java.net.HttpCookie' Object.

    @Thanks Shedon

    import java.io.IOException;
    import java.net.HttpCookie;
    import java.net.URI;
    import java.util.ArrayList;
    import java.util.List;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.client.ClientHttpRequest;
    import org.springframework.http.client.ClientHttpRequestFactory;
    import org.springframework.http.client.ClientHttpResponse;
    import org.springframework.stereotype.Component;
    import org.springframework.web.client.RequestCallback;
    import org.springframework.web.client.ResponseExtractor;
    import org.springframework.web.client.RestClientException;
    import org.springframework.web.client.RestTemplate;
    
    /**
     * @link https://stackoverflow.com/questions/22853321/resttemplate-client-with-cookies
     */
    @Component
    public class RestTemplateWithCookies extends RestTemplate {
    
        private final List<HttpCookie> cookies = new ArrayList<>();
    
        public RestTemplateWithCookies() {
        }
    
        public RestTemplateWithCookies(ClientHttpRequestFactory requestFactory) {
            super(requestFactory);
        }
    
        public synchronized List<HttpCookie> getCoookies() {
            return cookies;
        }
    
        public synchronized void resetCoookies() {
            cookies.clear();
        }
    
        private void processHeaders(HttpHeaders headers) {
            final List<String> cooks = headers.get("Set-Cookie");
            if (cooks != null && !cooks.isEmpty()) {
                cooks.stream().map((c) -> HttpCookie.parse(c)).forEachOrdered((cook) -> {
                    cook.forEach((a) -> {
                        HttpCookie cookieExists = cookies.stream().filter(x -> a.getName().equals(x.getName())).findAny().orElse(null);
                        if (cookieExists != null) {
                            cookies.remove(cookieExists);
                        }
                        cookies.add(a);
                    });
                });
            }
        }
    
        @Override
        protected <T extends Object> T doExecute(URI url, HttpMethod method, final RequestCallback requestCallback, final ResponseExtractor<T> responseExtractor) throws RestClientException {
            final List<HttpCookie> cookies = getCoookies();
    
            return super.doExecute(url, method, new RequestCallback() {
                @Override
                public void doWithRequest(ClientHttpRequest chr) throws IOException {
                    if (cookies != null) {
                        StringBuilder sb = new StringBuilder();
                        for (HttpCookie cookie : cookies) {
                            sb.append(cookie.getName()).append(cookie.getValue()).append(";");
                        }
                        chr.getHeaders().add("Cookie", sb.toString());
                    }
                    requestCallback.doWithRequest(chr);
                }
    
            }, new ResponseExtractor<T>() {
                @Override
                public T extractData(ClientHttpResponse chr) throws IOException {
                    processHeaders(chr.getHeaders());
                    return responseExtractor.extractData(chr);
                }
            });
        }
    
    }
    
    0 讨论(0)
  • 2020-12-08 15:58

    To get more browser like behavior you can use this interceptor:

    import java.io.IOException;
    import java.net.HttpCookie;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.stream.Collectors;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpRequest;
    import org.springframework.http.client.ClientHttpRequestExecution;
    import org.springframework.http.client.ClientHttpRequestInterceptor;
    import org.springframework.http.client.ClientHttpResponse;
    
    public class CookieHandlingClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
    
      private static final Logger LOG = LoggerFactory.getLogger(CookieHandlingClientHttpRequestInterceptor.class);
    
      private final Map<String, HttpCookie> cookies = new HashMap<>();
    
      @Override
      public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        List<String> cookiesForRequest = cookies.values().stream()
            .filter(cookie -> cookie.getPath() != null && request.getURI().getPath().startsWith(cookie.getPath()))
            .map(HttpCookie::toString)
            .collect(Collectors.toList());
        LOG.info("Using cookies: {}", cookiesForRequest);
        request.getHeaders().addAll(HttpHeaders.COOKIE, cookiesForRequest);
    
        ClientHttpResponse response = execution.execute(request, body);
    
        List<String> newCookies = response.getHeaders().get(HttpHeaders.SET_COOKIE);
        if (newCookies != null) {
          List<HttpCookie> parsedCookies = newCookies.stream().flatMap(rawCookie -> HttpCookie.parse(HttpHeaders.SET_COOKIE + ": " + rawCookie).stream()).collect(Collectors.toList());
          LOG.info("Extracted cookies from response: {}", parsedCookies);
          parsedCookies.forEach(newCookie -> cookies.put(newCookie.getName(), newCookie));
        }
    
        return response;
      }
    }
    

    And keep in mind that by default RestTemplate follows redirects for GET requests. In this case the above interceptor is bypassed.

    0 讨论(0)
提交回复
热议问题