??xml version="1.0" encoding="utf-8" standalone="yes"?>国产成人精品一区二区三区免费,欧美日韩伦理片,亚洲国产精品久久久久秋霞不卡http://www.aygfsteel.com/kook/category/15630.htmlzh-cnFri, 02 Mar 2007 03:11:31 GMTFri, 02 Mar 2007 03:11:31 GMT60Validator验证框架http://www.aygfsteel.com/kook/articles/71821.htmlkookkookMon, 25 Sep 2006 12:50:00 GMThttp://www.aygfsteel.com/kook/articles/71821.htmlhttp://www.aygfsteel.com/kook/comments/71821.htmlhttp://www.aygfsteel.com/kook/articles/71821.html#Feedback0http://www.aygfsteel.com/kook/comments/commentRss/71821.htmlhttp://www.aygfsteel.com/kook/services/trackbacks/71821.htmlStruts1.2中创建验证框架的步骤Q?br />
1、在struts-config.xml文g中添加下列内容:(x)
< plug - in (tng)className = " org.apache.struts.validator.ValidatorPlugIn " >
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
< set - property (tng)property = " pathnames "  (tng)value = " /WEB-INF/validator-rules.xml,
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)/WEB-INF/validation.xml
"  (tng) />

</ plug - in >

注意Q这些内容必L?lt;message-resources>元素之后。该规则是由
"
http://struts.apache.org/dtds/struts-config_1_2.dtd "文g制定的?br />
2、创建相关的lgQ?br />
Z(jin)实验的目的,我依ơ创?个ActionFormc,一个JSPQ一个Actionc,以下是他们在struts-config.xml中的配置信息Q?br />
 (tng)1 (tng)<form-beans (tng)>
 (tng)2 (tng) (tng) (tng) (tng) (tng)<form-bean (tng)name="DVForm" (tng)type="org.apache.struts.validator.DynaValidatorForm">
 (tng)3 (tng) (tng) (tng) (tng) (tng) (tng) (tng)<form-property (tng)name="name" (tng)type="java.lang.String" (tng)/>
 (tng)4 (tng) (tng) (tng) (tng) (tng)</form-bean>
 (tng)5 (tng) (tng) (tng) (tng) (tng)<form-bean (tng)name="DVAForm" (tng)type="org.apache.struts.validator.DynaValidatorActionForm">
 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng)<form-property (tng)name="name" (tng)type="java.lang.String" (tng)/>
 (tng)7 (tng) (tng) (tng) (tng) (tng)</form-bean>
 (tng)8 (tng) (tng) (tng) (tng) (tng)<form-bean (tng)name="VForm" (tng)type="com.kook.struts.form.HahaForm" (tng)/>
 (tng)9 (tng) (tng) (tng) (tng) (tng)<form-bean (tng)name="VAForm" (tng)type="com.kook.struts.form.HohoForm" (tng)/>
10 (tng) (tng) (tng)</form-beans>
11 (tng)
12 (tng) (tng) (tng)<global-exceptions (tng)/>
13 (tng) (tng) (tng)<global-forwards (tng)/>
14 (tng) (tng) (tng)<action-mappings (tng)>
15 (tng) (tng) (tng) (tng) (tng)< action
16 (tng) (tng) (tng) (tng) (tng) (tng) (tng)attribute="DVForm"

17 (tng) (tng) (tng) (tng) (tng) (tng) (tng)input="/form/index.jsp"
18 (tng) (tng) (tng) (tng) (tng) (tng) (tng)name="DVForm"
19 (tng) (tng) (tng) (tng) (tng) (tng) (tng)path="/index"
20 (tng) (tng) (tng) (tng) (tng) (tng) (tng)scope="request"
21 (tng) (tng) (tng) (tng) (tng) (tng) (tng)type="com.kook.struts.action.IndexAction" (tng)/>
22 (tng) (tng) (tng)</action-mappings>

其中
<form-bean name="VForm" type="com.kook.struts.form.HahaForm" />是ValidatorFormcȝ子类
<form-bean name="VAForm" type="com.kook.struts.form.HohoForm" />是ValidatorActionFormcȝ子类

下面是JSP面代码Q?br />
1 (tng)<html:form (tng)action="/index" (tng)onsubmit="return (tng)validateDVForm(this)">
2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)name (tng): (tng)<html:text (tng)property="name"/><html:errors (tng)property="name"/><br/>
3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<html:submit/>
4 (tng) (tng)</html:form>
5 (tng) (tng)<html:javascript (tng)formName="DVForm"/>

因ؓ(f)只是做表单验证,actioncd以不用涉?qing),因此不列出actioncȝ代码啦!

