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();
}
添加回答
举报