web-dev-qa-db-fra.com

Client RestTemplate avec des cookies

J'écris un client simple en Java pour permettre l'utilisation réutilisable d'un logiciel d'analyse antivirus exclusif accessible via une API RESTful. Pour télécharger un fichier pour l'analyse de l'API, une variable POST pour Connect, suivie d'une POST pour Publier le fichier sur le serveur. Dans la réponse à Connect POST, le serveur a défini des cookies qui doivent être présents dans la version suivante POST pour la publication du fichier. J'utilise actuellement Spring RestTemplate dans mon client.

Ma question est la suivante: comment accéder aux cookies dans la réponse pour le renvoyer au serveur avec la variable suivante POST? Je peux voir qu'ils sont présents dans l'en-tête qui est renvoyé, mais il n'y a pas de méthode sur la variable ResponseEntity pour y accéder.

12
Tom

RestTemplate a une méthode dans laquelle vous pouvez définir Interface ResponseExtractor<T>, cette interface est utilisée pour obtenir les en-têtes de la réponse. Une fois que vous les avez, vous pouvez les renvoyer à l'aide de HttpEntity et les rajouter.

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

Essayez quelque chose comme ça.

String cookieHeader = null;

new ResponseExtractor<T>(){
      T extractData(ClientHttpResponse response) {
        response.getHeaders();
      }
}

Ensuite

  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);

Lisez aussi ceci post

9
Koitoer

Vous devez utiliser la méthode exchange de RestTemplate du framework Java Spring. 

Lisez ce tutoriel: http://codeflex.co/Java-rest-client-get-cookie/

3
user5495300

Petite mise à jour pour gérer les sessions dans un test complet avec l'objet 'Java.net.HttpCookie'.

@Merci 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);
            }
        });
    }

}
2
GerardNorton

j'ai écrit une classe simple qui étend RestTemplate et gère les 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);
            }
        });
    }

}
1
Shedon