1 问题的起因
遇到这个问题的时间很悲剧,刚好在项目发布的当头.在运营修改一些业务数据的时候发现某一个参数无法修改!!!怎么传都传不了.注意,只有一个参数是无法修改的.其他的参数都可以
我马上查看源码,发现这个参数的名字是
<input type="text" value="<s:property value='couponBuy.bookPhone'/>" name="couponBuy.bookPhone" id="coupon-order-r3-desc" >
但是通过修改代码debug发现,在Action中打印出这个参数信息却是是null.初步的判断是页面传到Action的时候造成了参数的丢失.然后通过firebug查看,发现'couponBuy.bookPhone'确实是有值的..线索由此断了.中间折腾了差不多两个小时,一直无法解决.最后通过修改参数传入名字
<input type="text" value="<s:property value='couponBuy.bookPhone'/>" name="bookPhone" id="coupon-order-r3-desc" >
然后在Action中自己手工注入到couponBuy对象中..采取了这种临时的解决方案
2 后续的跟进
新建了新的web工程,进行测试,努力模拟当时的情况,在什么情况下会出现这种无法注入的情况.经过一番折腾.终于发现元凶.元凶的代码是
public CouponBuy getCouponBuy() {
if (couponBuy == null) {// 表示是新增操作,必须首先赋值CategoryId
couponBuy = new CouponBuy();
couponBuy.setCategoryId(CouponBuyUtil.getCategoryId());
couponBuy.setPublishUserName(this.getUser().getUserName());
}
return couponBuy;
}
很明显,上面这个是couponBuy对象的get方法.一般来说,struts2在依赖注入的时候会先调用这个方法(由于业务逻辑需要,所以必须自己去创建couponBuy对象).但是我注意到,运营在修改couponBuy对象的时候是不需要登录的!!也就是说,照理来说,这里应该会报一个空指针异常..根据这个情况,进行模拟.
pojo类
/**
* @author zhenghui
* @version 1.0
* @date 2011-6-2 下午04:57:47
*
*/
public class CouponBuy implements Serializable{
/**
*
*/
private static final long serialVersionUID = -3869627789513451015L;
private String bookPhone;
private String name;
private String descrbtion;
private String abc;
// get set 方法略
}
对应的Action
package com.koubei.action;
import com.koubei.pojo.CouponBuy;
import com.opensymphony.xwork2.ActionSupport;
/**
* @author zhenghui E-mail: zhenghui.cjb@taobao.com
* @version 1.0
* @date 2011-6-2 下午04:36:37
*
*/
public class SubmitAction extends ActionSupport {
/**
*
*/
private static final long serialVersionUID = 6074612093907655532L;
private CouponBuy couponBuy;
@Override
public String execute() throws Exception {
System.out.println(couponBuy.getBookPhone());
System.out.println(couponBuy.getName());
System.out.println(couponBuy.getDescrbtion());
System.out.println(couponBuy.getAbc());
return super.execute();
}
public CouponBuy getCouponBuy() {
if(couponBuy == null){
couponBuy = new CouponBuy();
throw new NullPointerException();
}
return couponBuy;
}
public void setCouponBuy(CouponBuy couponBuy) {
this.couponBuy = couponBuy;
}
}
直接抛出空指针异常,然后传入对应的参数
http://localhost/WebTest/submit.html?couponBuy.name=name&couponBuy.descrbtion=desc&couponBuy.bookPhone=05714788339&couponBuy.abc=abc
结果是
05714788339
name
desc
null
也就是说,abc参数丢失了!!.问题在于:
1 传入4个参数,但是couponBuy.abc 这个参数丢失了!其他都正常
2 最大的问题是,竟然没有报错的日志!!console下没有,结果页也是正常的,就是没这个参数而已...
问题终于发现,就是由于struts2在给我们做对象的注入的时候,会把空指针异常给吃了.然后会把某一个参数注入为Null.但是其他的参数都注入正常.
3 继续查看问题
这个问题虽然解决了,但是还是引出了其他几个问题.
(1)是否高版本的struts2还存在这个问题
(2)那个丢失的参数,规则是什么..
后续的解决
(1)这个问题我换成struts2.2.1版本来跑同样的程序.发现console日志输出里已经报了空指针异常.也就是说,高版本中这个吃异常的BUG已经修正了.但是还是会将某一个参数制空,其他参数正确传入.
(2)经过测试,struts2的规则是根据对象属性进行排序,在第一个注入的就会制空,后面注入的参数能正确被注入.比如上面的属性中 abc < bookPhone 所以abc首先被注入,所以丢失数据.如果我把abc属性删除,则bookPhone参数是最小的,则这个参数首先被注入,也就之前我在项目中遇到的丢失问题...
4 最后的总结.
struts2关于标签部分的代码没看,所以无法从根本上总结出这个BUG的所在..等待后人研究了..看源码的话没有这么快搞定..
分享到:
相关推荐
struts2.0.14官方jar包 struts2.0.14官方jar包 struts2.0.14官方jar包 struts2.0.14官方jar包 struts2.0.14官方jar包
struts2.0.14 是根据 Struts2.0.14的官方文档生成
struts2.0.14_apps struts 2.0.14 apps 示例应用
struts2.0.14-src struts2.0.14 源代码
这个是我利用struts2.0.14的官方源代码和相关工具生成的chm文件,希望能给需要的人带来福音。
[Struts2.0.14.API].Struts2.0.14.API 英文版
struts1.3.10 和 struts2.0.14 包
struts 2.0.14-lib struts 2.0.14核心类库
包含Struts2框架的核心类库,以及Struts2的第三方插件类库 struts2-core-2.0.14 xwork-2.0.7 ognl-2.6.11 commons-logging-1.0.4 freemarker-2.3.8 等等。
struts2.0.14-src struts2.0.14 源代码
Struts 2.0.14 API Struts 2.0.14 API Struts 2.0.14 API
我以人格保证我这个文档可以使用,由于原文档太大,故把docs去掉了,其余全部保存
struts2.0.14 api 最新 索引 chm
Struts2.0.14 API CHM
struts-2.0.14jar包源码,可以用来查询里面的类的具体实现
最简单的源码,一看就明白的配置,struts2初学者入门
struts2.0.14src struts 2.0.14 src 源码
最新版struts2包,官方网站http://struts.apache.org/download.cgi#struts20111
ssh框架应用中,struts2的这个版本较稳定,特意跟大伙分享。由于只能上传小于60M的文件,并没有把struts-2.0.14-all中struts文档(即,docs文件夹)一并上传,其他部分(lib,src,apps)均在内,进行web项目开发...
struts2.0.14.jap 架包 rar(完整的)