【问题标题】:Is it possible for a servlet filter to work out which servlet will handle the requestservlet 过滤器是否可以确定哪个 servlet 将处理请求
【发布时间】:2011-07-29 01:27:33
【问题描述】:

我正在编写一个执行日志记录的过滤器,如果请求最终到达某个 servlet,我需要禁用此日志记录。

过滤器有没有办法知道哪个 servlet 将处理请求?

【问题讨论】:

    标签: java tomcat servlets servlet-filters


    【解决方案1】:

    您可能希望设置 servlet 过滤器映射,以便在完全请求特定 servlet 的情况下不触发它。

    示例配置可能如下所示,假设有一个 DefaultServlet 不应受过滤器影响,而另外两个 servlet FirstServlet 和 SecondServlet 必须受到影响。

    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <servlet-name>FirstServlet</servlet-name>
    </filter-mapping>
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <servlet-name>SecondServlet</servlet-name>
    </filter-mapping>
    

    【讨论】:

    • 不幸的是,我想忽略的 servlet 是处理所有未在其他地方处理的 URL 的默认 servlet。这意味着它会有一个非常复杂的 URL 模式。
    • 您不仅可以将过滤器映射到 URL 模式,还可以映射到特定的 servlet。这意味着您可以仅为要应用过滤器的 servlet 定义映射。
    【解决方案2】:

    您可以指定要过滤的 url 模式 例如

    <filter>
            <filter-name>Admin</filter-name>
            <filter-class>com.nil.FilterDemo.AdminFilter</filter-class>
    </filter>
    
    <filter-mapping>
            <filter-name>Admin</filter-name>
            <url-pattern>/admin/*</url-pattern>
    </filter-mapping>
    

    此过滤器将针对 servlet 引擎使用 /admin 映射处理的每个请求运行。

    【讨论】:

      【解决方案3】:

      我一直认为您应该能够对 web.xml 中的 url-patterns 进行例外处理,例如如果你能做这样的事情:

      <filter-mapping>
          <filter-name>MyFilter</filter-name>
          <url-pattern>
              <match>/resources/*</match>
              <except>/resouces/images/blah.jpg</except>
          </url-pattern>
      

      但你不能,所以这对你没有帮助!

      您显然可以通过请求对象访问过滤器中的 URL,因此您可以执行以下操作:

      public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
                              FilterChain chain) throws IOException, ServletException {
      
          HttpServletRequest request = (HttpServletRequest)sRequest;
      
          if(!request.getRequestURI.equals("/resources/images/blah.jpg")) {
              doLogging();
          }
      
          chain.doFilter();
      }
      

      (这里是硬编码,但您可能会从属性文件中读取它)虽然这可能对您没有用处,因为您在查询中提到了 servlet 而不是 URL 模式。

      编辑:另一个想法。如果您不介意在 servlet 完成后进行日志记录,您可以执行以下操作:

      public void doFilter(ServletRequest sRequest, ServletResponse sResponse,
                              FilterChain chain) throws IOException, ServletException {
      
          sRequest.setAttribute("DO_LOGGING", new Boolean(true));
          chain.doFilter();
      
          Boolean doLogging = (Boolean)sRequest.getAttribute("DO_LOGGING");
          if(doLogging) {
              doLogging();
          }
      }
      

      而您想要从日志记录中排除的 servlet 只需将该属性设置为 false。

      public void doGet(HttpServletRequest req, 
                          HttpServletResponse res) throws IOException {
      
         req.setAttribute("DO_LOGGING", new Boolean(false));
         // other stuff
      }
      

      【讨论】:

        猜你喜欢
        • 2015-09-12
        • 2021-04-29
        • 1970-01-01
        • 2013-07-15
        • 2011-12-18
        • 2014-09-13
        • 2013-04-12
        • 1970-01-01
        • 2012-04-02
        相关资源
        最近更新 更多