3、删除name="VForm" 和name="VAForm"的ActionForm中的validateҎ(gu)?br />
因ؓ(f)q两个类不是动态的验证c,在用向导生成代码的时候会(x)自动覆盖父类的validateҎ(gu)。如果不删除的话Q根据类的多态性原理,?x)调用他们生成的validateҎ(gu)Q而不调用他们父类的该Ҏ(gu)。但是,实际上,是他们父cȝvalidateҎ(gu)调用?jin)validator框架的验证方法,因此我们没有必要再去重写他的q个Ҏ(gu)。同时也要记得删除,因ؓ(f)向导生成的是I实玎ͼ不删除的话,起不到验证作用。切记切讎ͼQ!曄在这吃啊担子_(d)Q?

观察以上代码不难发现Q表单中只有一个文本框Q因此实验也是对q个文本框进行验证?br />
4、创定义的验证文件validation.xmlQ主要内容如下所C:(x)
 (tng)1 (tng)<form-validation>  (tng) (tng) (tng) (tng)
 (tng)2 (tng) (tng) (tng) (tng) (tng)<formset>

 (tng)3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<form (tng)name="DVForm">
 (tng)4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<field (tng)property="name" (tng)depends="required">
 (tng)5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<arg0 (tng)name="required" (tng)key="lable.name"/>
 (tng)7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</field>
 (tng)8 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</form>
 (tng)9 (tng) (tng) (tng) (tng) (tng)</formset>
10 (tng)</form-validation>

其中key="lable.name "在资源文件中对应的内容ؓ(f)Qlable.name=nameQ因此,当文本框中没有输入Q何信息而提交的时候,会(x)反馈一条name is required.的信息?br />
下面开始实验,
实验的目的是Q依ơ?U验证Form来实现表单的验证功能Q?br />他们分别是:(x)DynaValidatorFormQDynaValidatorActionFormQValidatorFormQValidatorActionForm。这也是前面Z么要创徏4个ActionForm的目的,详细配置信息见前面struts-config.xml
而JSP面只有一个,是配置文g中的input="/form/index.jsp
"

实验一Q由DynaValidatorForm的子cDVForm来验?br />


validation.xml的内容ؓ(f)Q?br />
 (tng)1 (tng)<form-validation>  (tng) (tng) (tng) (tng)
 (tng)2 (tng) (tng) (tng) (tng) (tng)<formset>

 (tng)3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<form (tng)name="DVForm">
 (tng)4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<field (tng)property="name" (tng)depends="required">
 (tng)5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<arg0 (tng)name="required" (tng)key="lable.name"/>
 (tng)7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</field>
 (tng)8 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</form>
 (tng)9 (tng) (tng) (tng) (tng) (tng)</formset>
10 (tng)</form-validation>

struts-config.xml的内容ؓ(f)Q?br />
15 (tng) (tng) (tng) (tng) (tng)< action
16 (tng) (tng) (tng) (tng) (tng) (tng) (tng)attribute="DVForm"

17 (tng) (tng) (tng) (tng) (tng) (tng) (tng)input="/form/index.jsp"
18 (tng) (tng) (tng) (tng) (tng) (tng) (tng)name="DVForm"
19 (tng) (tng) (tng) (tng) (tng) (tng) (tng)path="/index"
20 (tng) (tng) (tng) (tng) (tng) (tng) (tng)scope="request"
21 (tng) (tng) (tng) (tng) (tng) (tng) (tng)type="com.kook.struts.action.IndexAction" (tng)/>
22 (tng) (tng) (tng)</action-mappings>

/form/index.jsp的主要内容ؓ(f)Q?br />
1 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<html:javascript (tng)formName="DVForm"/>
2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<html:form (tng)action="/index" (tng)onsubmit="return (tng)validateDVForm(this)">

<
html:javascript (tng)formName = " DVForm " />的formName属性对应的是进行验证的ActionForm的name属性?font style="BACKGROUND-COLOR: #ffffff">onsubmit="return (tng)validateDVForm(this)"为固定写法,格式为:(x)onsubmit="return (tng)validateXXX(this)"QXXX为Form的name属性,其中首字母大写就可以?jin)?br />

实验二:(x) 由ValidatorForm的子cVForm来验?br />
他的配置信息只需要将实验一中底色ؓ(f)黄色高(sh)部分的DVForm换成VForm可以了(jin)Q他们的区别只在于一个是动态的Q一个是非动态的?br />

