JavaWeb项目详解系列2-2(基于How2j天猫J2EE项目:Filter+Servlet的设计模式)

0 项目来源与阅读建议

项目来源

http://how2j.cn/k/tmall-j2ee/tmall-j2ee-894/894.html?p=66748
注册的时候用这个链接,谢谢啦!

价格

92 * 0.8

阅读建议

  1. 本教程与站长的官方教程互为补充,并不是取而代之,也做不到取而代之。站长是以老师的身份告诉你怎么写,我是以课代表的身份告诉你,我是怎么学的。
  2. 本教程应当在你做完站长相对应部分的内容之后,再来看。也就是说,在看本教程之前,你应当对站长对应章节的内容有了一定的了解和基础,不然某些词语你可能听不懂。
  3. 我在How2j的ID名叫HuangTY,我喜欢分享大家存在的问题,所以也希望大家能够在评论区多多留言,共同进步。

1 前情介绍

https://blog.csdn.net/w8253497062015/article/details/85004072#1_1
在这篇博客的2.2中,我介绍了了一种设计模式,概括来说是:
在jsp中用隐藏控件提交了name=“method”,value="add"的信息,然后在BaseServlet中request.getParameter(“name”),可以获得字符串add,然后通过反射调用add函数,以上的一切都是在service方法内发生的,因此要重写BaseServlet中的service方法。
这一次,我们用Filter+Servlet的设计模式,大致思路相同,具体操作不同。

2 Filter+Servlet的设计模式

2.1设计模式概览

和前情介绍相同,都是在Servlet中获得字符串,然后通过反射的方式在service中调用相应的方法。
获得字符串的方式除了之前所说的通过隐藏控件的方式提交,还有什么方法呢?
给你一个uri地址:http://localhost:9090/admin_category_list
这是一个字符串,重点是字符串是由什么构成的
uri =协议(http) + 主机名(loaclhost) + 端口号(9009) + 控制指令(admin_category_list)
为什么我叫做控制指令呢》我们接着往下看:
控制指令 = “拦截标志(admin)” + “Servlet名(category)” + “调用方法(list)”
可以看到,其实控制指令本质上就是按照某种规则组合起来的字符串,这样我们就可以在程序中进行解析。

2.2 Filter拦截

2.2.1 基本知识点分享

Filter的基本知识点见:
https://blog.csdn.net/chenkun2016/article/details/79498618
选取一点《深入分析Java Web技术内幕》书中的文字分享:

  1. Filter使用的是责任链设计模式。
  2. Web容器再调用Filter的destroy方法后悔再次调用doFilter方法。
  3. Filter的核心是传递FilterChain对象,通过计数器实现,每经过一个Filter对象,当前计数器就会+1,当达到规定长度时候,进入Servlet,之所以能在最后进servlet是因为FilterChain中含有servlet的引用。

2.2.1 BackServletFilter中的运用

作用本质上就是判断uri中的控制命令字符串是否以“/admin”开头。如果是,说明是后台功能,那么就需要先拿出第一个下划线后的内容,以确定要去哪个Servlet中处理,然后拿出第二个下划线后的内容,以确定要调用哪个函数。
举例说明
uri:http://localhost:9090/admin_category_list
控制命令:admin_category_list
admin:需要截去字符串
category:使用categoryServlet处理
list:需要在categoryServlet的service方法中调用list方法
流程图
在这里插入图片描述

2.2.2 ForeServletFilter中的运用

和BackServletFilter中相同的部分不再重复,仅仅给出流程图。
在这里插入图片描述
Filter是过滤器,每次request要交给service方法处理之前都需要先经过Filter的处理,因此如果有多个Servlet都需要对request做同样操作的工作,应该交给Filter来完成。
那我们来想想这样一个业务逻辑,一个用户点击进入天猫主页,如果他没登录,那么他应该看不到任何信息,但是如果他登录了,就应该在左上角看到自己的名字,在右上角看到购物车的数量,在主要页面显示分类信息和商品。

  1. 在左上角看到自己的名字,这个并没有在filter中写,而是交给了foreServlet中的login方法。显示在top.jsp中,注意,这里的user是一个session对象,就是为了在不同的页面跳来跳去的时候,top.jsp都能获取到user的值——所谓的一次登录,一直获取。除非你退出浏览器,不然你session中是一直保存着user的值的(不考虑时限)。因此你在浏览别的页面的时候,top.jsp依然可以保存你的登录信息。
  2. 在右上角看到购物车的数量。这个是交给Filter去完成的。ForeServletFilter中对登录状态进行判断,如果登陆了,则查询购物车中的数量,即这个用户OrderItem表中uid=这个用户,oid=-1的count(*)。
  3. 主要界面显示分类信息和商品。判断域对象中是否有cs,没有的话就是用categoryDAO.list()。

