今天查找一个问题:我在列表页面添加一个查询条件,然后查询符合条件的数据.查询结果正确.然后我进入其它菜单项操作,当我再次进入列表页面时,系统还是按刚才的查询条件查询的.只要不我修改或清空查询条件,查询条件一直存在.我用的struts1.
很奇怪.以前没遇到过.先是怀疑客户端错误:
1:是不是IE缓存?抓包页面确实是被重新请求了.请求的URL中也没有上次的查询条件.那就不是IE缓存的问题.
2:那是不是页面的COOKIE保存了数据呢?抓包里返回的页面直接就填写了这些查询条件.
这样,问题就排除了客户端设置错误的可能了.那问题肯定在服务器上,一定时服务器端什么地方保存了ActionForm!
于是我就debug服务器端代码追查,在传到我写的Action里的from就已经有查询条件了,于是再往上一级查,找到了拼装ActionForm的方法,在struts1的RequestProcessor类里,代码如下:
private static ActionForm lookupActionForm(HttpServletRequest request, String attribute, String scope) { // Look up any existing form bean instance if (log.isDebugEnabled()) { log.debug( " Looking for ActionForm bean instance in scope '" + scope + "' under attribute key '" + attribute + "'"); } ActionForm instance = null; HttpSession session = null; if ("request".equals(scope)) { instance = (ActionForm) request.getAttribute(attribute); } else { session = request.getSession(); instance = (ActionForm) session.getAttribute(attribute); } return (instance); }
|
从if ("request".equals(mapping.getScope())) { request.setAttribute(mapping.getAttribute(), instance); }这句可以看出来,原来当scorp是request时,会把Form保存在request里,否则保存在session里.从这里知道是哪儿存的了,我的配置文件没有配置scope属性,默认值就是session,也就是在这里会把ActionForm存到session里.
下面再找是怎么取的:在RequestUtils.createActionForm(request, mapping, moduleConfig, servlet);方法里,会调用它本身的另一个方法:
private static ActionForm lookupActionForm(HttpServletRequest request, String attribute, String scope) { // Look up any existing form bean instance if (log.isDebugEnabled()) { log.debug( " Looking for ActionForm bean instance in scope '" + scope + "' under attribute key '" + attribute + "'"); } ActionForm instance = null; HttpSession session = null; if ("request".equals(scope)) { instance = (ActionForm) request.getAttribute(attribute); } else { session = request.getSession(); instance = (ActionForm) session.getAttribute(attribute); } return (instance); }
|
这下明朗了吧?原来是scope搞的鬼.还是对struts研究不深,对scope属性作用不了解.
行了,也没费多少时间,这回对scope属性的作用就印象深刻了.呵呵.
上网查了一下,还真有不少人遇到这种问题.