J'ai essayé de trouver un moyen de définir le chemin de contexte pour une application webflux. Je sais que je peux le configurer en utilisant
server.servlet.context-path
si je déploie un servlet, mais que je voudrais le réaliser avec webflux, sans avoir à ajouter explicitement le chemin d'accès à chaque route ni à utiliser MVC.
Vous pouvez utiliser un filtre Web pour rendre WebFlux compatible avec contextPath
@Bean
public WebFilter contextPathWebFilter() {
String contextPath = serverProperties.getServlet().getContextPath();
return (exchange, chain) -> {
ServerHttpRequest request = exchange.getRequest();
if (request.getURI().getPath().startsWith(contextPath)) {
return chain.filter(
exchange.mutate()
.request(request.mutate().contextPath(contextPath).build())
.build());
}
return chain.filter(exchange);
};
}
Pour Undertow, j’ai réussi à ajouter un chemin de contexte en créant un UndertowReactiveWebServerFactory personnalisé:
@Bean
public UndertowReactiveWebServerFactory undertowReactiveWebServerFactory(
@Value("${server.servlet.context-path}") String contextPath) {
return new UndertowReactiveWebServerFactory() {
@Override
public WebServer getWebServer(HttpHandler httpHandler) {
Map<String, HttpHandler> handlerMap = new HashMap<>();
handlerMap.put(contextPath, httpHandler);
return super.getWebServer(new ContextPathCompositeHandler(handlerMap));
}
};
}
Voici comment procéder avec Tomcat Reactive:
@Configuration
public class TomcatReactiveWebServerConfig extends TomcatReactiveWebServerFactory {
@Value("${server.servlet.context-path}")
private String contextPath;
/**
* {@inheritDoc}
*/
@Override
protected void configureContext(final Context context) {
super.configureContext(context);
if (StringUtils.isNotBlank(this.contextPath)) {
context.setPath(this.contextPath);
}
}
}
Pour les cas d'utilisation où l'application WebFlux se trouve derrière l'équilibreur de charge/proxy, vous pouvez utiliser la classe dédiée - ForwardedHeaderTransformer
qui extraira le contexte de chemin à partir de X-Forwarded-Prefix
et l'ajoutera à ServerHttpRequest
.
Cela vous évitera de modifier le context-path
global (ce qui n’a aucun sens dans WebFlux)
Plus d'informations ici: https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#webflux-web-handler-api
Si vous configurez vous-même le serveur (si vous n’utilisez pas Spring Boot), vous pouvez configurer un ContextPathCompositeHandler qui encapsule lui-même plusieurs gestionnaires.
Si vous utilisez Spring Boot, cette fonctionnalité n'est actuellement pas prise en charge.
J'avais le même problème depuis que l'équilibreur du chargeur se base sur le chemin du contexte pour acheminer vers différentes applications principales. Une façon de contourner Spring Boot Webflux avec le chemin de contexte consiste à utiliser des variables dans les annotations @XXXXMapping. Par exemple, @RequestMapping (value = "$ {server.servlet.context-path}/subpath")