周记(jsp中Icon引用的bug)

来源:互联网 发布:买家如何进入淘宝客 编辑:程序博客网 时间:2024/06/05 03:03

2016/1/11--2016/1/17

         今天遇到了一个奇葩的问题,出现的现象是:在用户登录成功后的,我就用户信息以及权限信息放到了HttpSession对象中存放着(当然这是一个很常见的操作,也用过很多次都没有问题),我的主菜单页面中(menu.jsp)中菜单显示正常(菜单的显示是根据权限来判断决定),而在我其他子页面中功能按钮显示失常(功能按钮的显示也是由权限来决定)。

具体逻辑:


情景分析和猜想:主菜单页面能拿到session中的信息,说明信息set到session中了,检测子页面是否有拼写等小错误,再确认子页面中是否能拿到session中的权限信息

         测试结果:仔细检测了页面中权限逻辑控制部分代码,并无问题,又经测试发现在session中取到的权限信息为null(原应该是一个Map<String,Object>),而用户信息还在session中

         情景分析和猜想:用户信息能在子界面中从session中取到,说明session并没有过期,也没有重新创建,而权限信息为null,可能后台在哪里把session中的权限信息给remove了

         测试结果:检测了后台中的相应action,并没有把session中的权限信息remove,再重新查看登录方法时,发现在方法一开始有一句清空session中权限信息的代码(当时需求‘要控制重复登录’问题而写的一段代码),login方法代码类似如下,

public String login(){   String flag = "login";   HttpSession s = ServletActionContext.getRequest().getSession();   s.removeAttribute("authoMap");   User u = isLogin(userNo,password)//判断用户名和密码是否正确   if(u!=null){      flag = "menu";      Map<String,Object> authoMap = getAuthoMap(u);      s.setAttribute("user",u);      s.setAttribute("authoMap",authoMap);   }   return flag;}

将s.removeAttribute("authoMap");代码屏蔽重新测试,现象解决,均能正常显示。

         疑问:虽然问题现象恢复了正常,但这里还是有很大的疑问,先说remove语句在set语句之前,而且登录成功后将跳转到菜单页面(menu.jsp),而菜单页面中却能正常拿到权限信息。

         探究:现象很是奇怪,以前也没有遇到过,决定debug一下,将代码

                   s.removeAttribute("authoMap")

打开,并在上面设置一个断点,重新登录跟踪了下login()方法,发现了一个奇怪的现象:login()方法被执行了两次。第一执行的时候userNo和password都有登录界面提交过来的数据,登录成功取得权限信息set到session中,而第二次执行时userNo和password均为null,问题就出在了这里,第二次调用login方法时会先清空session中的权限信息,而调用该方法时的用户信息却为空,if里面的代码都没有被执行,这里就解释了session中的权限信息为空的原因,但是这里为什么会被调用两次还是个问题。

         关于登录这块,先是检测了登录过滤器(LoginFilter.java),该过滤器未防止未登录而访问项目中其他资源,过滤器中也没有重复提交请求之类的代码。第二个就查看登录界面中是否有重复登录操作,经排查也没有问题。在多次debug中是发现一个现象,第一到断点处时,页面在登录(login.jsp)页面,并没有跳转,等我点继续执行断点代码后,页面就跳到了主菜单(menu.jsp)界面,程序再次停在断点处。第一次请求应该就是在主菜单(menu.jsp)界面发出的,决定查看主菜单(menu.jsp)界面代码

         主菜单(menu.jsp)界面中与请求相关的一个就是js代码,一个就是head中关于头信息的一些设置,主菜单(menu.jsp)界面中js代码并不多,也并没有关于请求后台的代码。开始排查head中一些相关的代码(关于jsp/html中关于请求头信息和head中的一些标签并不太熟悉),menu.jsp中的代码类似如下

<head><link rel="Shortcut Icon"  href=""/><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>生产管理中心</title></head>

先将设置项目icon的这句屏蔽了

         <linkrel="Shortcut Icon"  href=""/>

重新debug运行,奇迹的发现login方法没有被执行两次了,重新加上一句和删掉这句试了几次,login重复执行了一次就是这里发出的请求(这里当时写代码的时候准备放公司的logo,但是手上没有公司logo的icon格式的文件,href就空在那里了),又在href中加上了项目中一张临时icon图片的路径后重新debug,login方法也没有被执行两次。

 

猜想:

         在jsp页面中,如果有<linkrel="Shortcut Icon"  href=""/>语句,而其中href中的地址为空,浏览器将会在加载到该句时,自动链接到跳转到该jsp的请求路径,也就是到该jsp路径,出现的现象就是,当你从后台跳转到该jsp时,后台的方法会在该语句下再被请求一次。

 

对猜想做测试:

         重新写了一个简单的demo,其中就跳转关系如图:


主要代码如下:

test.jsp代码

<html><head><link rel="stylesheet" href="bootstrap/css/bootstrap.css"><title>test</title></head><script type="text/javascript" src="js/jquery-1.10.2.js" ></script><script type="text/javascript" src="bootstrap/js/bootstrap.js" ></script><body ><a href="test" >action-->index</a><br/></body></html>

action中的test方法代码:

public String test(){System.out.println("--------------------------");return SUCCESS;}

indes.jsp代码

<html><head><link rel="Shortcut Icon"  href=""/><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>index page</title></head><body>This is a page.</body></html>

debug运行了该项目,访问test.jsp页面,点击action-->index链接,后台代码的test()方法被执行了两次。

结论:

         jsp中关于<linkrel="Shortcut Icon"  href=""/>语句中,如果href中地址为空,浏览器会自动加载跳转到该jsp的访问路径。

 

最后又扩展测试了下,link标签中其他rel值,没人出现上述现象,

                                     如<link rel="stylesheet"href=""/>
0 0
原创粉丝点击