Hello, Can you tell me how to call another micro-service on a GatewayFilterFactory?
I want to call the authentication micro-service when a request come from user.
1st, I tried to use feign client. but I can not get the ServletRequestAttribute on the RequestInterceptor because spring cloud gateway use webflux instead of web.
Here is the code :
````java
public class FeignAuthRequestInterceptor implements RequestInterceptor {
private final Logger logger = LoggerFactory.getLogger(FeignAuthRequestInterceptor.class);
private static final String HEADER_TOKEN = "token";
private static final String HEADER_USERNAME = "username";
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
//TODO the attribute is always null so I can not get the original request header
logger.warn("the request attribute is {}", attributes);
Map
if (requestTemplate.queries().get(HEADER_TOKEN) != null) {
requestTemplate.header(HEADER_TOKEN, queries.get(HEADER_TOKEN).iterator().next());
}
if (requestTemplate.queries().get(HEADER_USERNAME) != null) {
requestTemplate.header(HEADER_USERNAME, queries.get(HEADER_USERNAME).iterator().next());
}
requestTemplate.queries(queries);
/*
HttpServletRequest request = attributes.getRequest();
Enumeration
if (headerNames != null) {
while (headerNames.hasMoreElements()) {
String name = headerNames.nextElement();
String values = request.getHeader(name);
requestTemplate.header(name, values);
}
}
*
}
}
````
Then I tried to use webClient of spring5 to make a request to the authentication micro-service but I can not get the response
java
Mono<ResponseResult> res = webClient.post().uri(auth.getAuthUri())
.headers((httpHeaders -> httpHeaders.putAll(exchange.getRequest().getHeaders())))
.contentType(MediaType.APPLICATION_JSON_UTF8)
.body(BodyInserters.fromObject(JSONObject.toJSONString(params)))
.accept(MediaType.APPLICATION_JSON_UTF8)
.retrieve()
// .bodyToMono(ResponseResult.class);
.bodyToMono(ResponseResult.class)
;
When I use the
java
res.block();
method to get the response , there is an exception
shell
block()/blockFirst()/blockLast() are blocking, which is not supported in thread reactor-http-nio-2"
So. I want to know how to call another micro-service on spring cloud gateway environment.
Thanks a lot.
best wishes.
Feign is not going to work as it is not reactive.
This is also why you cannot call .block.
Unfortunately it is hard to say what is wrong without a way to reproduce the problem. Using WebClient should be fine.
Feign is not going to work as it is not reactive.
This is also why you cannot call
.block.Unfortunately it is hard to say what is wrong without a way to reproduce the problem. Using
WebClientshould be fine.
I tried to use WebClient 锛孊ut I do not know how to get the response from webclient call. Usually, .block() works. But it does not work well in webflux environment. So would you mind tell me how to get the response when using WebClient ? Thanks a lot .
Best wishes to you .
@ryanjbaxter
Thanks a lot.
I take a cursory look. But I am sorry, I don't think that's what I need. I deployed an authentication service used shiro in another project. So I need a way to call that. I want to use WebClient as @ryanjbaxter said . But I can not get the webclient response without .block method .
Sorry for the inconvenience.
Take more than a cursory look. The class in the filter could be replaced with webclient. In fact I think if you dig into it, it uses web client.
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-webclient.html
Thanks .
And Thank you for your contribution to spring cloud development.
hello spencergibb,
I can not find the source code about the ServerOAuth2AuthorizedClientRepository class.
But it doesn't really matter. This issue isn't to provide a lesson on reactive programming with reactor.
And
@vxray
I have the same problem as you
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
WebClient.create().post().uri("http://127.0.0.1:9001/user/query").retrieve().bodyToMono
(String.class).flatMap(s -> {
System.out.println(s);
return Mono.just(s);
});
return chain.filter(exchange);
});
how to get WebClient response
the webclient all returns a Mono and needs to be part of the filter chain. So instead of return Mono.just(s).
@Override
public GatewayFilter apply(Config config) {
return ((exchange, chain) -> {
return WebClient.create().post().uri("http://127.0.0.1:9001/user/query").retrieve().bodyToMono
(String.class).flatMap(s -> {
System.out.println(s);
return chain.filter(exchange);
});
});
Most helpful comment
the webclient all returns a Mono and needs to be part of the filter chain. So instead of
return Mono.just(s).