实验?由DynaValidatorActionForm的子cDVAForm来验?br />
该实验的配置信息只需要将实验一struts-config.xml中底色ؓ(f)黄色高(sh)部分的DVForm换成DVAForm可以了(jin)Q其ơ是修改validation.xml的内?具体如下Q?br />
1 (tng)<form-validation> (tng) (tng) (tng) (tng)
2 (tng) (tng) (tng) (tng) (tng)<formset>
3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<form (tng)name="/index">
4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<field (tng)property="name" (tng)depends="required">
5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<arg0 (tng)name="required" (tng)key="lable.name"/>
6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</field>
7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</form>
8 (tng) (tng) (tng) (tng) (tng)</formset>
9 (tng)</form-validation>

区别?font style="BACKGROUND-COLOR: #ffff00"><form (tng)name="/index">中的name属性不再对应的是验证Form的name属性,而是其相对的actioncȝpath属?br />
实验四:(x)由ValidatorActionForm的子cVAForm来验?br />
与实验三一P换掉struts-config.xml中底色ؓ(f)黄色高(sh)部分的DVAForm换成VAForm可以了(jin)Qvalidation.xml文g中的内容与实验三保持一_(d)<form (tng)name="/index">中的name属性不再对应的是验证Form的name属性,而是其相对的actioncȝpath属性?br />
不过用DynaValidatorActionForm和ValidatorActionForm的时候好象不能用客L(fng)验证Q只能用服务器端验证。还得有高手指点Q因此前台JSP面得改成:(x)

1 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<html:form (tng)action="/index">
2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)name (tng): (tng)<html:text (tng)property="name"/><html:errors (tng)property="name"/><br/>
3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<html:submit/>
4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</html:form>

下面来介l一下validation.xml文g中的一些元素信息:(x)

1?lt;global>中定义的<constant>?lt;formset>中定义的<constant>
前者表C在全局范围内定义常量,可以在validation.xml文g中的其他<formset>中访问。访问格式ؓ(f)${constantName}
后者表C局部的帔R定义Q只能在声明他的<formset>中用?br />
2?lt;field>元素中的几个子元素:(x)
<!ELEMENT field (msg|arg|arg0|arg1|arg2|arg3|var)*>
也就是说他的所有子元素都可以是0-n个,q一点和孙卫琴的书有出入Q以此ؓ(f)准?br />
msg元素
<msg name="" key="" bundle="" resource=""/>

nameQ表C验证规则的逻辑名;
keyQ对应资源文件中的keyQ?br />bundleQ指定从哪个资源文g获取key|~省时ؓ(f)默认的资源文Ӟ
resourceQؓ(f)true是表CZ资源文g中获取key属性对应的信息Qؓ(f)false时表C直接显Ckey属性的内容Q和资源文g无关。缺省ؓ(f)true?br />
Strust框架中指定了(jin)一些常用规则的对应文本Q验证框枉认是从这些对应的文本中读取信息。但是我们可以通过指定msg元素来从自定义的资源文g或者是key中来获取消息?br />
arg.....元素用来指定复合文本中的参数Q依ơ对应。他们的属性和msg的属性很怼Q用法也是一L(fng)?br />
var元素
 (tng)1 (tng) (tng) (tng) (tng) (tng)<formset>
 (tng)2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<form (tng)name="/index">
 (tng)3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<field (tng)property="name" (tng)depends="required">
 (tng)4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<arg0 (tng)name="required" (tng)key="${var:required}" (tng)resource="false"/>
 (tng)5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<var>
 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<var-name>required</var-name>
 (tng)7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<var-value>xx</var-value>
 (tng)8 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</var>
 (tng)9 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</field>
10 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)</form>
11 (tng) (tng) (tng) (tng) (tng)</formset>


如果执行?jin)该验证的话Q输出的l果为:(x)xx is required.








kook 2006-09-25 20:50 发表评论
]]>
Struts学习(fn)W记http://www.aygfsteel.com/kook/articles/71710.htmlkookkookMon, 25 Sep 2006 04:26:00 GMThttp://www.aygfsteel.com/kook/articles/71710.htmlhttp://www.aygfsteel.com/kook/comments/71710.htmlhttp://www.aygfsteel.com/kook/articles/71710.html#Feedback0http://www.aygfsteel.com/kook/comments/commentRss/71710.htmlhttp://www.aygfsteel.com/kook/services/trackbacks/71710.html  (tng)

一?/span> 如何获得 ApplicationResources.properties 中的信息


1
、获得默认的资源文g

1 (tng)MessageResources (tng)messages (tng)=  (tng)getResources(request);
2 (tng)

3 (tng)String (tng)title (tng)= (tng)messages.getMessage("hello.jsp.title" );
4 (tng)



2
、获得默认的资源文g

1 (tng)MessageResources (tng)resources (tng)=  (tng)(MessageResources) (tng)request.
2 (tng)

