我可以从<filter-mapping>中的<url-pattern>中排除一些具体的URL吗?

Rom*_*man 121 java servlets servlet-filters

我想要一些混凝土过滤器应用于除一个混凝土之外的所有网址(即/*除了/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>
Run Code Online (Sandbox Code Playgroud)

Bal*_*usC 146

标准Servlet API不支持此功能.您可能希望使用重写URL过滤器,例如Tuckey的(与Apache HTTPD非常相似mod_rewrite),或者doFilter()在Filter 的方法中添加一个检查/*.

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.
}
Run Code Online (Sandbox Code Playgroud)

您可以根据需要指定要忽略的路径作为init-param过滤器的一部分,以便您可以在web.xml任何时候控制它.您可以在过滤器中获取它,如下所示:

private String pathToBeIgnored;

public void init(FilterConfig config) {
    pathToBeIgnored = config.getInitParameter("pathToBeIgnored");
}
Run Code Online (Sandbox Code Playgroud)

如果过滤器是第三方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);
}
Run Code Online (Sandbox Code Playgroud)

为避免此过滤器在无限循环中调用自身,您需要让它仅侦听(分派)并REQUEST仅启用第三方过滤器FORWARD.

也可以看看:

  • 我的问题是过滤器不是我的,它来自组件库. (3认同)
  • Ypu应该使用compnent库过滤器并对其进行扩展,以便添加要用于执行排除的代码. (3认同)

mrz*_*asa 13

我使用了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>
Run Code Online (Sandbox Code Playgroud)

和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);
    }
}
Run Code Online (Sandbox Code Playgroud)


kvi*_*tso 8

当您想要阻止某个过滤器和所有以下过滤器时,此方法有效.如果你这样做应该会很好.想要将一些内容作为servlet容器中的静态资源提供,而不是让你的应用程序逻辑(通过像GuiceFilter这样的过滤器):

将包含静态资源文件的文件夹映射到默认servlet.创建一个servlet过滤器并将其放在web.xml中的GuiceFilter 之前.在您创建的过滤器中,您可以将一些请求转发到GuiceFilter,将其他请求直接转发给调度程序.示例如下......

web.xml中

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

<filter>
    <filter-name>StaticResourceFilter</filter-name>
    <filter-class>com.project.filter.StaticResourceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>StaticResourceFilter</filter-name>
    <url-pattern>/static/*</url-pattern>
</filter-mapping>

<filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)

StaticResourceFilter.class

public class StaticResourceFilter implements Filter {

    private final static Logger LOGGER = LoggerFactory.getLogger(StaticResourceFilter.class);

    private static final String RESOURCE_PATH = "/static/";
    @Override
    public void init(final FilterConfig filterConfig) throws ServletException {
        LOGGER.info("StaticResourceFilter initialized");
    }

    @Override
    public void doFilter(final ServletRequest request, final ServletResponse response,
                         final FilterChain chain) throws IOException, ServletException {

        String path = ((HttpServletRequest) request).getServletPath();
        if (path.toLowerCase().startsWith(RESOURCE_PATH)) {
            request.getRequestDispatcher(path).forward(request, response);
        } else {
            chain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {
        LOGGER.info("StaticResourceFilter destroyed");
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,如果你只想跳过过滤器链中的一个步骤,同时保留随后的步骤,这将不起作用.