web-dev-qa-db-ja.com

Cookieを使用したRestTemplateクライアント

Javaで簡単なクライアントを作成し、RESTful APIを介してアクセス可能な独自のウイルススキャンソフトウェアを再利用できるようにします。APIをスキャンするファイルをアップロードするには、ConnectにPOSTファイルをサーバーに公開するためのPOST Connect POSTへの応答には、ファイルを公開するために後続のPOSTに存在する必要があるサーバーによって設定されたCookieがあります。現在、クライアントでSpring RestTemplateを使用しています。

私の質問は、応答内のCookieにアクセスして、後続のPOSTを使用してサーバーに戻す方法です。返されるヘッダーに存在していることがわかりますが、ResponseEntityにアクセスするメソッドはありません。

15
Tom

RestTemplateには、インターフェイスResponseExtractor<T>、このインターフェイスは応答のヘッダーを取得するために使用されます。ヘッダーを取得したら、HttpEntityを使用して返信し、再度追加できます。

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

このようなものを試してください。

String cookieHeader = null;

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

それから

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

こちらもお読みください post

12
Koitoer

Java SpringフレームワークのexchangeRestTemplateメソッドを使用する必要があります。

このチュートリアルを読む: http://codeflex.co/Java-rest-client-get-cookie/

4
user5495300

「Java.net.HttpCookie」オブジェクトを使用した完全なテストでセッションを処理するための小さな更新。

@ありがとうシェドン

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

}
4
GerardNorton

クッキーを保存して次のリクエストに入れるインターセプターを作成することで問題を解決しました。

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

RestTemplateのインターセプターを設定します。

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

restTemplateを拡張し、Cookieを処理する単純なクラスを作成しました。

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

}
2
Shedon