3 getAttribute(Globals.MESSAGES_KEY);
4 (tng)



3
、获得指?span lang="EN-US">key的资源文?/font>

MessageResources (tng)messages (tng) =  (tng)getResources(request, " en " );

 (tng)

其实Ҏ(gu)一本质上就是调用方法二来获?/span> MessageResources 的实例?span lang="EN-US">

首先获得一个封装了(jin) ApplicationResources.properties 信息

的对?/span> MessageResources 的实?span lang="EN-US">messagesQ然后调?span lang="EN-US">getMessage(key);来获?span lang="EN-US">key的?span lang="EN-US">

二?/span> 如何打包发布一?span lang="EN-US">WEB应用

?span lang="EN-US">DOC下{到应用的根目录执?span lang="EN-US">jar cvf appName.war *.*

三?/span> 如何?span lang="EN-US">formbean下验证表?span lang="EN-US">

 (tng)

 (tng)1 (tng)ActionErrors (tng)errors (tng)= (tng)new  (tng)ActionErrors();
 (tng)2 (tng)

 (tng)3 (tng) (tng) (tng) (tng) (tng)String (tng)array[] (tng)= (tng)new (tng)String[2 ];
 (tng)4 (tng)

 (tng)5 (tng) (tng) (tng) (tng) (tng)array[0] (tng)= (tng)"xx" ;
 (tng)6 (tng)

 (tng)7 (tng) (tng) (tng) (tng) (tng)array[1] (tng)= (tng)"hh" ;
 (tng)8 (tng)

 (tng)9 (tng) (tng) (tng) (tng) (tng)if(name==null (tng)|| (tng)name.length()<1 )
10 (tng)

11 (tng)  (tng) (tng) (tng) (tng){
12 (tng)

13 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)errors.add("name",new (tng)ActionMessage("kong",false ));
14 (tng)

15 (tng) (tng) (tng) (tng) (tng)//对应的key为hello,且hello为动态复合消息,array数组用来替换复合消息中的参数
16 (tng)
17 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)errors.add("name",new (tng)ActionMessage("hello" ,array));
18 (tng)

19 (tng)  (tng) (tng) (tng) (tng)}
20 (tng)

21 (tng)return  (tng)errors;
22 (tng)

23 (tng)

 (tng)

?span lang="EN-US">inputJSP中用 <html:errors/> 获取q显C?span lang="EN-US">

 (tng)

四?/span> ?span lang="EN-US">action下处理业务逻辑时返回的错误信息

 (tng)1 (tng)ActionErrors (tng)errors (tng)= (tng) new (tng)ActionErrors();
 (tng)2 (tng)

 (tng)3
 (tng)String (tng)userName (tng) = (tng)(String)((HelloForm) (tng)form).getUserName();
 (tng)4 (tng)

 (tng)5
 (tng)  (tng)
 (tng)6 (tng)

 (tng)7
 (tng)String (tng)badUserName (tng)= (tng)"Monster ";
 (tng)8 (tng)

 (tng)9
 (tng)  (tng)
10 (tng)

11
 (tng) if (tng)(userName.equalsIgnoreCase(badUserName)) (tng){
12 (tng)

13
 (tng) (tng) (tng) (tng) (tng) (tng)errors.add("username", (tng)new (tng)ActionError("hello.dont.talk.to.monster ", (tng)badUserName (tng)));
14 (tng)

15
 (tng) (tng) (tng) (tng) (tng) (tng)saveErrors(request, (tng)errors); (tng) (tng) (tng) (tng) (tng) (tng) (tng)// l定到request对象?br />16 (tng)
17
 (tng) (tng) (tng) (tng) (tng) (tng)return (tng)( new (tng)ActionForward(mapping.getInput()));
18 (tng)

19
 (tng)  (tng)}
20 (tng)


同样在相应的JSP面中用?lt;html:errors/>
获取q显C?br />

 (tng)

五?/span> JSP 中如何访?span lang="EN-US">action

1 ?br />

< A (tng)href = " <%=request.getContextPath() (tng)%>/hello.do " > Link </ A >

 (tng)

2 、自动蟩?br />


 (tng) (tng) (tng)
A_JSP
面Q?span lang="EN-US">

< logic:forward (tng)name = " gaga " />


B_struts-config.xml
讄Q?br />


< global - forwards (tng) >

 (tng) (tng) (tng) (tng) (tng) (tng)<
forward (tng)name = " gaga "  (tng)path = " /hello.do " ></ forward
>

</
global - forwards >


六?/font>
配置错误面和异帔R面:(x)《精?span lang="EN-US">Struts?/font> page_75


