Tomcat基于URL参数的多应用请求路由实现(默认路由至Foo应用)
路由实现方案
这套方案不需要改造现有Foo、Bar两个应用的业务代码,完全依托Tomcat原生能力实现,完全匹配需求规则:
- 所有入站请求默认路由到Foo应用处理
- 检测到请求携带
param=42参数时,在服务端内部将请求转发到Bar应用的对应端点,保留全部原始请求参数 - 所有未触发转发规则的请求,完全走Foo应用原有处理链路,无任何改动
基础部署准备
保持原有两个war包的部署逻辑不变:
foo.war部署后上下文路径为/foo,内置GET /test端点,无参数访问时返回Hello Worldbar.war部署后上下文路径为/bar,内置GET /test端点,访问时返回Hello Universe- 不修改两个war包内部的业务代码,所有路由判断逻辑放在Tomcat全局层实现
核心路由逻辑实现
在Tomcat全局层面注册优先级最高的请求Filter,处理链路在请求到达业务应用之前先执行路由判断:
- 解析入站请求的全部查询参数,判断是否存在
param参数且取值严格等于42 - 匹配到转发规则时,将请求的内部路径从
/foo开头改写为/bar开头,保留所有原始查询参数,通过Servlet原生的RequestDispatcher完成服务端内部转发,不产生客户端跳转,也不增加额外网络开销 - 未匹配到转发规则时,直接将请求透传到原路径的Foo应用处理,不做任何路径、参数修改
核心判断代码片段:
// 读取请求参数判断是否触发转发 String paramValue = request.getParameter("param"); if ("42".equals(paramValue)) { String originalUri = request.getRequestURI(); // 替换上下文路径完成转发目标改写 String forwardTarget = originalUri.replace("/foo", "/bar"); // 服务端内部转发,传递原始请求和响应对象 request.getRequestDispatcher(forwardTarget).forward(request, response); return; } // 不触发规则直接透传到原有应用 chain.doFilter(request, response);
部署注意事项
- 该Filter不要配置在单个Web应用的
web.xml中,要配置到Tomcat全局conf/web.xml文件,或者将Filter实现类打成jar包放到Tomcat的lib目录下,保证判断逻辑在所有业务应用处理之前执行 - 服务端内部转发不会改变客户端浏览器的地址栏,用户访问
foo/test?param=42时,地址栏保持不变,实际拿到的是Bar应用返回的Hello Universe结果;同时因为传递了原始request对象,Bar应用的接口可以正常读取到原请求携带的全部查询参数,和直接访问bar/test?param=42的调用效果完全一致 - 匹配参数时要做严格等值判断,不要做模糊匹配,避免
param=420、param=142这类非目标请求被误转发到Bar应用 - 不需要额外引入反向代理组件,所有转发逻辑在Tomcat进程内部完成,无跨域、跨网络的额外性能开销
内容的提问来源于stack exchange,提问作者Optio
相关产品推荐
相关产品推荐

