最近在公司做的项目一直测试和使用都很好,客户反响也很不错,但是,就在前两天,客户提出了一个bug,但是全队都愁眉不展,在今天做公交车的时候,我突然想到了一种可能,就是我们习以为常的ajax提交出了问题!
起因:
需求:在判断用户session有没有超时的情况,我们使用的是在所有的请求前通过aop进行判断,如果session中,用户登录信息丢失,则重新登录,否则继续!
bug情况:在页面提交,跳转下正常判断,但是在用户session过期后,直接使用Ajax提交时,提交失败!
初期方案:
方案1:
修改session失效时间(未治本)
方案2:
抽象公共js,先验证session是否登陆,未登录,则返回登陆页面(个人认为最好,因为在不改动原有的基础上,增加,而不是修改)
方案3:
抽象公共ajax方案,用到ajax方法的,统一调用这个方法
利弊分析:
修改session失效时间(未治本)治标不治本,还会导致系统性能下降,应该是调试到一个合适的时间,或者用cookie方案代替!
抽象公共js, 抽象公共ajax方案,每个调用都需要更改,改动太大,造成系统维护工作增加!
更优雅方案:
首先建了个拦截器,来判断session超时。用户登录后会保存用户信息在一个session里,在session的监听里,session超时会销毁保存在session里的用户信息,而拦截器就通过session里是否有用户信息来判断session超时。(我总觉得这种方法不怎么好。不知还有什么更好的办法。)
拦截器是spring-mvc的拦截器,在拦截器里判断是不是ajax请求:
<span style="font-size:18px;">1. public boolean preHandle(HttpServletRequest request, 2. HttpServletResponse response, Object handler) throws Exception 3. { 4. if (request.getSession().getAttribute("user") == null)//判断session里是否有用户信息 5. { 6. if (request.getHeader("x-requested-with") != null 7. && request.getHeader("x-requested-with") 8. .equalsIgnoreCase("XMLHttpRequest"))//如果是ajax请求响应头会有,x-requested-with; 9. { 10. response.setHeader("sessionstatus", "timeout");//在响应头设置session状态 11. return false; 12. } 13. 14. } 15. return true; 16. } </span>
这样,如果session超时,而且是ajax请求,就会在响应头里,sessionstatus有一个timeout;
再用一个全局的方法来处理,session超时要跳转的页面。
jquery 可以用$.ajaxSetup 方法,ext也有类似的方法
<span style="font-size:18px;">1. //全局的ajax访问,处理ajax清求时sesion超时 2. $.ajaxSetup({ 3. contentType:"application/x-www-form-urlencoded;charset=utf-8", 4. complete:function(XMLHttpRequest,textStatus){ 5. var sessionstatus=XMLHttpRequest.getResponseHeader("sessionstatus"); //通过XMLHttpRequest取得响应头,sessionstatus, 6. if(sessionstatus=="timeout"){ 7. //如果超时就处理 ,指定要跳转的页面 8. window.location.replace("${path}/common/login.do"); 9. } 10. } 11. } 12. }); </span>
总结:
一个合格的工程师,可以为系统bug及时提供解决方案,但是一个优秀的工程师,绝不止步于此,他会分析各个方案的优劣,选择一种更优雅的方案,或者提供这种方案!
当我们适应了合格的工程师这个称谓,我们是否在朝着优秀的工程师迈进呢?