从Tuckey UrlRewriteFilter迁移至Tomcat Rewrite Valve:出站规则转换求助
把Tuckey的Outbound-Rule迁移到Tomcat Rewrite机制
先说清楚:Tomcat自带的默认RewriteValve只管进来的请求URL重写,不管响应里的链接改写。要实现和Tuckey outbound-rule一样的功能(修改响应内容里的链接),得用Tomcat专门的RewriteOutboundValve。
具体配置步骤
1. 开启RewriteOutboundValve
在Tomcat的context.xml(推荐给单个应用配置,避免影响全局)或者server.xml里添加这个Valve:
<Valve className="org.apache.catalina.valves.rewrite.RewriteOutboundValve" />
如果还要处理入站请求的重写,原来的RewriteValve可以保留,两个Valve能共存使用。
2. 编写rewrite.config规则
在你应用的WEB-INF文件夹下创建rewrite.config文件,对应你提供的示例规则(将/app/**改写为/$1),规则写法如下:
RewriteCond %{OUTBOUND_URL} ^/app/(.*)$ RewriteRule ^/app/(.*)$ /$1 [L]
%{OUTBOUND_URL}是这个Valve专门用来匹配响应中URL的变量- 要是你需要的是跳转型重写(比如返回302让浏览器跳转),可以把规则改成:
RewriteCond %{OUTBOUND_URL} ^/app/(.*)$ RewriteRule ^/app/(.*)$ /$1 [R=302,L]
不想绑定Tomcat?试试应用内自定义过滤器
如果以后可能切换到其他Servlet容器(比如Jetty),不想依赖Tomcat特定组件,自己写个Filter处理也很简单:
import jakarta.servlet.*; import jakarta.servlet.http.HttpServletResponse; import java.io.CharArrayWriter; import java.io.IOException; import java.io.PrintWriter; public class OutboundUrlRewriteFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletResponse httpResponse = (HttpServletResponse) response; CharResponseWrapper wrapper = new CharResponseWrapper(httpResponse); chain.doFilter(request, wrapper); // 替换响应内容中/app开头的链接 String modifiedContent = wrapper.toString().replaceAll("/app/(\\w+)", "/$1"); httpResponse.getWriter().write(modifiedContent); } // 用于捕获响应内容的包装类 private static class CharResponseWrapper extends HttpServletResponseWrapper { private final CharArrayWriter charWriter = new CharArrayWriter(); public CharResponseWrapper(HttpServletResponse response) { super(response); } @Override public PrintWriter getWriter() { return new PrintWriter(charWriter); } @Override public String toString() { return charWriter.toString(); } } }
然后在web.xml里注册这个Filter:
<filter> <filter-name>OutboundUrlRewriteFilter</filter-name> <filter-class>com.yourpackage.OutboundUrlRewriteFilter</filter-class> </filter> <filter-mapping> <filter-name>OutboundUrlRewriteFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
或者直接用Jakarta的@WebFilter注解标注在Filter类上也可以。
注意事项
RewriteOutboundValve是Tomcat独有的组件,需要跨容器兼容的话,自定义Filter方案更合适- 修改响应内容会轻微影响性能,尤其是大页面场景,建议把匹配规则写精准,避免无意义的全局替换
内容的提问来源于stack exchange,提问作者Nikola Dinev
相关产品推荐
相关产品推荐

