在项目中我遇到读取资源问题,资源路径没有规则,还有很多虚拟路径处理。我使用了Filter过滤404错误方法处理这些资源。在实现过程中统一了资源处理方法,并且容易同spring的整合。该实现在Tomcat 9.0上测试通过。
实现需要注意二点:
- 使用HttpServletResponseWrapper包装response
- 覆盖sendError方法,遇到404错误不能触发错,如触发错误response就被托管,托管后就不能输出数据。
下面是 Error404ResponseWrapper 具体实现:
package com.filter;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
/**
* Created by TYK on 2017/9/23.
*/
public 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处理,上面代码解决了核心两个问题。接下来完成过滤就可。
下面是 Error404Filter 具体实现:
package com.filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Created by TYK on 2017/9/24.
*/
public class Error404Filter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
Error404ResponseWrapper responseWrapper = new Error404ResponseWrapper(this, response);
chain.doFilter(request, responseWrapper);
if (responseWrapper.isFound()) {
return;
}
response.sendRedirect("404.html");
}
public void init(FilterConfig config) throws ServletException {
}
}
web.xml配置
<filter>
<filter-name>Error404Filter</filter-name>
<filter-class>com.filter.Error404Filter</filter-class>
</filter> <!--404-->
<filter-mapping>
<filter-name>Error404Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意:在web.xml中把该过滤器放在所有过滤器后。