七?/font>
如何?span lang="EN-US">Web应用中访?span lang="EN-US">Locale对象


1
、什么是LocaleQ?br />
java.util.Locale cȝ实例代表一U特定的语言环境和地?br />


2
如何获得LocaleQ?span lang="EN-US">

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) 构造函?span lang="EN-US">

Locale (tng)locale (tng) =  (tng) new  (tng)Locale( " en " , " US ");
Locale (tng)locale (tng)
=  (tng) new  (tng)Locale( " ch " , " CH " );


̔ (tng) (tng) (tng) (tng)
讉Kjava.util.Localecȝ?rn)态常量来获得常用?/span> Locale 实例

Locale (tng)locale (tng) =  (tng)Locale.CHINA; (tng) (tng) (tng) (tng) (tng)(zh_CN)
Locale (tng)locale (tng)
=  (tng)Locale.CHINESE; (tng) (tng) (tng)(zh)

̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng) 通过HttpServletRequest对象来获得客L(fng)?span lang="EN-US">Locale

Locale (tng)locale (tng) =  (tng)request.getLocale(); (tng) (tng) (tng)// 获得优先使用?/span>Locale
System.out.println(locale);

 (tng)

// 获得所有LocaleQ从优先U高的依ơ降序排列ƈ打印出来?/span>
Enumeration (tng)locales (tng) =  (tng)request.getLocales();

while
 (tng)(locales.hasMoreElements()) (tng){
 (tng) (tng) (tng) (tng) (tng) (tng)Locale (tng)element (tng)
=
 (tng)(Locale) (tng)locales.nextElement();
 (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(element);
}


̔ (tng) (tng) (tng) (tng) (tng) (tng) (tng)
通过HttpSession对象来获?span lang="EN-US">Locale

HttpSession (tng)session (tng) =  (tng)request.getSession();

Locale (tng)locale (tng)
=
 (tng)(Locale) (tng)session.

getAttribute(Globals.LOCALE_KEY);

System.out.println(locale);

 (tng)

获得Locale的方法还有很多,其实?span lang="EN-US">Web应用中,很多获得Locale的方法都是不同程度的或者是直接的或者是间接在调?/span> request.getLocale(); Ҏ(gu)。因此有?/span> HttpServletRequest Q我们可以做很多事情?span lang="EN-US">



kook 2006-09-25 12:26 发表评论
]]>
ActionMessagescd(qing)其绑定的lghttp://www.aygfsteel.com/kook/articles/71626.htmlkookkookSun, 24 Sep 2006 18:54:00 GMThttp://www.aygfsteel.com/kook/articles/71626.htmlhttp://www.aygfsteel.com/kook/comments/71626.htmlhttp://www.aygfsteel.com/kook/articles/71626.html#Feedback0http://www.aygfsteel.com/kook/comments/commentRss/71626.htmlhttp://www.aygfsteel.com/kook/services/trackbacks/71626.html 首先来了(jin)解一下ActionMessagescȝl构Q?br />



在ActionMessages中包含着一个HashMapQ其中的key是addҎ(gu)的property参数Q然而他的值对应的是一个ActionMessageItem,ActionMessageItem是该cȝ一个内部类Q当中包含了(jin)一个ArrayList?br />由此可见Q一个property中可以包含着多个ActionMessage,q些ActionMessage都将保存在ActionMessageItem的ArrayList中?br />

 (tng)1 (tng)public (tng)void  (tng)add(String (tng)property, (tng)ActionMessage (tng)message) (tng){
 (tng)2 (tng)

 (tng)3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)ActionMessageItem (tng)item (tng)=  (tng)(ActionMessageItem) (tng)messages.get(property);
 (tng)4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)List (tng)list (tng)= (tng)null
;
 (tng)5 (tng)

 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if (tng)(item (tng)== (tng)null ) (tng){
 (tng)7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)list (tng)= (tng)new
 (tng)ArrayList();
 (tng)8 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)item (tng)= (tng)new (tng)ActionMessageItem(list, (tng)iCount++
, (tng)property);
 (tng)9 (tng)

10 (tng)  (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)messages.put(property, (tng)item);
11 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)} (tng)else
 (tng){
12 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)list (tng)=
 (tng)item.getList();
13 (tng)
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
14 (tng)

15 (tng)  (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)list.add(message);
16 (tng)

17 (tng) (tng) (tng) (tng) (tng)}



每次d新的ActionMessage中,ActionMessagescM(x)判断HashMap中的get(property)是否存在Q如果存在的话,p得该list (tng)= (tng)item.getList();q把ActionMessaged到其中。如果不存在Q就?x)创Z个新的list (tng)= (tng)new  (tng)ArrayList();
再将内容d到当中去。ȝ来说QActionMessages是一个保存(sh)息的容器。通常ActionMessages是不?x)单独用的Q和他相关的一些Strutslg?x)对其进行访问和操作Q?br />
<html:errors>标签