2.2.3 EncodingFilter中的运用

刚才说了,如果有多个Servlet都要对request进行什么处理的话,那么就可以通过Filter解决。我们知道,中文需要采用UTF-8编码,否则将显示乱码。对于post提交方式,我们可以指定编码的字符集,但是每个请求都要在servlet中指定也未免有些麻烦,因此可以采用Filter进行统一处理。

request.setCharacterEncoding("UTF-8");//对所有请求的编码设定为UTF-8

2.2.4 ForeAuthFilter中的运用

这个逻辑很简单——我不给你看的界面,就都跳转到登录界面,等你登陆上了我才给你看。
所以整个代码的逻辑就是:

  1. 划定不给看的范围。
  2. 判断user是不是null。
  3. 如果是null就滚回login.jsp,如果不是null就正常显示,即return。

2.3BaseServlet

2.3.1 BaseBackServlet

这个抽象类继承自HttpServlet,重写了service方法,并且做出以下约定:
1.所有我的子类,都必须事先add,delete,edit,update,list方法。
2.所有我的子类,都可以使用我所定义的XxxDAO对象,因为是protected,继承享有访问权限。其实就是免去了new的操作。
3.所有我的子类,在对request提供service方法进行服务时,调用的service方法都是我写好的这个。但是我没写死,还通过反射给你留出了一个方法可以调用,只要你按照控制命令的格式发过来即可。

重点再说一下service方法。
我们知道Servlet的生命周期,service方法是在servlet存活期间(几乎是Tomcat的运行期间)都一直在提供服务的。我们在学习的时候常用的写法是重写doGet或者doPost方法。但是其实也可以通过重写service方法来实现服务。注意了,如果你采用重写service方法的方式,那就一定要把super.service去掉,不然它还是会去执行父类的doGet或者doPost方法。

再来看BaseBackServlet类中的service方法都做了那些事吧。

  1. 设置分页基本信息。这部分内容我将单独写一篇文章来详细分析。
  2. 根据控制指令中的admin_category_list中的list(举例)来调用子类的list方法。
  3. 图片(文件)上传相关。这部分不做重点,本质上是JavaSE的内容,本教程建议在第一次学习的时候不要考虑任何与图片有关的内容,等到复习的时候再去考虑。如果我想写的话,以后会把这些零零碎碎的东西单独拿出来写文章。
  4. service方法中通过反射调用的那个方法获得的返回值,通过服务器跳转或者客户端跳转,跳转到指定页面或Servlet。

service方法中通过反射调用的那个方法获得的返回值

这一部分内容我在之前说过,但是我看How2j的很多学员并不清楚,那我就再说一下,分为三点。
1.上面的4是什么意思?什么叫service…的返回值?
service方法…返回值,我指的是String redirect这里的redirect,而不是说service方法本身有什么返回值。这个返回值通常是xxx.jsp或者控制指令,譬如admin_category_list。
仔细看代码,在service方法中,获得到了redirect之后,通过开头字母是否是@或%来决定跳不跳转,如何跳转。跳转的方式分为服务器跳转与客户端跳转。
2. 什么叫服务器跳转,什么叫客户端跳转,有什么区别?
https://blog.csdn.net/qq_34111779/article/details/78164027
服务器跳转又叫请求转发,这里的请求是名词不是动词,request forward。意思是,客户端发来的request,服务器接收到之后觉得自己应该交给另一个servlet处理或者应该展示某一个jsp的时候,服务器自动的把请求转发过去了。
客户端跳转又叫重定向。本质上是服务器接收到客户端的request之后,又发了个response给客户端,告诉他你得去找另一个界面,然后客户端再跳转过去。
两者的区别一目了然,服务器跳转是服务器做的事情,和浏览器无关,因此浏览器地址栏的uri不会发生变化。客户端跳转本质上是客户端发起的另一次请求,因此uri可能会变化。
3. 什么时候用服务器跳转,什么时候用客户端跳转?
3.1 对数据库进行增加,删除,和修改的时候用客户端跳转,因为用客户端跳转导致uri变化,因此客户无论怎么F5都不会造成多次增加或删除。
3.2 只读数据库的时候,比如查询,用服务器跳转,因为快啊。服务器跳转是服务器直接跳过去,客户端跳转是服务器告诉客户端你要去哪个页面,然后客户端再发请求,肯定慢。
3.3 如果你传递参数是通过request域对象,那只能服务器跳转,因为客户端跳转相当于是请求两次,request会变的。

2.3.1 BaseForeServlet

如上述完全相同。

3 小结

本次主要讲解了Servlet+Filter的设计模式,建议结合前情介绍中的内容一起看,效果更好。
下节预告
下节讲分页。

猜你喜欢

转载自blog.csdn.net/w8253497062015/article/details/85344984