使用过滤器,处理404错误获得指定资源。

在项目中我遇到读取资源问题,资源路径没有规则,还有很多虚拟路径处理。我使用了Filter过滤404错误方法处理这些资源。在实现过程中统一了资源处理方法,并且容易同spring的整合。该实现在Tomcat 6.0上测试通过。

实现需要注意二点:
  • 1.使用HttpServletResponseWrapper包装response
  • 2.覆盖sendError方法,遇到404错误不能触发错,如触发错误response就被托管,托管后就不能输出数据。

下面是HttpServletResponseWrapper具体实现:
  private class Error404ResponseWrapper extends HttpServletResponseWrapper {
        
        private int status = SC_OK;
        
        public Error404ResponseWrapper(Error404Filter error404Filter, HttpServletResponse response){
            super(response);
        }
        
        @Override
        public void sendError(int sc) throws IOException {
            this.status = sc;
            if(isFound()){
                super.sendError(sc);                
            }else{
                super.setStatus(SC_OK);
            }
        }

        @Override
        public void sendError(int sc, String msg) throws IOException {
            this.status = sc;
            if(isFound()){
                super.sendError(sc,msg);  
            }else{
                super.setStatus(SC_OK);                 
            }
        }
        
        public void setStatus(int status){
           this.status = status;
           super.setStatus(status);
        }
        
        @Override
        public void reset() {
            this.status = SC_OK;
            super.reset();
        }

        
        public boolean isFound(){
            return status != SC_NOT_FOUND;
        }
    }

注意sendError处理,上面代码解决了核心两个问题。接下来完成过滤就可。
public class Error404Filter implements Filter {
  @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
    }
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse rep,FilterChain chain) throws IOException, ServletException {
        
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) rep;
        Error404ResponseWrapper responseWrapper = new Error404ResponseWrapper(this, response);
        
        chain.doFilter(request, responseWrapper);
        if(responseWrapper.isFound()){
            return ;
        }
        
        //TODO 实现读取资源
        //readResource(request,response);
        
        //资源不存在返回错误
        String uri = request.getRequestURI();
        logger.warn("This is not resource = {}",uri);
        response.sendError(HttpServletResponse.SC_NOT_FOUND,uri);
    }
}

注意:在web.xml中把该过滤器放在所有过滤器后。

猜你喜欢

转载自hhywangwei.iteye.com/blog/1260384