今天在看JPetStore代码时,对他的链接中的请求参数感到疑惑,最后发现是自己的对Struts框架不熟悉导致的。
我是从Net阵营中刚转入Java里的,在Net中对请求参数的名称无特殊限制,只要在页面中取参数的值即可。当然这个功能在Java中也具备。即request.Getparameter()
今天我在看JpetStore代码时,在点击
http://127.0.0.1:8083/JPetStore/shop/viewCategory.shtml?categoryId=BIRDS时,当跟踪函数viewCategory时发现此时categoryID已经赋值了,我却找不到在什么地方赋值的,好是花费了一番周执。
查看此段链接对应的struts.xml
<action path="/shop/viewCategory" type="org.apache.struts.beanaction.BeanAction"
name="catalogBean" scope="session"
validate="false">
<forward name="success" path="/catalog/Category.jsp"/>我首先跟踪BeanAction的excute函数发现在此之前就已经赋值,说明和BeanAction无关,是Struts系统本身的结构。我故意将链接修改,修改成
http://127.0.0.1:8083/JPetStore/shop/viewCategory.shtml?category=BIRDS此时出现错误,错误如下:
java.lang.IllegalArgumentException: Cannot invoke com.ibatis.jpetstore.presentation.CatalogBean.setCategory - argument type mismatch
org.apache.commons.beanutils.PropertyUtilsBean.invokeMethod(PropertyUtilsBean.java:1778)
org.apache.commons.beanutils.PropertyUtilsBean.setSimpleProperty(PropertyUtilsBean.java:1759)
org.apache.commons.beanutils.PropertyUtilsBean.setNestedProperty(PropertyUtilsBean.java:1648)
org.apache.commons.beanutils.PropertyUtilsBean.setProperty(PropertyUtilsBean.java:1677)
org.apache.commons.beanutils.BeanUtilsBean.setProperty(BeanUtilsBean.java:1022)
org.apache.commons.beanutils.BeanUtilsBean.populate(BeanUtilsBean.java:811)
org.apache.commons.beanutils.BeanUtils.populate(BeanUtils.java:298)
org.apache.struts.util.RequestUtils.populate(RequestUtils.java:493)
org.apache.struts.action.RequestProcessor.processPopulate(RequestProcessor.java:805)
org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:203)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1194)
org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:414)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
根据这个错误堆栈可知,它实际上采用的是反射,setProperty,此时找不到category的Setter函数报错。然后我查看了一下RequestProcessor的默认实现代码
// Process any ActionForm bean related to this request
ActionForm form = processActionForm(request, response, mapping);
processPopulate(request, response, form, mapping); 这段函数功能为:
1)调用processActionForm( )方法检查是否存在为ActionMapping配置的ActionForm 。如果存在,则在有效区
域内查找是否存在该ActionForm 的实例,存在,则复用,不存在,则创建一个实例。然后将实例保存与再配置
文件中配置好的有效区域(request,session,application)内,并用Action元素的name属性作为该实例的关键字。
2)调用processPopulate( )方法,如果存来存在为ActionMapping配置的ActionForm,则封装请求对象中的数据
到ActionForm 中,在进行封装之前,先调用ActionForm 的reset( )方法进行属性值的默认化。
根据以上的分析,可得知,在调用链接前struts框架会自动的将所有的请求参数封装入指定的formbean中。所以请求参数的名称应该是对应formbean的一个属性。
这就是struts中请求参数的处理过程。主要是我对struts还没有完全掌握,加上Net的影响,才花费了一圈发现这个原因。
posted on 2007-01-15 20:56
涤生 阅读(962)
评论(0) 编辑 收藏