首先我们看下 sendRedirect(重定向)与forworld(转发)的具体是指什么:
一个web资源受到客户端请求后,通知服务器去调用另一个web资源进行处理,称之为请求转发。 一个web资源受到客户端请求后,通知浏览器去调用另一个web资源进行处理,称之为请求重定向。
根据字面意思上理解,重定向肯定是会重新走filter了,因为重定向是告知浏览器再次发出请求。而请求转发则是服务器内部的逻辑,它还会重新走filter吗?
我们看下 正常的一个请求是怎么访问到servelte的 ,下面我画了个简图
到底是不是我们猜测的那样呢?我们用代码说话
首先创建自己的filter
public class CharsetEncodingFilter implements Filter {
private String encoding = null;
private ServletContext servletContext;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.encoding = filterConfig.getInitParameter("encoding");
this.servletContext = filterConfig.getServletContext();
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response, FilterChain chain)
throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
httpRequest.setCharacterEncoding(encoding);
httpResponse.setCharacterEncoding(encoding);
servletContext.log("当前编码已设置为:" + encoding);
// CharsetEncodingFilter -> FrontControllerServlet -> forward -> index.jsp
}
// 执行过滤链
chain.doFilter(request,response);
}
@Override
public void destroy() {
}
}
运行项目查看执行结果:
日志输出
三月 03, 2021 2:02:09 下午 org.apache.catalina.core.ApplicationContext log
三月 03, 2021 2:02:09 下午 org.apache.jasper.compiler.TldLocationsCache tldScanJar
发现并没有咱们刚才打印的日志
servletContext.log("当前编码已设置为:" + encoding);
这是未什么呢?
翻找servlet规范
[图片上传失败...(image-ee5aab-1614751675752)]
文字太多 咱们只截图部分说明哈,具体的文档请翻阅《Java™ Servlet 规范》3.1版本
根据文档中我们发现,设置filter是可以指定拦截的是什么类型的请求。
根据文档,配置如下
<filter-mapping>
<filter-name>CharsetEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
再次打包运行,结果如下:
信息: 当前编码已设置为:UTF-8
三月 03, 2021 2:02:09 下午 org.apache.jasper.compiler.TldLocationsCache tldScanJar
根据结果得知,无论是转发和重定向都会根据是否配置了拦截的类型而进行拦截的。
git代码:https://github.com/cuoduidui/geekbanglessons.git