<html:errors>标签是一个StrutslgQ他的内部标{对ActionMessagescȝ子类ActionErrorsq行讉K。通过在request和session中找到ActionErrors来获得相关信息。在此之前,先来?jin)解?lt;html:errors>标签的几个重要属性:(x)

name属性:(x)
指定ActionMessages在request和session范围内的属性key.默认gؓ(f)Globals.ERROR_KEY。由此我们可以了(jin)解到Struts是如此保存和获取ActionMessages的:(x)

保存Q?br />ActionErrors errors = new ActionErrors();

request.setAttribute(Globals.ERROR_KEY ,errors);或?br />
session.setAttribute(Globals.ERROR_KEY ,errors);

获取Q?br />ActionErrors errors = new ActionErrors();

errors = (ActionErrors)request.getAttribute(Globals.ERROR_KEY);或?br />
errors = (ActionErrors)session.getAttribute(Globals.ERROR_KEY);或?br />
该属性通常我们不用讄和更改他Q用默认值就可以啦?br />
property属性:(x)
用来指定消息的属性,如果不设|该属性,那么<html:errors>标签显CActionMessages中的所有属性。如果设|了(jin)该属性,则只昄HashMap中Key为property属性值的ArrayList集合。通常Q我们在调用ActionMessages的addҎ(gu)Ӟ?x)指定addҎ(gu)的property参数Q也是W一个参敎ͼ相关信息添加到指定的property对应的ArrayList中。那么我们要昄相关信息Ӟ可以指定输?lt;html:errors>标签的property属性对应的ArrayListQ这两个property是相互对应的?br />
bundle属性:(x)
指定资源文g的key属性。缺省的情况下调用的是默认的资源文gApplication.properties?br />如在struts-config.xml中声明的资源文g信息如下Q?/font>

 (tng) < message - resources (tng)parameter = " com.kook.struts.ApplicationResources "  (tng) />
 (tng) (tng)
< message - resources (tng)key = " ch "  (tng)parameter = " com.kook.struts.ApplicationResources_ch "  (tng) />
 (tng) (tng)
< message - resources (tng)key = " en "  (tng)parameter = " com.kook.struts.ApplicationResources_en "  (tng) />

对应的addҎ(gu)如下Q?/font>

1 (tng)ActionErrors (tng)errors (tng)= (tng)new  (tng)ActionErrors();
2 (tng)if(name==null (tng)|| (tng)name.length()<1
)
3 (tng)
{
4 (tng) (tng) (tng) (tng) (tng) (tng) (tng)errors.add("name",new (tng)ActionMessage("kong"
));
5 (tng)
 (tng)}
6 (tng) (tng)return (tng)errors;

new  (tng)ActionMessage( " kong " )对应在key="en"的资源文件中为:(x)

kong=bu neng wei kong

JSP中的<html:errors>标签Q?/font>

1 (tng)<html:errors (tng)property="name" (tng)bundle="en"/>

q时候将?x)输出key="en"的资源文件中?kong"对应的信息:(x)bu neng wei kong

<html:messages>标签

<html:messages>标签是用来在JSP面上输Z条消息的。通常我们在做d数据的时候,如果d成功Q通常?x)在前台面反馈l用户一条“添加成功”的信息Q这时候我们就可以用到q个标签?br />
name属性:(x)

是指ActionMessages对象保存在request或session中的属性keyQ即request.setAttribute("heihei", messages);中的W一个参数?br />
message属性:(x)如果为trueQ表C是从request或session中取得key为Globals.MESSAGE_KEY的ActionMessages对象Q此时该标签讄的name属性的无效的。如果ؓ(f)falseQ表CZ该标{name属性来获得request或session的key倹{缺省值就为false?br />
id属性:(x)q个属性就不说?jin),(g)索出ActionMessages集合中单个对象的标识Q他?lt;logic:iterate>的id是同一个意思?br />
实验:(x)

在action中的executeҎ(gu)中添加如下代码:(x)

1 (tng)ActionMessages (tng)messages (tng)= (tng)new (tng)ActionMessages();
2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
3 messages.add("", (tng)new (tng)ActionMessage("haha",false));
4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
5 (tng)this.saveMessages(request, (tng)messages); (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
6 (tng)
7 (tng)return (tng)new (tng)ActionForward("/form/hello.jsp");

表示往ActionMessages对象中添加一条信?span style="COLOR: #0000ff">new (tng)ActionMessage("haha",false)Qƈ保存在request当中this.saveMessages(request, (tng)messages); (tng) (tng)那么在这个方法中Q他是如何保存ActionMessage对象的呢Q下面是 (tng)saveMessages (tng)Ҏ(gu)的源代码Q?/span>

 (tng)1 (tng)protected (tng)void (tng)saveMessages(
 (tng)2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)HttpServletRequest (tng)request,
 (tng)3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)ActionMessages (tng)messages) (tng){
 (tng)4 (tng)
 (tng)5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// (tng)Remove (tng)any (tng)messages (tng)attribute (tng)if (tng)none (tng)are (tng)required
 (tng)6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)if (tng)((messages (tng)== (tng)null) (tng)|| (tng)messages.isEmpty()) (tng){
 (tng)7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)request.removeAttribute(Globals.MESSAGE_KEY);
 (tng)8 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)return;
 (tng)9 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)}
