目前,我的 post 和 get 请求是通过 WebClients 处理的,WebClients 在 Spring Boot 中具有公共连接和读取超时。我有 5 个不同的类,每个类都需要自己的一组连接和读取超时。我不想创建 5 个不同的 WebClient,而是使用相同的 Webclient,但在从特定类发送 post 或 get 请求时,指定所需的连接和读取超时。有没有办法实现这个?
我当前的网络客户端:
@Bean
public WebClient getWebClient(WebClient.Builder builder){
HttpClient httpClient = HttpClient.newConnection()
.tcpConfiguration(tcpClient -> {
tcpClient = tcpClient.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectionTimeout*1000);
tcpClient = tcpClient.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(readTimeout, TimeUnit.SECONDS)));
return tcpClient;
}).wiretap(true);
ClientHttpConnector connector = new ReactorClientHttpConnector(httpClient);
return builder.clientConnector(connector).build();
}
Run Code Online (Sandbox Code Playgroud)
我正在使用的帖子请求:
public WebClientResponse httpPost(String endpoint, String requestData, Map<String, Object> requestHeader) {
ClientResponse res = webClient.post().uri(endpoint)
.body(BodyInserters.fromObject(requestData))
.headers(x -> {
if(requestHeader != null && …Run Code Online (Sandbox Code Playgroud) 参考:org.springframework.web.util.UriBuilder
我正在用来UriBuilder为端点构建 URI
final String response = myWebClient.get()
.uri(uriBuilder -> uriBuilder.scheme("https").path("example.com/mypage").path("/{id}.xml").build(id))
.header(AUTHORIZATION, getAuthorizationHeaderValue(username, password))
.accept(MediaType.TEXT_XML)
.retrieve()
.bodyToMono(String.class)
.block();
Run Code Online (Sandbox Code Playgroud)
但是,我已经在字符串变量中获得了值https://example.com/mypage(从数据库中获取)。我可以直接使用这个字符串而不是单独指定方案和路径/主机吗?现在我正在手动将主字符串分成单独的部分。
我有一个控制器,用于RestTemplate从多个休息端点获取数据。由于RestTemplate阻塞,我的网页需要很长时间才能加载。为了提高性能,我计划将所有用法替换RestTemplate为WebClient. 我目前使用的方法之一RestTemplate如下。
public List<MyObject> getMyObject(String input){
URI uri = UriComponentsBuilder.fromUriString("/someurl")
.path("123456")
.build()
.toUri();
RequestEntity<?> request = RequestEntity.get(uri).build();
ParameterizedTypeReference<List<MyObject>> responseType = new ParameterizedTypeReference<List<MyObject>>() {};
ResponseEntity<List<MyObject>> responseEntity = restTemplate.exchange(request, responseType);
MyObject obj = responseEntity.getBody();
}
Run Code Online (Sandbox Code Playgroud)
现在我想替换上面的方法来使用,WebClient但我是新手WebClient,不知道从哪里开始。任何指导和帮助表示赞赏。
我有两种 Webflux 应用程序,基于注释和基于路由。这些应用程序使用一组标头进行调用,其中一些(开放跟踪)我需要使用WebClient.
如果这些都是正常的春天WebMvc应用我会用一个过滤器,以保持选定的标题中ThreadLocal,访问它的RestTemplate拦截器将它们发送到后续服务和清除ThreadLocal。
在 WebFlux 应用程序中复制这种行为的正确方法是什么?
我不明白反应式 webclient 的工作原理。它说spring webclient是非阻塞客户端,但是这个webclient似乎在等待来自远程api的onComplete()信号,然后它可以处理从远程api发出的每个项目。我期望当 onNext() 从目标 api 被触发时,webclient 可以处理每个项目
我是春季 webflux 世界的新手。我读到它,它说它使用 netty 作为默认服务器。而这个 netty 使用 eventloop。所以为了理解它是如何工作的,我尝试创建 2 个小应用程序,客户端和服务器。服务器应用程序只返回简单的通量,每个项目延迟 1 秒。客户端应用程序使用 webclient 调用远程 api。
服务器:
@GetMapping(ITEM_END_POINT_V1)
public Flux<Item> getAllItems(){
return Flux.just(new Item(null, "Samsung TV", 399.99),
new Item(null, "LG TV", 329.99),
new Item(null, "Apple Watch", 349.99),
new Item("ABC", "Beats HeadPhones",
149.99)).delayElements(Duration.ofSeconds(1)).log("Item : ");
}
Run Code Online (Sandbox Code Playgroud)
客户:
WebClient webClient = WebClient.create("http://localhost:8080");
@GetMapping("/client/retrieve")
public Flux<Item> getAllItemsUsingRetrieve() {
return webClient.get().uri("/v1/items")
.retrieve()
.bodyToFlux(Item.class).log();
}
Run Code Online (Sandbox Code Playgroud)
从服务器登录:
2019-05-01 22:44:20.121 INFO 19644 --- [ctor-http-nio-2] Item : : onSubscribe(FluxConcatMap.ConcatMapImmediate)
2019-05-01 …Run Code Online (Sandbox Code Playgroud) 我正在升级我的服务并使用 oAuth2 实现 webclient,我得到的异常是“tokenType 不能为空”,请您帮我解决这个问题。
异常:org.springframework.security.oauth2.core.OAuth2AuthorizationException:[invalid_token_response] 尝试检索 OAuth 2.0 访问令牌响应时出错:提取类型 [class org.springframework.security.oauth2.core.endpoint 的响应时出错.OAuth2AccessTokenResponse] 和内容类型 [application/json];嵌套异常是 org.springframework.http.converter.HttpMessageNotReadableException:读取 OAuth 2.0 访问令牌时发生错误响应:tokenType 不能为空;嵌套异常是 java.lang.IllegalArgumentException: tokenType 不能为 null
Spring 文档说明我们必须从 RestTemplate 切换到WebClient即使我们想要执行同步 http 调用。
现在我有以下代码:
Mono<ResponseEntity<PdResponseDto>> responseEntityMono = webClient.post()
.bodyValue(myDto)
.retrieve()
.toEntity(MyDto.class);
responseEntityMono.subscribe(resp -> log.info("Response is {}", resp));
//I have to return response here
// return resp;
Run Code Online (Sandbox Code Playgroud)
当然我可以在这里使用 CountdownLatch 但它看起来像 API 滥用。
我怎么能执行同步请求?
我正在使用 Spring WebFlux 接受请求并使用相同的请求来调用另一个服务。但我不确定如何添加查询参数。这是我的代码
@RequestMapping(value= ["/ptta-service/**"])
suspend fun executeService(request: ServerHttpRequest): ServerHttpResponse {
val requestedPath = if (request.path.toString().length > 13) "" else request.path.toString().substring(13)
return WebClient.create(this.dataServiceUrl)
.method(request.method ?: HttpMethod.GET)
.uri(requestedPath)
.header("Accept", "application/json, text/plain, */*")
.body(BodyInserters.fromValue(request.body))
.retrieve()
.awaitBody()
// But how about query parameters??? How to add those
}
Run Code Online (Sandbox Code Playgroud)
尽管代码在 Kotlin 中,但 Java 也会有所帮助。
我有很多方法使用 Spring 的 WebClient 中的 onStatus API:
@Override
public Mono<Accommodation> createAccommodation(CreateAccommodation create) {
return webClient
.post()
.contentType(APPLICATION_JSON)
.bodyValue(create)
.retrieve()
.onStatus(HttpStatus::isError,
clientResponse -> clientResponse
.bodyToMono(ApiErrorResponse.class)
.flatMap(errorResponse -> Mono.error(new ResponseStatusException(
HttpStatus.valueOf(errorResponse.getStatus()),
errorResponse.getMessage()
))))
.bodyToMono(Accommodation.class);
}
Run Code Online (Sandbox Code Playgroud)
我想做的是避免在每个 WebClient 调用中都使用“onStatus”。
在构建 WebClient 实例时有没有办法设置它?你能举一些例子吗?
这是我的 WebClient 实例:
public AccommodationServiceClientImpl(WebClient.Builder builder) {
this.webClient = builder
.baseUrl("lb://accommodation-service/api/v1/accommodations")
.build();
}
Run Code Online (Sandbox Code Playgroud) 我对能够发出 HTTP 请求的需求非常有限。我看到 WebClient 是 RestTemplate 的新替代品。但是好像不能用WebClient,不拖整个spring boot;这不是我想做的。有没有办法在没有 Spring Boot 的情况下使用 WebClient?
spring-webclient ×10
java ×6
spring ×5
spring-boot ×4
kotlin ×1
opentracing ×1
resttemplate ×1
uri ×1
uribuilder ×1