http://how2j.cn/k/tmall-j2ee/tmall-j2ee-894/894.html?p=66748
注册的时候用这个链接,谢谢啦!
92 * 0.8
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的设计模式,大致思路相同,具体操作不同。
和前情介绍相同,都是在Servlet中获得字符串,然后通过反射的方式在service中调用相应的方法。
获得字符串的方式除了之前所说的通过隐藏控件的方式提交,还有什么方法呢?
给你一个uri地址:http://localhost:9090/admin_category_list
这是一个字符串,重点是字符串是由什么构成的?
uri =协议(http) + 主机名(loaclhost) + 端口号(9009) + 控制指令(admin_category_list)
为什么我叫做控制指令呢》我们接着往下看:
控制指令 = “拦截标志(admin)” + “Servlet名(category)” + “调用方法(list)”
可以看到,其实控制指令本质上就是按照某种规则组合起来的字符串,这样我们就可以在程序中进行解析。
Filter的基本知识点见:
https://blog.csdn.net/chenkun2016/article/details/79498618
选取一点《深入分析Java Web技术内幕》书中的文字分享:
作用本质上就是判断uri中的控制命令字符串是否以“/admin”开头。如果是,说明是后台功能,那么就需要先拿出第一个下划线后的内容,以确定要去哪个Servlet中处理,然后拿出第二个下划线后的内容,以确定要调用哪个函数。
举例说明
uri:http://localhost:9090/admin_category_list
控制命令:admin_category_list
admin:需要截去字符串
category:使用categoryServlet处理
list:需要在categoryServlet的service方法中调用list方法
流程图
和BackServletFilter中相同的部分不再重复,仅仅给出流程图。
Filter是过滤器,每次request要交给service方法处理之前都需要先经过Filter的处理,因此如果有多个Servlet都需要对request做同样操作的工作,应该交给Filter来完成。
那我们来想想这样一个业务逻辑,一个用户点击进入天猫主页,如果他没登录,那么他应该看不到任何信息,但是如果他登录了,就应该在左上角看到自己的名字,在右上角看到购物车的数量,在主要页面显示分类信息和商品。
刚才说了,如果有多个Servlet都要对request进行什么处理的话,那么就可以通过Filter解决。我们知道,中文需要采用UTF-8编码,否则将显示乱码。对于post提交方式,我们可以指定编码的字符集,但是每个请求都要在servlet中指定也未免有些麻烦,因此可以采用Filter进行统一处理。
request.setCharacterEncoding("UTF-8");//对所有请求的编码设定为UTF-8
这个逻辑很简单——我不给你看的界面,就都跳转到登录界面,等你登陆上了我才给你看。
所以整个代码的逻辑就是:
这个抽象类继承自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方法都做了那些事吧。
这一部分内容我在之前说过,但是我看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会变的。
如上述完全相同。
本次主要讲解了Servlet+Filter的设计模式,建议结合前情介绍中的内容一起看,效果更好。
下节预告
下节讲分页。