Cómo enviar una porción de las solicitudes a otra URL
Tengo un servicio web que maneja las solicitudes HTTP GET/POST/PUT utilizando un controlador Spring Rest (usando Netty en lugar de Apache Tomcat). Deseo filtrar todas las solicitudes que llegan a mi servicio, y cuando una solicitud tiene una cierta cabecera configurada, quiero enviar esta solicitud específica a una URL completamente diferente, al mismo tiempo que devuelvo la respuesta a la misma entidad que envió la solicitud original.
Aquí está mi código:
@Component
public class MyWebFilter implements WebFilter {
@Autowired
private SomeService someService;
private final Logger log = LoggerFactory.getLogger(MyWebFilter.class);
@Override
public Mono<void> filter(ServerWebExchange serverWebExchange, WebFilterChain webFilterChain) {
HttpHeaders headers = serverWebExchange.getRequest().getHeaders();
if (headers.containsKey("someHeader")) {
if (someService.askSomething(Objects.requireNonNull(headers.get("someHeader")))) {
URI originalUri = serverWebExchange.getRequest().getURI();
log.info("Redirigiendo solicitud con URI {} a algún servicio", originalUri.getPath());
try {
URI someUri = new URI("http",
originalUri.getUserInfo(),
someService.getHost(),
someService.getPort(),
originalUri.getPath(),
originalUri.getQuery(),
originalUri.getFragment());
ServerHttpRequest newRequest = serverWebExchange.getRequest().mutate().uri(someUri).build();
ServerWebExchange newExchange = serverWebExchange.mutate().request(newRequest).build();
return webFilterChain.filter(newExchange);
} catch (URISyntaxException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
}
return webFilterChain.filter(serverWebExchange);
}
}
Con esta implementación, la solicitud simplemente se pasa al controlador rest normal y no llega al otro servicio. ¿Qué me falta aquí?
davy.ai
Basándose en el código proporcionado, parece que el filtro está interceptando correctamente las solicitudes y comprobando si contienen el encabezado especificado. Si el encabezado está presente y cumple la condición de
someService.askSomething()
, entonces el código crea una nueva URI y una nueva solicitud utilizandoserverWebExchange.getRequest().mutate().uri(someUri).build()
y la pasa alwebFilterChain
para continuar el procesamiento.Sin embargo, no está claro dónde exactamente se envía la solicitud a la nueva URI. El código solo está creando una nueva solicitud, pero parece que está pasando la solicitud al
webFilterChain
sin enviarla realmente a la nueva URI.Para enviar la solicitud a la nueva URI, es necesario usar un cliente para hacer una nueva solicitud a la nueva URI con los encabezados y cuerpo de la solicitud modificados, y luego devolver la respuesta a la entidad de solicitud original. Puede utilizar
Netty WebClient
para hacer una nueva solicitud.Aquí hay una implementación actualizada que utiliza
Netty WebClient
para manejar la solicitud y respuesta:En esta implementación, se utiliza
Netty WebClient
para crear una nueva solicitud con la URI y los encabezados modificados, y el cuerpo de la solicitud original. Luego, se utiliza elClientResponse
resultante para escribir la respuesta de vuelta alServerWebExchange
original.