最近在写一个项目,用到了Shiro,Shiro中的过滤器引起了小编的兴趣,今天特地把原生的过滤器filter复习了一遍,给大家分享一下,下次再来说说Shiro中封装的过滤器,其实说白了,所有框架都是封装了原生的servlet,因为底层是不会变的。不同的在于别人是技术大牛,封装的牛逼,其实你自己也可以封装,但估计会bug很多。
代码中有些注释不是关于filter的,是和重定向/转发以及访问不安全资源有关的,小编思路横飞,写着写着就想到其他地方去了,这一篇文章应该是写的最长的一篇了,就当给大家发福利了。
先来看一下小编的demo结构图:
第一步、先看一下web.xml文件,Tomcat启动时就会加载并初始化过滤器。注意:过滤器的执行顺序和web.xml文件中顺序是一样的,从上往下依次执行。
第二步、编码过滤器,解释在后面,先看代码。
第三步、记录日志过滤器
下面开始测试:
1)当我们启动Tomcat时,会发生什么事呢?来看一下日志。
2)在地址栏中输入:http://localhost:8080/FilterTest/
在web.xml中默认访问首页是index.jsp。
此时过滤器工作流程是:
从中我们可以看出,先执行了EncodingFilter中的doFilter()方法,然后在执行chain.doFilter(request, response);时,发现后面还有LogFilter()过滤器,就立刻跳转执行LogFilter中的doFilter()方法,然后在执行chain.doFilter(request, response);时,后面已经没有过滤器了,将本过滤器中的doFilter()方法执行完之后有跳回到EncodingFilter中的doFilter()的chain.doFilter(request, response);的下一行,有点类似于中断嵌套的意思,自行体会吧。
3)接着再看一个表单提交的例子
<!-- 定义一个测试用的servlet -->
<servlet>
<servlet-name>filterTest</servlet-name>
<servlet-class>cn.uestc.chengdu.servlet.FilterTestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filterTest</servlet-name>
<url-pattern>/filterTest</url-pattern>
</servlet-mapping>
同样的,在地址栏输入:http://localhost:8080/FilterTest/filterTestForm.jsp,过滤器也会对其进行阻拦,这个和上一个是一样的,本质都是一次对服务器的访问。
控制台打印的日志如下:
4)点击提交表单,此时与提交相关的servlet如下,先测试转发时过滤器的工作流程:
控制台日志如下:
success.jsp页面如下:
看到这里我们基本上就明白了:由于我们在web.xml文件中配置的是/*,表示过滤所有请求,所以每次都会经过过滤器,FilterTestServlet类中我们用的是第24行代码,也就是转发,现在换成用31行的重定向来试试会有什么效果。
将FilterTestServlet类改成如下:
再次提交表单,看一下日志会打印出什么内容:
很明显,地址栏发生了改变,日志内容也比上次多了很多,原因在于重定向是客户端重新向服务器发送请求,所以过滤器又会拦截一次。
5)下面小编就来说一下转发和重定向的问题。
请求:从客户端--->服务器(Servlet)过程称为请求。由客户端发出比如登录表单操作。
响应:从服务器---->客户端过程称为响应。服务器向登录表单做出相应结果(无论登录是否成功)。
转发是同次请求(由服务器在它自己内部请求下一个资源)。重定向是多次请求(由服务器重定向到客户端,由客户端请求下一个资源)。一句话总结:转发是由服务器发出请求,重定向是由客户端发出请求。
6)重定向和转发相对路径和绝对路径问题
注意:转发和重定向的URLString前有加 / 为绝对路径 反之为相对路径
1.我们这里通过表单请求指定的Url资源 action="filterTest" ,那么则表单生成的请求地址为:
http://localhost:8080/FilterTest/filterTest
2.在servlet处理请求之后重定向到下面指定资源
参数可以指定为相对路径或绝对路径或web应用程序。
①相对路径:response.sendRedirect("redirect.jsp")生成的地址:原来请求地址+参数生成完整的URL即:http://localhost:8080/FilterTest/redirect.jsp
这个已经验证了。
②绝对路径:response.sendRedirect("/AbsolutePath/absolutePath.jsp")生成的地址:web服务器本身地址+参数生成完整的URL 即:http://localhost:8080/AbsolutePath/absolutePath.jsp。很明显,这是不对的。
如图所示:
正解如下:
下面小编将为项目增加一个 AbsolutePath文件夹, 相应代码更改如下图所示:
FilterTestServlet更改及日志如下:
跳转结果如下:
③其他web应用地址response.sendRedirect("http://www.baidu.com") 容器直接定向到该URL。
上述的结论小编都已经验证,没有问题哦!!!!!!
下面再说今天的最后一个问题,访问静态资源文件,在WEB-INF里的资源外界是无法访问的,由此可以知道,如果想用重定向肯定是不可能的,原因是重定向就是外界直接访问的意思,而只能有转发:也就是服务器内部自己访问。项目结构及相关代码如下:
运行结果:
大功告成了!今天就先说这么多吧,本来是只想聊聊过滤器的,结果啰嗦了这么多,如果你觉得小编的文章对你有用,请点赞支持一下!谢谢啦!