3 回答

TA貢獻1890條經驗 獲得超9個贊
在編寫服務器端Java和JSP多年之后,我在很大程度上忽略了cookie的概念,因為管理是由(例如)服務器端的Tomcat和客戶端的瀏覽器負責的。在Spring中,任何對cookie處理的搜索總是集中在Spring服務器上,很少關注Spring實際上是另一個服務器的客戶端。WebClient 的任何示例都是過于簡單化的,并且沒有采用任何形式的安全協商。
在閱讀了餅干解釋維基百科餅干和餅干標準RFC6265之后,對我來說,為什么傳入的餅干在課堂上,而傳出的餅干是.傳入的 Cookie 在 (例如) 和 上具有其他元數據。ResponseCookie
String
Domain
Path
Max-Age
對于我的實現,供應商沒有指定需要返回哪些 cookie,因此我最終返回了所有這些 Cookie。因此,我修改后的代碼如下;
WebClient webClient = WebClient.create("https://remoteServer");
MultiValueMap<String, String> myCookies = new LinkedMultiValueMap<String, String>()
webClient
.post()
.uri("uri/login")
.body(Mono.just(myLoginObject), MyLogin.class)
.exchange()
.subscribe(r ->
for (String key: r.cookies().keySet()) {
myCookies.put(key, Arrays.asList(r.cookies().get(key).get(0).getValue()));
}
);
webClient
.post()
.uri("/uri/data")
.cookies(cookies -> cookies.addAll(myCookies))
.body(....)
.exchange();

TA貢獻1815條經驗 獲得超10個贊
由于已被棄用,但此線程出現在流行的搜索計算機上,因此讓我使用下面的代碼示例添加一個代碼示例以供將來參考。.exchange().exchangeToMono()
請注意,我使用一個,它將在bean發送的每個請求之前發送授權請求:ExchangeFilterFunctionwebClient
@Bean("webClient")
public WebClient webClient(ReactorResourceFactory resourceFactory,
ExchangeFilterFunction authFilter) {
var httpClient = HttpClient.create(resourceFactory.getConnectionProvider());
var clientHttpConnector = new ReactorClientHttpConnector(httpClient);
return WebClient.builder().filter(authFilter).clientConnector(clientHttpConnector)
.build();
}
@Bean("authWebClient")
public WebClient authWebClient(ReactorResourceFactory resourceFactory) {
var httpClient = HttpClient.create(resourceFactory.getConnectionProvider());
var clientHttpConnector = new ReactorClientHttpConnector(httpClient);
return WebClient.builder().clientConnector(clientHttpConnector).build();
}
@Bean
public ExchangeFilterFunction authFilter(@Qualifier("authWebClient") WebClient authWebClient,
@Value("${application.url:''}") String url,
@Value("${application.basic-auth-credentials:''}") String basicAuthCredentials) {
return (request, next) -> authWebClient.get()
.uri(url)
.header("Authorization", String.format("Basic %s", basicAuthCredentials))
.exchangeToMono(response -> next.exchange(ClientRequest.from(request)
.headers(headers -> {
headers.add("Authorization", String.format("Basic %s", basicAuthCredentials));
})
.cookies(readCookies(response))
.build()));
}
private Consumer<MultiValueMap<String, String>> readCookies(ClientResponse response) {
return cookies -> response.cookies().forEach((responseCookieName, responseCookies) ->
cookies.addAll(responseCookieName,
responseCookies.stream().map(responseCookie -> responseCookie.getValue())
.collect(Collectors.toList())));
}

TA貢獻1794條經驗 獲得超8個贊
這個答案的靈感來自@J。
.exchange不應再使用。取而代之的是一個名為 的新方法。在 Lambda 的幫助下,可以編輯和轉換響應。餅干也可以被提取。在此示例中,Cookie 顯示在控制臺中。但它們也可以毫無問題地保存。.exchangeToMono
public String getWebsiteWithCookies() {
var webClient = WebClient.create();
return webClient.post()
.uri("url")
// Your headers & so here
.exchangeToMono(response -> {
MultiValueMap<String, ResponseCookie> cookies = response.cookies();
for (var cookie : cookies.entrySet()) {
System.out.println(cookie.getKey() + " : " + cookie.getValue());
}
return response.bodyToMono(String.class);
})
.block();
}
添加回答
舉報