在项目中我遇到读取资源问题,资源路径没有规则,还有很多虚拟路径处理。我使用了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中把该过滤器放在所有过滤器后。