【发布时间】:2020-12-07 05:18:09
【问题描述】:
我想使用 Spring Webflux 发出 POST 请求。我试过这个:
Web 客户端构建:
public RestClient(String gatewayUrl, String token, String username, String password, SslContext sslContext) {
this.token = token;
this.gatewayUrl = gatewayUrl;
WebClient.Builder builder = WebClient.builder().baseUrl(gatewayUrl);
if (sslContext != null) {
HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
builder.clientConnector(httpConnector);
}
if (username != null && password != null) {
builder.filter(basicAuthentication(username, password));
}
client = builder.build();
}
......
public class RestClientBuilder {
private String token;
private String username;
private String password;
private URL gatewayUrl;
private SslContextBuilder sslContextBuilder;
public static RestClientBuilder builder() {
return new RestClientBuilder();
}
public RestClientBuilder token(String token) {
this.token = validateAndTrim(token, "Token");
return this;
}
public RestClientBuilder usernamePassword(String username, String password) {
this.username = validateAndTrim(username, "Username");
this.password = validateAndTrim(password, "Password");
return this;
}
private String validateAndTrim(String value, final String parameter) {
if (value == null || value.trim().isEmpty()) {
throw new IllegalArgumentException(parameter + " is empty");
}
return value.trim();
}
public RestClientBuilder gatewayUrl(String gatewayUrl) {
String urlSt = validateAndTrim(gatewayUrl, "Gateway URL");
try {
this.gatewayUrl = new URL(urlSt);
} catch (MalformedURLException e) {
throw new IllegalArgumentException("Malformed URL: " + urlSt, e);
}
return this;
}
public RestClientBuilder truststore(File truststoreFile) {
getSslContextBuilder().trustManager(truststoreFile);
return this;
}
public RestClientBuilder sslCertificate(File keyCertChainFile, File keyFile, String keyPassword) {
getSslContextBuilder().keyManager(keyCertChainFile, keyFile, keyPassword);
return this;
}
public RestClient build() throws SSLException {
SslContext sslContext = sslContextBuilder != null ? sslContextBuilder.build() : null;
return new RestClient(gatewayUrl.toString(), token, username, password, sslContext);
}
private SslContextBuilder getSslContextBuilder() {
if (sslContextBuilder == null) {
sslContextBuilder = SslContextBuilder.forClient();
}
return sslContextBuilder;
}
}
测试成功:
client.post()
.uri("https://test.oppwa.com/v1/checkouts?entityId=1234567&amount=92.00¤cy=GBP&paymentType=DB")
.header(HttpHeaders.USER_AGENT, "Mozilla/5.0")
.header(HttpHeaders.AUTHORIZATION, "Bearer 11111111")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.retrieve()
.bodyToMono(SaleResponse.class);
请求失败:
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("entityId", "1234567");
map.add("amount", "92.00");
map.add("currency", "GBP");
map.add("paymentType", "DB");
client.post()
.uri(uriBuilder -> uriBuilder.path("https://test.oppwa.com/v1/checkouts")
.queryParams(map)
.build())
.header(HttpHeaders.USER_AGENT, "Mozilla/5.0")
.header(HttpHeaders.AUTHORIZATION, "Bearer 11111111")
.accept(MediaType.APPLICATION_JSON)
.contentType(MediaType.APPLICATION_FORM_URLENCODED)
.retrieve()
.bodyToMono(SaleResponse.class);
由于某种原因,Webflux 构造了这个值:
.WebClientResponseException$NotFound: 404 Not Found from POST https://test.oppwa.com/v1/checkoutshttps:/test.oppwa.com/v1/checkouts?entityId=1234567&amount=92.00¤cy=GBP&paymentType=DB
你知道为什么 url 链接重复了 2 次吗?我该如何解决这个问题?
【问题讨论】:
-
你从哪里得到
uriBuilder(你知道在第一个sn-p中你完全放弃了使用它的结果吗?)? -
uriBuilder 是一个 Java Lambda 表达式。
-
客户端是否设置了基本路径?
-
我犯了一个错误。帖子已更新。
-
我没有基本路径的配置。
标签: java spring spring-boot spring-webflux