[我的JAVA历程]过滤器的应用
BUG重现:在用户注销后,应用浏览器的前进后退按钮仍然可以看到以前的操作页面,但是再进行具体业务逻辑时由于一些对象已经销毁而产生错误,修改要求再进行具体业务操作时应该返回登录页面。
修改方案1:由于注销动作会销毁session,因此想到进行具体操作时根据session是否为空来判断是跳转到下一页面还是返回到登录页面。在jsp页面的代码中加入session是否为空的判断,但是发现不是每次都会读取那段代码,大部分为读取的缓存。所以禁止浏览器读取缓存,代码如下
<%response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
response.setHeader("Pragrma","no-cache");
response.setDateHeader("Expires",0);
%>
html中加入代码:
<meta http-equiv="Expires" content="0"/>
<meta http-equiv="Cache-Control" content="no-cache"/>
<meta http-equiv="Pragma" content="no-cache"/>
代码修改后发现并没有达到要求,还是会进行具体的业务逻辑。
修改方案2:在原来请求jsp页面前请求一个servlet,在servlet里面判断session是否为空,但是这样在传jsp所需要的参数时就很麻烦,需要自己拼装字符串。修改完以后发现仍然会进行具体的业务逻辑。然后看日志,打印sessionId,发现注销后点击后退,没有读取缓存,但是session确实不为空。为什么呢..查询代码发现在注销后会自动创建新的session,fuck.看来不能用session来判断是否已经注销了。转变思路,在注销后进行具体业务逻辑失败不是因为session为空,为是因为操作具体逻辑的对象被销毁了,而这些对象是在登录时创建的。所以有判断session是否为空改为判断这些重点的逻辑对象是否为空,这里为判断异步控制对象是否为空(AsynInfoControl),经过这样的修改后部分满足了要求。为什么这么说呢,应为这个servlet是针对某一个jsp页面的跳转写的验证程序,如果用户后退到其他操作页面则还会进行具体的业务操作,难道要为每个jsp页面写一个这样的验证程序吗?O,NO..
突然想到为什么不写一个类似与过滤器的东西呢,再所有的请求中都加上这个过滤器,这样还可以解决具体jsp参数传递的问题。GOOD,于是写了一个filter,过滤条件为*,因为程序中有直接访问jsp的,还有访问servlet的。代码改完后,登录,发现登录界面跳转后还是登录界面,恍然大悟,原来过滤器在过滤登录的servlet(loginservlet)时,正好这个servlet也满足了被滤掉的条件(具体的那个逻辑对象为空,因为此时还没到创建这些对象的地方,cause还没到loginservlet,只在过滤器上就被pass了,T_T)。于是想到主动让过滤器露掉登录的servlet,在请求的request中查询当前请求的URI,如果为loginservlet的URI,则为正常的登录,要结着跳转到后面的loginservlet,不能pass掉。所有代码改完后,测试,成功。ohyeah!
这次改bug最满足的地方是由刚开始的再别人写的代码上改,最后改成加过滤器,并没有修改别人的代码,这样安全性和代码的污染性要小很多很多。
写这个的目的只是记录下自己遇到问题分析问题的过程和思路的转变,因为以前没有特意用过过滤器,所以这次能想到这里还是挺兴奋的。尽管这是很基础的能力...
经验是一点一点积累起来的,在JAVA开发的路上我会慢慢成长,仅以此纪念。