对于 WebSphere 中的这个场景,Web 容器使用 HttpServetResponse.sendError(int, String) 方法发送 403 响应代码。因此,您可以使用过滤器和 HttpServletResponseWrapper 修改响应代码。 Filter 用您的 HttpServletResponseWrapper 替换响应对象,然后覆盖 sendError 方法。例如这个 HttpServletResponseWrapper:
package wrappers;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class SendErrorResponseWrapper extends HttpServletResponseWrapper {
HttpServletRequest _request;
HttpServletResponse _wrappedResponse;
public SendErrorResponseWrapper(HttpServletRequest request, HttpServletResponse response) {
super(response);
_request= request;
_wrappedResponse= response;
}
@Override
public void sendError(intstatus) throwsIOException {
String path = _request.getServletPath() + _request.getPathInfo();
if(status == 403 && path.endsWith("html/")) {
_wrappedResponse.sendError(404);
} else{
_wrappedResponse.sendError(status);
}
}
@Override
public void sendError(intstatus, String msg) throwsIOException {
String path = _request.getServletPath() + _request.getPathInfo();
if(status == 403 && path.endsWith("html/")) {
_wrappedResponse.sendError(404, msg);
} else{
_wrappedResponse.sendError(status, msg);
}
}
}
通过此过滤器添加到请求处理中:
package filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import wrappers.SendErrorResponseWrapper;
@WebFilter(urlPatterns = "/*")
public class SendErrorFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
SendErrorResponseWrapper responseWrapper = new SendErrorResponseWrapper((HttpServletRequest) request, (HttpServletResponse) response);
chain.doFilter(request, responseWrapper);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
注意事项:
过滤器 urlPatterm 必须是 /* 以确保它被错误请求调用。如果模式是 .html,则过滤器不会被错误请求调用,并且“.html/”不是有效的 urlPattern。
如果请求以“html/”结尾的资源,则响应包装器将覆盖 sendError 方法并将 403 响应代码更改为 404,否则保持原样。然而,对“html\”的测试有点简单,因为您可能需要它来处理其他静态文件类型或其他类似情况,其中 web 容器将针对静态文件请求返回 403。基本上,在这些情况下,静态文件请求会收到 403:
- 路径包含“..”但不以“/...”开头
- 路径以“\”、“.”结尾或“/”
但是,过滤器的困难在于确保它不会更改响应代码,例如,对于路径以“/”结尾的 servlet 的请求,因为这样的请求是有效的。因此,仅针对以“/”结尾的请求路径进行测试过于笼统,并且必须在了解应用程序打算提供哪些静态资源的情况下设置测试。