我可以从<过滤器映射><url-pattern>中排除一些具体的url吗?

2022-08-31 08:14:52

我希望将一些具体的过滤器应用于除一个具体网址之外的所有网址(即除)。/*/specialpath

有没有可能做到这一点?


示例代码:

<filter>
    <filter-name>SomeFilter</filter-name>
    <filter-class>org.somproject.AFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SomeFilter</filter-name>
    <url-pattern>/*</url-pattern>   <!-- the question is: how to modify this line?  -->
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

答案 1

标准的 Servlet API 不支持此工具。您可能希望为此使用重写URL过滤器,例如Tuckey的过滤器(这与Apache HTTPD非常相似),或者在过滤器侦听的方法中添加检查。mod_rewritedoFilter()/*

String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
    chain.doFilter(request, response); // Just continue chain.
} else {
    // Do your business stuff here for all paths other than /specialpath.
}

如有必要,可以将要忽略的路径指定为筛选器的 路径,以便无论如何都可以对其进行控制。您可以在过滤器中获取它,如下所示:init-paramweb.xml

private String pathToBeIgnored;

public void init(FilterConfig config) {
    pathToBeIgnored = config.getInitParameter("pathToBeIgnored");
}

如果过滤器是第三方API的一部分,因此您无法对其进行修改,则将其映射到更具体的,例如 并创建一个新过滤器,该过滤器转发到与第三方过滤器匹配的路径。url-pattern/otherfilterpath/*/*

String path = ((HttpServletRequest) request).getRequestURI();
if (path.startsWith("/specialpath/")) {
    chain.doFilter(request, response); // Just continue chain.
} else {
    request.getRequestDispatcher("/otherfilterpath" + path).forward(request, response);
}

为了避免此过滤器在无限循环中调用自身,您需要让它仅侦听(调度),仅让第三方过滤器打开。REQUESTFORWARD

另请参阅:


答案 2

我使用了 Eric Daugherty 描述的一种方法:我创建了一个特殊的 servlet,它总是用 403 代码来回答,并将其映射放在一般代码之前。

映射片段:

  <servlet>
    <servlet-name>generalServlet</servlet-name>
    <servlet-class>project.servlet.GeneralServlet</servlet-class>
  </servlet>
 <servlet>
    <servlet-name>specialServlet</servlet-name>
    <servlet-class>project.servlet.SpecialServlet</servlet-class>
 </servlet>
 <servlet-mapping>
    <servlet-name>specialServlet</servlet-name>
    <url-pattern>/resources/restricted/*</url-pattern>
 </servlet-mapping>
 <servlet-mapping>
    <servlet-name>generalServlet</servlet-name>
    <url-pattern>/resources/*</url-pattern>
 </servlet-mapping>

和 servlet 类:

public class SpecialServlet extends HttpServlet {
    public SpecialServlet() {
        super();
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.sendError(HttpServletResponse.SC_FORBIDDEN);
    }
}

推荐