我真的很喜欢RestTemplate
所提供的解决方案,但很快它将在将来的春季版本中贬值。我正在尝试使用WebClient
String text = URLEncoder.encode(text,"UTF-8");
WebClient webClient = WebClient.builder()
.baseUrl(BASE_URL)
.defaultHeader("Key","af999-e99-4456-b556-4ef9947383d")
.defaultHeader("src", srcLang)
.defaultHeader("tgt", tgtLang)
.defaultHeader("text", text)
.build();
然后在此处发送帖子:
Mono<String> response = webClient.post().uri("/google/rtv/text")
.retrieve()
.bodyToMono(String.class);
尝试根据旧版响应进行解析:
private String parseJson( Mono<String> response) {
ObjectMapper mapper = new ObjectMapper();
JsonNode root = null;
JsonNode review = null;
//TODO: create an object and map it here. We need to save the original review too.
try {
root = mapper.readTree(response.toString());
review = root.path("message");
} catch (IOException e) {
e.printStackTrace();
}
return review.asText();
}
稍后我需要解析响应,但是现在我收到一条错误消息:
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'MonoFlatMap': was expecting ('true', 'false' or 'null')
at [Source: (String)"MonoFlatMap"; line: 1, column: 23]
及更高版本:
java.lang.NullPointerException: null
我要完成的工作类似于我对RestTemplate
所做的事情。
像这样:
UriComponentsBuilder builder = UriComponentsBuilder
.fromUriString(URL)
.queryParam("src", src)
.queryParam("tgt", tgt)
.queryParam("text", text);
ResponseEntity<String> response = restTemplate.exchange(builder.toUriString(), HttpMethod.GET, request, String.class);
然后在全局设置我的订阅标题。
private ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
request.getHeaders().add("Key","af999-e99-4456-b556-4ef9947383d");
ClientHttpResponse response = execution.execute(request, body);
return response;
}
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = new RestTemplate();
restTemplate.setInterceptors(Collections.singletonList(this::intercept));
return restTemplate;
}
建议?
答案 0 :(得分:1)
问题发生在这里:
root = mapper.readTree(response.toString());
当Mono<String>
是一种可以最终提供该Mono
值的响应类型时,此代码段试图将String
序列化为字符串。
您可以调用response.block()
并得到结果String
,但这将是阻塞调用,并且Reactor禁止在执行响应过程中这样做。这样做有充分的理由,因为这将阻止您的Web应用程序正在使用的几个线程之一,并可能导致它停止处理其他请求。
您可以改成类似以下内容:
Mono<String> review = response.map(r -> parseJson(r);
然后重新使用该新值。
请注意,WebClient
本机支持JSON反序列化,您可以像这样反序列化整个有效负载:
Mono<Review> review = webClient.post().uri("/google/rtv/text")
.retrieve()
.bodyToMono(Review.class);