I have a @RestController
that uses WebClient
in one of its endpoints to invoke another endpoint from the same controller:
@RestController
@RequestMapping("/api")
@RequiredArgsConstructor
public class FooRestController {
private final WebClient webClient;
@Value("${service.base-url}")
private String fooServiceBaseUrl;
@GetMapping(value = "/v1/foo", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Foo> getFoo() {
return webClient.get().uri(fooServiceBaseUrl + "/api/v1/fooAnother")
.retrieve()
.bodyToFlux(Foo.class);
}
@GetMapping(value = "/v1/fooAnother", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Foo> getFooAnother() {
return Flux.xxx
}
In my @WebFluxTests
class I can test the fooAnother
endpoint without any problem:
@ExtendWith(SpringExtension.class)
@Import({MyWebClientAutoConfiguration.class})
@WebFluxTest(FooRestController.class)
class FooRestControllerTest {
@Test
void shouldGetFooAnother() {
xxx
webTestClient.get()
.uri("/api/v1/fooAnother")
.exchange()
.expectStatus().isOk()
}
@Test
void shouldGetFoo() {
xxx
webTestClient.get()
.uri("/api/v1/fooAnother")
.exchange()
.expectStatus().isOk()
}
However when I test the /v1/foo
endpoint (notice in my tests service.base-url
=""), it fails calling webClient.get().uri(fooServiceBaseUrl + "/api/v1/fooAnother")
having fooServiceBaseUrl + "/api/v1/fooAnother"
= "/api/v1/fooAnother"
, complaining that it need an absolute URL: java.lang.IllegalArgumentException: URI is not absolute: /api/v1/fooAnother
.
How could I fix this test?
You have to configure your WebClient
using WebClient.Builder()
. You could do this inside your FooRestController
but I like to use Configuration
that way if you have any further WebClient customizations, you could do in different class rather than in your controller class.
Configure WebClient:
@Configuration
public class WebClientConfig() {
@Value("${service.base-url}")
private String fooServiceBaseUrl;
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder
.baseUrl(fooServiceBaseUrl)
.build();
}
}
If you decide to go ahead with configuring your webClient in your FooRestController
, you have to refactor as below. You don't need above configuration.
If this doesn't solve your issue, you might have some sort of mismatch between application.yml
file and the value that your are trying to inject in fooServiceBaseUrl
.
@RestController
@RequestMapping("/api")
public class FooRestController() {
private final WebClient webClient;
@Value("${service.base-url}")
private String fooServiceBaseUrl;
public FooRestController(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder
.baseUrl(fooServiceBaseUrl)
.build();
}
@GetMapping(value = "/v1/foo", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Foo> getFoo() {
return webClient
.get()
.uri("/api/v1/fooAnother")
.retrieve()
.bodyToFlux(Foo.class);
}
@GetMapping(value = "/v1/fooAnother", produces = MediaType.APPLICATION_JSON_VALUE)
public Flux<Foo> getFooAnother() {
return Flux.xxx
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.