Struts1中如何像Struts2的excludePattern那样排除路径以使用WebService?
嘿,这个问题我太熟悉了!Struts1确实没有Struts2那种开箱即用的excludePattern配置,但咱们有几个实用的办法能让WebService请求绕过Struts的拦截,顺利被处理。
方案1:调整Struts ActionServlet的映射范围(最简单)
Struts默认的ActionServlet映射通常是/*,这会拦截所有请求。你可以把它改成后缀匹配(比如*.do),这样只有以.do结尾的请求才会被Struts处理,WebService的路径(比如/services/*)就会直接交给对应的WebService处理器。
修改web.xml里的ActionServlet配置:
<servlet> <servlet-name>action</servlet-name> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class> <!-- 保留原有的初始化参数 --> </servlet> <servlet-mapping> <servlet-name>action</servlet-name> <!-- 把原来的/*改成*.do --> <url-pattern>*.do</url-pattern> </servlet-mapping>
同时确保你的WebService Servlet(比如Axis的AxisServlet或者CXF的CXFServlet)已经配置了对应的路径映射,比如:
<servlet> <servlet-name>AxisServlet</servlet-name> <servlet-class>org.apache.axis.transport.http.AxisServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AxisServlet</servlet-name> <url-pattern>/services/*</url-pattern> </servlet-mapping>
这样所有/services/开头的请求都会直接被WebService Servlet处理,完全不会经过Struts。
方案2:利用Servlet匹配优先级(无需改Struts映射)
如果你不想改动Struts现有的/*映射,也可以利用Servlet容器的匹配优先级规则:精确匹配 > 路径匹配 > 扩展名匹配 > 默认匹配。
只要给WebService Servlet配置更具体的路径映射(比如/services/*),而Struts用/*,容器会优先把符合/services/*的请求交给WebService Servlet,不会落到Struts的ActionServlet手里。
这个方案不需要修改Struts的任何配置,只要确保WebService Servlet的映射路径足够具体就行,非常适合不想动现有Struts配置的场景。
方案3:自定义ActionServlet子类(灵活控制排除规则)
如果上面两种方案都不满足你的需求(比如需要更复杂的排除规则),可以自定义一个ActionServlet的子类,重写doGet/doPost方法,在里面判断请求路径,符合排除条件的就直接跳过Struts的处理,交给对应的处理器。
示例代码:
public class CustomActionServlet extends ActionServlet { // 定义需要排除的路径集合,可根据需求修改 private static final Set<String> EXCLUDE_PATHS = new HashSet<>(Arrays.asList("/services/", "/ws/")); @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String requestUri = request.getRequestURI(); // 检查请求路径是否包含需要排除的前缀 boolean shouldExclude = EXCLUDE_PATHS.stream().anyMatch(requestUri::contains); if (shouldExclude) { // 交给容器处理,直接转发到对应的Servlet getServletContext().getRequestDispatcher(requestUri).forward(request, response); return; } // 否则走正常的Struts流程 super.doGet(request, response); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 和doGet逻辑保持一致 String requestUri = request.getRequestURI(); boolean shouldExclude = EXCLUDE_PATHS.stream().anyMatch(requestUri::contains); if (shouldExclude) { getServletContext().getRequestDispatcher(requestUri).forward(request, response); return; } super.doPost(request, response); } }
然后修改web.xml里的ActionServlet类为自定义的类:
<servlet> <servlet-name>action</servlet-name> <servlet-class>com.yourpackage.CustomActionServlet</servlet-class> <!-- 保留原有的初始化参数 --> </servlet>
这个方案可以让你灵活定义各种排除规则,比如多个路径、正则匹配等,适合复杂场景。
内容的提问来源于stack exchange,提问作者darrey

