struts1之LocaleAction、DynaActionForm

来源:互联网 发布:翻译证书 知乎 编辑:程序博客网 时间:2024/06/17 12:07

    今天被Struts1.3中的DynaActionForm害惨了!

    想用Struts1提供的LocaleAction来实现在页面中点击链接改变Locale信息,实现国际化。通过查看源代码,可以知道LocaleAction中使用到了language、country、page三个属性,分别表示语言、国家及改变Locale信息后跳转的页面。通过页面传递的参数,创建一个Locale,并将它存入session中来实现动态改变Locale。注意,在LocaleAction中获取那三个属性是使用PropertyUtils.getSimpleProperty(form, "page")来实现的,而不是直接从关联的actinForm中获取。

    于是,本着想多学点知识的想法,我就使用了DynaActionFrom,在struts-config.xml中配置了一个DynaActionFrom,

<form-bean name="localeForm" type="org.apache.struts.action.DynaActionForm">
            <form-property name="language" type="java.lang.String"></form-property>
            <form-property name="country" type="java.lang.String"></form-property>
            <form-property name="page" type="java.lang.String"></form-property>
</form-bean>

配置了一个改变Locale信息的action,

<action path="/changeLocale" type="org.apache.struts.actions.LocaleAction" name="localeForm" scope="request" validate="false">
           <forward name="success" path="/WEB-INF/pages/login.jsp"></forward>

 </action>

从LocaleAction的源代码中

if (null == page) {
            return mapping.findForward("success");
        } else {
            return new ActionForward(page);
        }

可以看出,如果配置了page属性,则跳转到page指定的页面,如果page为null,则会跳转到一个叫success的视图,因此我配了一个success视图,打算不传递page属性。

在页面中写了两个连接,用于传递参数改变Locale信息,没有传递page属性:

<html:link action="changeLocale?language=zh&country=CN">中文</html:link>

<html:link action="changeLocale?language=en&country=US">英文</html:link>

结果在测试时报了java.lang.IllegalArgumentException: Path fillinfo does not start with a "/" character的错,检查了下,该加“/”的地方都加了,还是没解决。于是用Debug跟踪了下,发现执行到LocaleAction中跳转代码

if(null == page) {
            return mapping.findForward("success");
        } else {
            return new ActionForward(page);
        }

时,page=“”,而不是null,因此没有找success视图,而是跳转到page,而page我没有传值,为“”。可是为什么page会是“”,而不是null呢?记得formBean中的属性int类型默认值为0,对象默认值为null,因此这个page属性的值应该为null啊。然后就继续追踪源代码,LocaleAction是通过PropertyUtils.getSimpleProperty(form, "page")来获取属性值得,在getSimpleProperty方法中代码为PropertyUtilsBean.getInstance().getSimpleProperty(bean, name);继续查看PropertyUtilsBean中的getSimpleProperty方法,发现有句代码if (bean instanceof DynaBean) ,然后看到DynaActionFrom的方法签名为public class DynaActionForm extends ActionForm implements DynaBean,因此我在配置文件中配的localeForm是DynaBean的实例,然后通过((DynaBean) bean).get(name)方法去找page对应的值。那么就来看get方法中的代码,在DynaActionFrom的get方法中,在这里代码就有点看不懂了,方法先从一个HashMap中找page对应的值,如果找到了就直接返回,如果找到的值为空则Class type = getDynaProperty(name).getType();在根据type的类型判断,返回值,反正这边就看不大懂了,希望有懂的人指点一下,为什么最终page的值成了“”,而不是null。

    反正看到这,大概知道DynaActionFrom与普通的ActionForm是有区别的,于是,我将DynaActionFrom换成了ActionForm,自己写了个LocaleForm,继承ActionForm,

<form-bean name="localeForm" type="com.jiangnan.struts.form.LocaleForm"></form-bean>

同样没传page值,这次Debug的时候page属性的值就是null,也成功改变了Locale的信息,没有报错!

希望有明白的高手指点一下上面提到的get方法中的源代码,page的值为什么是“”而不是null!