如何使 WebFilter 在非 WebFlux/非反应式 Spring Boot 应用程序中工作?
Posted
技术标签:
【中文标题】如何使 WebFilter 在非 WebFlux/非反应式 Spring Boot 应用程序中工作?【英文标题】:How to make WebFilter work in a non-WebFlux/non-reactive Spring Boot application? 【发布时间】:2020-12-23 14:59:32 【问题描述】:我正在尝试解决这个问题:How to rewrite URLs with Spring (Boot) via REST Controllers? 通过创建某种“过滤器”,该过滤器将应用于每个传入的 HTTP 请求。
这个问题的一些答案涵盖了这个问题:Spring Boot Adding Http Request Interceptors
但是接口HandlerInterceptor
处理javax'HttpServletRequest
和HttpServletResponse
,它们不如Spring 引入的新类,即ServerWebExchange
(参见下面代码中setLocation()
的使用)实用,它出现在名字听起来很有希望的界面,org.springframework.web.server.WebFilter
:
所以我以这样的方式结束:
@Component
public class LegacyRestRedirectWebFilter implements WebFilter
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain)
URI origin = exchange.getRequest().getURI();
String path = origin.getPath();
if (path.startsWith("/api/"))
ServerHttpResponse response = exchange.getResponse();
response.setStatusCode(HttpStatus.MOVED_PERMANENTLY);
URI location = UriComponentsBuilder.fromUri(origin).replacePath(path.replaceFirst("/api/", "/rest/")).build().toUri();
response.getHeaders().setLocation(location);
return chain.filter(exchange);
...以同样的方式人们正在做类似的事情:
Spring WebFlux add WebFIlter to match specific paths WebFilter in WebFlux application唉,我的过滤器永远不会被调用!!!
问题是:我不在“WebFlux”上下文中(与上述问题相反),因为:
-
我不需要,而且
我尝试了以下问题:
Reactive Webfilter is not working when we have spring-boot-starter-web dependency in classpath(但没有明确的答案);标记重复: Don't spring-boot-starter-web and spring-boot-starter-webflux work together?
Spring WebFlux with traditional Web Security(我的pom.xml
中有一个“传统”spring-boot-starter-security
依赖项加上一个扩展WebSecurityConfigurerAdapter
的@Configuration
类 - 但不愿意将其迁移到...顺便说一句?)
我也不明白为什么我需要在 WebFlux 上下文中,因为 org.springframework.web.server.WebFilter
既不处理 reactive
也不处理 Webflux
,对吧? ..或者是吗?这在 Javadoc 中不是很清楚。
【问题讨论】:
您的应用程序要么是 Web 应用程序,要么是 webflux 应用程序。不能两者兼有,webfilter 是 webflux 的一部分,因此如果您的应用程序是 webflux 应用程序,它将被加载和使用。如果您的类路径中同时具有 web 和 webflux,则默认情况下,spring boot 将作为 Web 应用程序启动,并且您应该使用Filter
baeldung.com/spring-boot-add-filter 而无需查看您的 pom.xml/gradle,它很难知道您拥有哪种类型的应用程序。
WebFilter 位于spring-web-5.1.9.RELEASE.jar
,如何成为“WebFlux”的一部分?!
顺便说一句,当您在我的另一个问题上请求 pom.xml 时,我将其发布在这里:***.com/questions/63737318/…
...也感谢您将我指向这个(简单)Filter
,但经过快速搜索(尽管 Baeldung 没有指定它是哪个过滤器...)我发现这是@ 987654347@,正如我上面所说,我会尽量避免使用它,因为它是纯“javax”代码,它处理 (Http)ServletRequest/(Http)ServletResponse,[参见 RequestResponseLoggingFilter
中的转换]。跨度>
好吧,因为我还没有看到你的 pom.xml(直到现在),许多人将 webflux 添加到他们的 spring-web 应用程序中以仅使用 WebClient
。因此默认情况下,另一方面,您希望使用WebFilter
,因为您想构建一个 webflux 应用程序。而你的问题是你正在引入不支持 webflux (springfox v2.9.2) 的东西,所以 springfox 可能会强制你的应用程序作为 web 应用程序启动。
【参考方案1】:
事实上,我没有找到让WebFilter
在非WebFlux 上下文中工作的方法,但我可以成功实现这样的过滤器,它既实现了javax.servlet.Filter
(非反应式)又实现了org.springframework.web.server.WebFilter
(反应性)。
这是我对另一个相关问题的回答:https://***.com/a/63780659/666414
【讨论】:
以上是关于如何使 WebFilter 在非 WebFlux/非反应式 Spring Boot 应用程序中工作?的主要内容,如果未能解决你的问题,请参考以下文章
Spring WebFlux添加WebFIlter以匹配特定路径