Javaで簡単なクライアントを作成し、RESTful APIを介してアクセス可能な独自のウイルススキャンソフトウェアを再利用できるようにします。APIをスキャンするファイルをアップロードするには、ConnectにPOST
ファイルをサーバーに公開するためのPOST
Connect POST
への応答には、ファイルを公開するために後続のPOST
に存在する必要があるサーバーによって設定されたCookieがあります。現在、クライアントでSpring RestTemplate
を使用しています。
私の質問は、応答内のCookieにアクセスして、後続のPOST
を使用してサーバーに戻す方法です。返されるヘッダーに存在していることがわかりますが、ResponseEntity
にアクセスするメソッドはありません。
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
Java Springフレームワークのexchange
のRestTemplate
メソッドを使用する必要があります。
このチュートリアルを読む: http://codeflex.co/Java-rest-client-get-cookie/
「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);
}
});
}
}
クッキーを保存して次のリクエストに入れるインターセプターを作成することで問題を解決しました。
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();
}
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);
}
});
}
}