10 (tng)
11 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)// (tng)Save (tng)the (tng)messages (tng)we (tng)need
12 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)request.setAttribute(Globals.MESSAGE_KEY, (tng)messages);
13 (tng) (tng) (tng) (tng) (tng)}

观察q段代码不难发现Q他是将ActionMessages存放在key为Globals.MESSAGE_KEY当中的,因此我们在调用ActionMessages的addҎ(gu)Ӟ他的property参数QaddҎ(gu)的第一个参敎ͼ(j)没有必要让我们自己L动指定了(jin)Q因ZZ指定什么参敎ͼ只要调用?jin)saveMessagesҎ(gu)Q这是前提)(j)Q他只会(x)信息保存在固定的常量key中?br />q时前台的hello.jsp面的显CZ码ؓ(f)Q?/p>

1 (tng)<html:messages (tng)id="a" (tng)message="true">
2 (tng) (tng) (tng) (tng) (tng)<bean:write (tng)name="a"/>
3 (tng)</html:messages>

上面代码讄?jin)message属性,表示从Globals.MESSAGE_KEY中获取信息,前面也有提到Q此时指定name属性是无效的?br />
那如果我惛_昄我自己指定的信息怎么办呢Q?br />
我们可以不用saveMessagesҎ(gu)而用最原始的办法,通常最原始的办法也是最有效?Struts其实是封装了(jin)许多最原始的实现。我们先action中的代码改ؓ(f)Q?/p>

ActionMessages (tng)messages (tng) =  (tng) new  (tng)ActionMessages();
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
messages.add(
"" , (tng) new  (tng)ActionMessage( " haha " , false ));
 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)
request.setAttribute(
" show " , (tng)messages);

return  (tng) new  (tng)ActionForward( " /form/hello.jsp " );

然后在JSP面中指定name属性,而将message设ؓ(f)false可以了(jin)Q?/p>

1 (tng)<html:messages (tng)id="a" (tng)name="show">
2 (tng) (tng) (tng) (tng) (tng)<bean:write (tng)name="a"/>
3 (tng)</html:messages>

q里是直接省略了(jin)message属性,因ؓ(f)他的~省值就是false。这样就可以辑ֈ输出自己指定属性的信息啦!




 (tng)



kook 2006-09-25 02:54 发表评论
]]>
资源文g中复合消息的实现http://www.aygfsteel.com/kook/articles/71624.htmlkookkookSun, 24 Sep 2006 16:48:00 GMThttp://www.aygfsteel.com/kook/articles/71624.htmlhttp://www.aygfsteel.com/kook/comments/71624.htmlhttp://www.aygfsteel.com/kook/articles/71624.html#Feedback0http://www.aygfsteel.com/kook/comments/commentRss/71624.htmlhttp://www.aygfsteel.com/kook/services/trackbacks/71624.html在Struts框架中,往往需要对资源文gq行配置Q从而实现国际化的目的?br />
资源文g中允怋用静(rn)态和动态文本。通过动态文本来动态的讑֮其显C的内容Q从而能更好的减代码的冗余Q然而动态文本中的参数指定,是通过什么来实现的呢Q?br />
下面是ApplicationResources.properties资源文g中的内容Q?br />
1 (tng)# (tng)Resources (tng)for (tng)parameter (tng)'com.kook.struts.ApplicationResources'
2 (tng)# (tng)Project (tng)P/ Demo_242103
3 (tng)

4 (tng)
5 (tng)
6 (tng)hello={0} (tng)is (tng)the (tng)brother (tng)of (tng){1 }
7 (tng)hello.brother=
zhangsan
8 (tng)hello.person=lisi

通常我们可以在验证框架的配置文g中来配置其动态参数的|如:(x)

