it-swarm.com.de

RestTemplate-Client mit Cookies

Ich schreibe einen einfachen Client in Java, um die wiederverwendbare Verwendung von proprietärer Virenscanner-Software zu ermöglichen, auf die über eine RESTful-API zugegriffen werden kann. Um eine Datei zum Scannen der API hochzuladen, ist ein POST für Connect erforderlich, gefolgt von einem POST zum Veröffentlichen der Datei auf dem Server. In der Antwort auf Connect POST gibt es vom Server gesetzte Cookies, die in dem nachfolgenden POST zum Veröffentlichen der Datei vorhanden sein müssen. Ich verwende derzeit Spring RestTemplate in meinem Client.

Meine Frage ist, wie kann ich auf die Cookies in der Antwort zugreifen, um sie mit dem nachfolgenden POST an den Server weiterzuleiten? Ich kann sehen, dass sie im zurückgegebenen Header vorhanden sind, aber auf ResponseEntity keine Methoden vorhanden sind, um darauf zuzugreifen.

12
Tom

RestTemplate verfügt über eine Methode, in der Sie die Schnittstelle ResponseExtractor<T> definieren können. Diese Schnittstelle wird verwendet, um die Header der Antwort abzurufen. Sobald Sie sie haben, können Sie sie mit HttpEntity zurücksenden und erneut hinzufügen.

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

Versuchen Sie so etwas.

String cookieHeader = null;

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

Dann

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

Lesen Sie auch diese post

9
Koitoer

Sie müssen die exchange-Methode von RestTemplate des Java Spring-Frameworks verwenden. 

Lesen Sie dieses Tutorial: http://codeflex.co/Java-rest-client-get-cookie/

3
user5495300

Kleines Update, um Sitzungen in einem vollständigen Test mit 'Java.net.HttpCookie' Object zu verarbeiten.

Vielen Dank für 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

Ich habe das Problem gelöst, indem ich einen Abfangjäger erstellt habe, in dem ein Cookie gespeichert und bei den nächsten Anfragen abgelegt wird.

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

Stellen Sie den Interceptor für Ihr RestTemplate ein:

@Bean
public RestTemplate restTemplate(RestTemplateBuilder templateBuilder) {
    return templateBuilder
            .requestFactory(new BufferingClientHttpRequestFactory(new HttpComponentsClientHttpRequestFactory()))
            .interceptors(new StatefulRestTemplateInterceptor())
            .build();
}
2
Ilya Lysenko

ich habe eine einfache Klasse geschrieben, die RestTemplate erweitert und Cookies behandelt.

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