【问题标题】:@WebFilter exclude url-pattern@WebFilter 排除 url 模式
【发布时间】:2015-07-09 13:05:44
【问题描述】:

我使用过滤器检查登录用户的 URL 模式。

但我有许多 URL 模式需要过滤。

{ "/table/*", "/user/*", "/contact/*", "/run/*", "/conf/*", ..., ..., ...}

它变得无法维护。排除会更简单:

{ "/", "/login", "/logout", "/register" }

我怎样才能做到这一点?

@WebFilter(urlPatterns = { "/table/*","/user/*", "/contact/*","/run/*","/conf/*"})
public class SessionTimeoutRedirect implements Filter {

    protected final Logger logger = LoggerFactory.getLogger("SessionFilter");

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;
        if (request.getSession().getAttribute("Id") != null) {
            chain.doFilter(req, res);
        } else {
            logger.debug("session is null:"+request.getRequestURL());                    
            response.sendRedirect(request.getContextPath()+"/login");
        }
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

    @Override
    public void destroy() {

    }

}

【问题讨论】:

    标签: java servlets servlet-filters url-pattern


    【解决方案1】:

    servlet API 不支持“排除”URL 模式。

    最好的办法是仅映射 /* 并将 HttpServletRequest#getRequestURI() 与允许的路径集进行比较。

    @WebFilter("/*")
    public class LoginFilter implements Filter {
    
        private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
            Arrays.asList("", "/login", "/logout", "/register")));
    
        @Override
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) res;
            HttpSession session = request.getSession(false);
            String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", ""); 
    
            boolean loggedIn = (session != null && session.getAttribute("Id") != null);
            boolean allowedPath = ALLOWED_PATHS.contains(path);
    
            if (loggedIn || allowedPath) {
                chain.doFilter(req, res);
            }
            else {
                response.sendRedirect(request.getContextPath() + "/login");
            }
        }
    
        // ...
    }
    

    【讨论】:

      【解决方案2】:

      您可以使用initParam 来排除一些模式并实现您的逻辑。这与BalusC's 答案基本相同,除了使用initParam 如果您愿意/需要,可以将其写入web.xml。

      下面我忽略了一些二进制(jpeg jpg png pdf)扩展:

      @WebFilter(urlPatterns = { "/*" },
          initParams = { @WebInitParam(name = "excludedExt", value = "jpeg jpg png pdf") }
      )
      public class GzipFilter implements Filter {
      
          private static final Set<String> excluded;
      
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
              String excludedString = filterConfig.getInitParameter("excludedExt");
              if (excludedString != null) {
                  excluded = Collections.unmodifiableSet(
                      new HashSet<>(Arrays.asList(excludedString.split(" ", 0))));
              } else {
                  excluded = Collections.<String>emptySet();
              }
          }
      
          boolean isExcluded(HttpServletRequest request) {
              String path = request.getRequestURI();
              String extension = path.substring(path.indexOf('.', path.lastIndexOf('/')) + 1).toLowerCase();
              return excluded.contains(extension);
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                  throws IOException, ServletException {
              System.out.print("GzipFilter");
              HttpServletRequest httpRequest = (HttpServletRequest) request;
              HttpServletResponse httpResponse = (HttpServletResponse) response;
              if (isExcluded(httpRequest)) {
                  chain.doFilter(request, response);
                  return;
              }
      
              // Do your stuff here
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2021-12-25
        • 1970-01-01
        • 2017-08-12
        • 2022-10-19
        • 2021-06-15
        • 2012-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多