1 (tng)<field (tng)property="name" (tng)depends="required">
2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)<arg0 (tng)name="required" (tng)key="hello.brother"/>
3 (tng) (tng)</field>

但是具体的实现可以通过java.text.MessageFormatcL实现

1 (tng) (tng) (tng) (tng) (tng) (tng) (tng)MessageResources (tng)messages (tng)=  (tng)getResources(request);
2 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)String (tng)title (tng)= (tng)messages.getMessage("hello"
);
3 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)String[] (tng)arr (tng)= (tng)new (tng)String[2
];
4 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)arr[0] (tng)= (tng)messages.getMessage("hello.brother"
);
5 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)arr[1] (tng)= (tng)messages.getMessage("hello.person"
);
6 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)String (tng)newMessage (tng)=
 (tng)MessageFormat.format(title, (tng)arr);
7 (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng) (tng)System.out.println(newMessage);

最后输出:(x)zhangsan is the brother of lisi

 (tng)

 (tng)



kook 2006-09-25 00:48 发表评论
]]>
logic:present ?logic:empty标签http://www.aygfsteel.com/kook/articles/71605.htmlkookkookSun, 24 Sep 2006 14:35:00 GMThttp://www.aygfsteel.com/kook/articles/71605.htmlhttp://www.aygfsteel.com/kook/comments/71605.htmlhttp://www.aygfsteel.com/kook/articles/71605.html#Feedback0http://www.aygfsteel.com/kook/comments/commentRss/71605.htmlhttp://www.aygfsteel.com/kook/services/trackbacks/71605.htmllogic:present ?logic:empty他们的用法大致相同,唯一的不同点是:(x)两者在对空字符串的处理上存在着不同?br />

下面为index.jsp中的代码Q?br />
 (tng)1 (tng)<logic:notPresent (tng)name="users">
 (tng)2 (tng) (tng)notpresent
 (tng)3 (tng)</logic:notPresent>
 (tng)4 (tng)<logic:notEmpty (tng)name="users">
 (tng)5 (tng) (tng)notempty
 (tng)6 (tng)</logic:notEmpty>
 (tng)7 (tng)<logic:empty (tng)name="users">
 (tng)8 (tng) (tng)empty
 (tng)9 (tng)</logic:empty>
10 (tng)<logic:present (tng)name="users">
11 (tng) (tng)present
12 (tng)</logic:present>


当第一ơ访问该JSP的时候,׃users没有定义Qƈ且也不在page,request,session,applicationM一个作用域中,因此输出的结果ؓ(f)notpresent,empty?br />
下面我们增加一个actionQ让他在index.jsp之前执行Q然后再跌{到index.jsp中,同时在该action的executeҎ(gu)中增加如下代码:(x)
 (tng)
1String (tng)userName (tng)= (tng)"";
2request.setAttribute("users", (tng)userName);
3return (tng)new (tng)ActionForward("/index.jsp");
4
q里userName保存在request中,key为usersQ再请求{发至index.jsp中,但是userName的gؓ(f)一个空字符Ԍ转发q后Q输出的gؓ(f)Qempty,present

q里我们再做一ơ改动,action的executeҎ(gu)中的代码改ؓ(f)Q?br />
1String (tng)userName (tng)= (tng)null;
2request.setAttribute("users", (tng)userName);
3return (tng)new (tng)ActionForward("/hello.jsp");
4
不同的是userName 不再为空字符串了(jin)Q而是null|当{发至index.jsp后,输出的gؓ(f)Qnotpresent,empty ?br />
Ҏ(gu)q几ơ改动,我们可以得出l论Q?br />
对于没有在page,request,session,application中定义或者是没有分配内存I间(null?的变量,q两个标记处理的Ҏ(gu)是一致的Q都?x)认为此变量不存?notpresent)或者ؓ(f)I?empty)。而对于空字符?"|他们的处理就不一样了(jin)Qlogic:present 标记认ؓ(f)I字W串仍然是存在的Q也是_(d)只要是引用了(jin)一块内存空间的变量Qlogic:present ׃(x)q回present Q而logic:empty则认为空字符串仍然ؓ(f)I,由此得出Q在logic:empty看来Q变量不仅仅要引用一块内存空_(d)而且该地址I间的g能ؓ(f)I字W串Q否则都认ؓ(f)该变量ؓ(f)I,都会(x)q回empty


kook 2006-09-24 22:35 发表评论
]]>
վ֩ģ壺 ɽʡ| | | ®| Ž| | Ž| | | | | Ϸ| | | | | ۶| | ̨| ƽ| | Ǭ| ʯ| | | | ƽԶ| կ| | ɽ| ˫| п| ʲ| | Ƿ| | | | | | |