我一直在尝试找到设置Webflux应用程序上下文路径的方法。我知道可以使用
server.servlet.context-path
如果我部署一个servlet,但是我想用webflux来实现它,而不必在每个路由上明确添加路径或使用MVC。我一直在尝试找到设置Webflux应用程序上下文路径的方法。我知道可以使用
server.servlet.context-path
如果我部署一个servlet,但是我想用webflux来实现它,而不必在每个路由上明确添加路径或使用MVC。spring.webflux.base-path=/your-path
你可以使用Web过滤器来使WebFlux支持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);
};
}
我也曾遇到类似的问题,与spring.webflux.base-path
有关(似乎没有按照预期工作),是在webflux-reactive-spring-web
中。后来我发现我已将自动配置禁用了。
手动解决方法如下:
@Bean
public WebFluxProperties webFluxProperties(){
return new WebFluxProperties();
}
首先,我们需要添加以下依赖项:
@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);
}
}
}
对于Undertow,我成功添加了上下文路径,方法是创建一个自定义的UndertowReactiveWebServerFactory:
@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));
}
};
}
NettyReactiveWebServerFactory
。 - Dmytro BoichenkoForwardedHeaderTransformer
,它将从X-Forwarded-Prefix
中提取路径上下文,并将其添加到ServerHttpRequest
中。context-path
(在WebFlux中没有意义)Spring webflux版本为2.3.4.RELEASE
需要两个元素,首先声明一个bean以启用weflux属性
@Bean public WebFluxProperties webFluxProperties(){
return new WebFluxProperties();
}
第二步是定义正确的路径
spring.webflux.base-path = mypath
https://github.com/spring-projects/spring-boot/issues/22162
在我的情况下,我按照以下建议逐步操作:
SpringApplication springApplication = new SpringApplication(DscUserManagementService.class); springApplication.setWebApplicationType(WebApplicationType.REACTIVE); springApplication.run(args);
谢谢wilkinsona
Base Controller.java
@RestController
@RequestMapping("/{base_url}")
public abstract class BaseController {
}
NewController.java
@RestController
public class NewController extends BaseController{
@Autowired
DatabaseClient databaseClient;
@GetMapping("/status")
public Mono<Map<String, String>> status() {
return databaseClient.execute("SELECT 'ok'").
map(row -> singletonMap("status", row.get(0, String.class)))
.one();
}
}
/actuator/health
在根级别。 - Kai Stapel@Configuration
public class NettyServerConfig {
@Value("${server.port}")
private int port;
@Value("${server.context.path}")
private String contextPath;
@Bean
public NettyReactiveWebServerFactory nettyReactiveWebServerFactory() {
NettyReactiveWebServerFactory webServerFactory = new NettyReactiveWebServerFactory() {
@Override
public WebServer getWebServer(HttpHandler httpHandler) {
Map<String, HttpHandler> handlerMap = new HashMap<>();
handlerMap.put(contextPath, httpHandler);
return super.getWebServer(new ContextPathCompositeHandler(handlerMap));
}
};
webServerFactory.addServerCustomizers(portCustomizer());
return webServerFactory;
}
public NettyServerCustomizer portCustomizer() {
return new NettyServerCustomizer() {
@Override
public HttpServer apply(HttpServer httpServer) {
return httpServer.port(port);
}
};
}
}