Shiro过滤器(1)-先从filter路径开始讲起

最近在写一个项目,用到了Shiro,Shiro中的过滤器引起了小编的兴趣,今天特地把原生的过滤器filter复习了一遍,给大家分享一下,下次再来说说Shiro中封装的过滤器,其实说白了,所有框架都是封装了原生的servlet,因为底层是不会变的。不同的在于别人是技术大牛,封装的牛逼,其实你自己也可以封装,但估计会bug很多。

代码中有些注释不是关于filter的,是和重定向/转发以及访问不安全资源有关的,小编思路横飞,写着写着就想到其他地方去了,这一篇文章应该是写的最长的一篇了,就当给大家发福利了。

先来看一下小编的demo结构图:

Shiro过滤器(1)-先从filter路径开始讲起

demo结构图

第一步、先看一下web.xml文件,Tomcat启动时就会加载并初始化过滤器。注意:过滤器的执行顺序和web.xml文件中顺序是一样的,从上往下依次执行。

Shiro过滤器(1)-先从filter路径开始讲起

web.xml文件

第二步、编码过滤器,解释在后面,先看代码。

Shiro过滤器(1)-先从filter路径开始讲起

编码过滤器

第三步、记录日志过滤器

Shiro过滤器(1)-先从filter路径开始讲起

日志过滤器

下面开始测试:

1)当我们启动Tomcat时,会发生什么事呢?来看一下日志。

Shiro过滤器(1)-先从filter路径开始讲起

启动tomcat

2)在地址栏中输入:http://localhost:8080/FilterTest/

Shiro过滤器(1)-先从filter路径开始讲起

index.jsp

在web.xml中默认访问首页是index.jsp。

Shiro过滤器(1)-先从filter路径开始讲起

index.jsp页面内容

此时过滤器工作流程是:

Shiro过滤器(1)-先从filter路径开始讲起

访问index.jsp时,过滤器的执行过程

从中我们可以看出,先执行了EncodingFilter中的doFilter()方法,然后在执行chain.doFilter(request, response);时,发现后面还有LogFilter()过滤器,就立刻跳转执行LogFilter中的doFilter()方法,然后在执行chain.doFilter(request, response);时,后面已经没有过滤器了,将本过滤器中的doFilter()方法执行完之后有跳回到EncodingFilter中的doFilter()的chain.doFilter(request, response);的下一行,有点类似于中断嵌套的意思,自行体会吧。

3)接着再看一个表单提交的例子

Shiro过滤器(1)-先从filter路径开始讲起

form表单

<!-- 定义一个测试用的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,过滤器也会对其进行阻拦,这个和上一个是一样的,本质都是一次对服务器的访问。

Shiro过滤器(1)-先从filter路径开始讲起

filterTestForm.jsp

控制台打印的日志如下:

Shiro过滤器(1)-先从filter路径开始讲起

4)点击提交表单,此时与提交相关的servlet如下,先测试转发时过滤器的工作流程:

Shiro过滤器(1)-先从filter路径开始讲起

表单内容

Shiro过滤器(1)-先从filter路径开始讲起

FilterTestServlet转发

控制台日志如下:

Shiro过滤器(1)-先从filter路径开始讲起

Shiro过滤器(1)-先从filter路径开始讲起

success.jsp页面如下:

Shiro过滤器(1)-先从filter路径开始讲起

success.jsp页面

看到这里我们基本上就明白了:由于我们在web.xml文件中配置的是/*,表示过滤所有请求,所以每次都会经过过滤器,FilterTestServlet类中我们用的是第24行代码,也就是转发,现在换成用31行的重定向来试试会有什么效果。

将FilterTestServlet类改成如下:

Shiro过滤器(1)-先从filter路径开始讲起

再次提交表单,看一下日志会打印出什么内容:

Shiro过滤器(1)-先从filter路径开始讲起

Shiro过滤器(1)-先从filter路径开始讲起

很明显,地址栏发生了改变,日志内容也比上次多了很多,原因在于重定向是客户端重新向服务器发送请求,所以过滤器又会拦截一次。

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。很明显,这是不对的。

如图所示:

Shiro过滤器(1)-先从filter路径开始讲起

正解如下:

下面小编将为项目增加一个 AbsolutePath文件夹, 相应代码更改如下图所示:

Shiro过滤器(1)-先从filter路径开始讲起

项目目录结构

FilterTestServlet更改及日志如下:

Shiro过滤器(1)-先从filter路径开始讲起

跳转结果如下:

Shiro过滤器(1)-先从filter路径开始讲起

重定向

③其他web应用地址response.sendRedirect("http://www.baidu.com") 容器直接定向到该URL。

上述的结论小编都已经验证,没有问题哦!!!!!!

下面再说今天的最后一个问题,访问静态资源文件,在WEB-INF里的资源外界是无法访问的,由此可以知道,如果想用重定向肯定是不可能的,原因是重定向就是外界直接访问的意思,而只能有转发:也就是服务器内部自己访问。项目结构及相关代码如下:

Shiro过滤器(1)-先从filter路径开始讲起

Shiro过滤器(1)-先从filter路径开始讲起

Shiro过滤器(1)-先从filter路径开始讲起

运行结果:

Shiro过滤器(1)-先从filter路径开始讲起

大功告成了!今天就先说这么多吧,本来是只想聊聊过滤器的,结果啰嗦了这么多,如果你觉得小编的文章对你有用,请点赞支持一下!谢谢啦!

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页