最近小玩Struts。改造项目。
在测试时两次发现
javax.servlet.ServletException: BeanUtils.populate
java.lang.IllegalArgumentException: argument type mismatch异常。
第一次,是由于在Form中定义的是String[] somethingID数组类型,而在jsp中定义的是
<html:hidden property="somethingID"/>,导致类型不匹配,从而出现异常。
第二次出现,原因比较隐蔽。容我慢慢道来。
两个画面,SomeList.jsp 和Some.jsp,分别对应SomeListForm,SomeListAction.java 和 SomeForm,SomeChangeAction.java。功能就是打开SomeList.jsp画面,选择某条Some进入SomeChange.jsp,修改好后返回SomeList.jsp。为了修正Session问题,在Some.jsp中添加了<html:hidden property="somethingID"/>,然后上面异常就发生了。
历经挫折,跋山涉水后找到原因。在SomeListForm中有属性String[] somethingID,数组类型,在SomeForm中有属性String somethingID是单值String类型,名字一致类型不一样。
当SomeChangeForm返回SomeListForm的时候,会将somethingID的值传回。这时候就发生类型不匹配异常了。根本原因在于,配置struts-config.xml的时候,
<action attribute="someForm" input="/form/somechange.jsp" name="someForm"
path="/somechange" type="com.somecorp.struts.action.SomeChangeAction">
<forward name="display" path="/form/somechange.jsp" />
<forward name="return" path="/somelist.do" />
</action>
高亮这行没有设置 redirect="true",这样的话,返回时就会将上个Form的值返回从而导致不匹配异常。
- 一般来说,这时候的Form是不需要将值返回的,改成<forward name="return" path="/somelist.do" redirect="true"/>就可以了。要注意其他参数的传递。
- 还有个改法就是将两个Form中同名不同类型的属性改个名字也可以。
==========打酱油的分割线====================
对于redirect="true"不理解的可以参考下面这段:
在ActionForward中有一个重要的属性redirect,当redirect=false时,将保存存储在http请求和请求上下文中的所有内容,仅在同一个应用中可用。当redirect=true时,Web客户端进行一次新的http请求,请求的资源可以在同一个应用中,也可以不在,原来的请求参数不再保存,原来的请求上下文也被清除,新的http请求仅包含ActionForward的path属性里所包含的参数。如果在同一个应用中,用户会话的上下文会被维护。