??xml version="1.0" encoding="utf-8" standalone="yes"?>
在MD5法中,首先需要对信息q行填充Q其字节长度对512求余的结果等?48。因此,信息的字节长度(Bits LengthQ将被扩展至N*512+448Q即N*64+56个字节(BytesQ,NZ个正整数。填充的Ҏ(gu)如下Q在信息的后面填充一?和无C0Q直到满上面的条g时才停止?对信息的填充。然后,在在q个l果后面附加一个以64位二q制表示的填充前信息长度。经q这两步的处理,现在的信息字节长?N*512+448+64=(N+1)*512Q即长度恰好?12的整数倍。这样做的原因是为满_面处理中对信息长度的要求?/span>
具体的一个MD5实现Q?/span>
Struts是Apache Jakarta的一个著名的开源项目,目标是ؓ(f)构徏ZJava的web应用E序提供一个框架?/p>
Struts提供了非常多的标{,依据功能和用习(fn)惯的不同被分C五个标签库中:
q篇指南主要介绍前三个标{ֺ中的标签?/p>
cookie最早是由Netscape公司提出来的Q用来存储客L(fng)量状态信息?/p>
bean:cookie标签取回h中名UCؓ(f)name的cookie的倹{如果没有指定multiple属性则依据刚取回的值创Z个Cookiecd的bean。如果指定了multiple属性则依据刚取回的值创Z个Cookie[]cd的数l。然后用id属性值将Cookie或Cookie[]l定到page作用域中(q种l定是ؓ(f)了其它标{能够用该?Qƈ创徏对应的scripting变量(q种变量是ؓ(f)了JSP脚本能够使用该??/p>
下面的代码片D늤例了如何使用bean:cookie标签d名ؓ(f)JSESSIONID的cookie的|q且使用了两U方式进行了输出Q?/p>
<logic:present cookie="JSESSIONID"> <bean:cookie id="jSession" name="JSESSIONID"/> <!-- 其它标签通过l定到page作用域中的属性用该?--> q个cookie的名U是<bean:write name="jSession" property="name"/>Qgؓ(f)<bean:write name="jSession" property="value"/>?lt;br/> <!-- JSP脚本通过scripting变量使用该?--> <% String name = jSession.getName(); String value = jSession.getValue(); out.println("q个cookie的名U是"+name+"Qgؓ(f)"+value+"?lt;br/>"); %> </logic:present>
bean:define标签在toScope(如果没有指定值就使用page作用?指定的作用域中创Z个新属性,同时创徏一个scripting变量。我们可以通过idg用它们。新创徏的属性可以由其它标签使用Q而新创徏的scripting变量可以由JSP脚本使用?/p>
我们可以使用三种方式为新创徏的属性和scripting变量赋|(x)
下面的代码片D늤例了如何使用bean:define标签创徏新属性values和新scripting变量valuesQ它?yu)listForm中persons的值取出来赋给values:
<bean:define id="values" name="listForm" property = "persons" type="java.util.List"/>
下面l出ListForm的代码片D以帮助(zhn)更好的理解Q其中Person是一个只有id和name两个属性的单beanQ?/p>
public class ListForm extends ActionForm { private List<Person> persons = null; public List<Person> getPersons() { return persons; } public void setPersons(List<Person> persons) { this.persons = persons; } public void reset(ActionMapping mapping, HttpServletRequest request) { persons = null; } }
下面的代码片D늤例了logic:iterate标签如何使用bean:define标签创徏的新属性values:
<logic:iterate id="person" name="values"> <bean:write name="person" property="id"/><br/> </logic:iterate>
下面的代码片D늤例了JSP脚本如何使用bean:define标签创徏的新scripting变量values:
<% Person p = new Person(); for(int i=0;i<values.size();i++){ p = (Person)values.get(i); out.println(p.getId()); out.println("<br/>"); } %>
bean:header标签取回h中名UCؓ(f)name的header的倹{如果没有指定multiple属性则依据刚取回的值创Z个Stringcd的bean。如果指定了multiple属性则依据刚取回的值创Z个String[]cd的数l。然后用id属性值将String或String[]l定到page作用域中(q种l定是ؓ(f)了其它标{能够用该?Qƈ创徏对应的scripting变量(q种变量是ؓ(f)了JSP脚本能够使用该??/p>
下面是我的浏览器发送的header的内容,q些内容和浏览器有关Q因此?zhn)的浏览器发送的内容可能和下面列出的不同。不q这没有关系Q因理解bean:header标签(zhn)只要对q些内容有一个大概的认识p够了?/p>
accept: */* accept-language: zh-cn accept-encoding: gzip, deflate user-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322) host: localhost:8080 connection: Keep-Alive
下面的代码片D늤例了如何使用bean:header标签d名ؓ(f)User-Agent的header的|q且使用了两U方式进行了输出Q?/p>
<logic:present header="User-Agent"> <!-- 其它标签通过l定到page作用域中的属性用该?--> (zhn)的览器是<bean:header id="userAgent" name="User-Agent"/> <bean:write name="userAgent"/>?lt;br/> <!-- JSP脚本通过scripting变量使用该?--> <% out.println("(zhn)的览器是"+userAgent+"?lt;br/>"); %> </logic:present>
bean:include标签Ҏ(gu)定url(由forward、href或page定)处的资源做一个请求,响应数据作Z个Stringcd的beanl定到page作用域,同时创徏一个scripting变量。我们可以通过idD问它们?/p>
下面的代码片D늤例了bean:include标签的用法,其中include.txt文g包含要include的内容,然后这些内容输?
<bean:include id="value" page="/include.txt"/> <!-- 其它标签通过l定到page作用域中的属性用该?--> <bean:write name="value"/><br/> <!-- JSP脚本通过scripting变量使用该?--> <% out.println(value); %>
bean:message标签用来从指定的locale中取回国际化的消息ƈ输出Q在q个q程中我们还可以传递五个以内的参数。message key可以通过key直接指定Q也可以通过name和property间接的指定?/p>
bean:message标签有两U指定message key的方式,一是通过key属性直接指定;二是通过name和property属性间接的指定Q其中message key是在message resources文g中定义的?/p>
我们可以在struts-config.xml文g中?lt;message-resources>来设|message resources文g?/p>
Z介绍该标{我使用了三个message resources文gQ三个文件的名字分别为Resources.properties、Resources_en.properties和Resources_zh.properties。在struts-config.xml文g中的讄(q里不用讄三个Qstruts?x)依据locale自动扑ֈ对应的文?如下Q?/p>
<message-resources parameter="Resources" />
三个message resources文g中定义的message key为:(x)
<!-- Resources.properties --> resource=Resources.properties. from=Resources.properties. <!-- Resources_en.properties --> from=Resources_en.properties. <!-- Resources_zh.properties 因ؓ(f)文g的编码被限制为ISO8859所以要有汉字必ȝjdk的native2ascii提前转换 --> from=Resources_zh.properties.
下面的代码片D늤例了bean:message标签的用?
<bean:message key="from"/><br/> <bean:message key="resource"/><br/> <html:link action="/locale?language=en">English</html:link> <html:link action="/locale?language=zh">Chinese</html:link>
上面的代码中含有改变locale的两个html:link标签Q要使它们工作?zhn)的struts-config.xml文g中必d有下面定义的form和action:
<form-bean name="localeForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="language" type="java.lang.String" /> <form-property name="country" type="java.lang.String" /> <!--action成功后要跛_那里--> <form-property name="page" type="java.lang.String" initial="/message.jsp"/> </form-bean> <action path="/locale" type="org.apache.struts.actions.LocaleAction" name="localeForm" scope="request"></action>
在不同的locale下我们得C如下的两个结果:(x)
在locale为zh时的l果Q? Resources_zh.properties. Resources.properties. 在locale为en时的l果Q? Resources_en.properties. Resources.properties.
让我们来看一下在locale为zh时如何得到的是上面的l果。因为locale为zh所?lt;bean:message key="from"/><br/>先找Resources_zh.propertiesq个文g从中得到form键的倹{?lt;bean:message key="resource"/><br/>也会(x)先找Resources_zh.propertiesq个文g但这ơ没有找到resource键,q时Struts?x)到Resources.propertiesq个文g中找Q很q运q里扑ֈ了。如果还没有扑ֈQ或message resource文g不存在就?x)抛出异常。当locale为en时类|(zhn)可以自p试?
bean:page标签页上下文中的application、config、request、response ?session取出Q然后用id属性值将它们l定到page作用域中(q种l定是ؓ(f)了其它标{能够用该?Qƈ创徏对应的scripting变量(q种变量是ؓ(f)了JSP脚本能够使用该??/p>
下面的代码片D늤例了bean:page标签取出responseQ然后用bean:write标签response的characterEncoding和contentType属性输出:(x)
<bean:page id="res" property="response"/> <!-- 其它标签通过l定到page作用域中的属性用该?--> <bean:write name="res" property="characterEncoding"/><br/> <bean:write name="res" property="contentType"/><br/> <!-- JSP脚本通过scripting变量使用该?--> <% String characterEncoding = res.getCharacterEncoding(); String contentType = res.getContentType(); out.println(characterEncoding+"<br/>"); out.println(contentType+"<br/>"); %>
(zhn)可以用和上面类似的代码讉Ka(chn)pplication、config、request ?session中的M一个对象?/p>
bean:parameter标签取回h中的参数倹{如果没有指定multiple属性则依据刚取回的值创Z个Stringcd的bean。如果指定了multiple属性则依据刚取回的值创Z个String[]cd的数l。然后用id属性值将String或String[]l定到page作用域中(q种l定是ؓ(f)了其它标{能够用该?Qƈ创徏对应的scripting变量(q种变量是ؓ(f)了JSP脚本能够使用该??/p>
下面的两个代码片D用相同的url传递参敎ͼurl的Ş式ؓ(f)http://127.0.0.1:8080/struts-demo/parameter.jsp?param=1¶m=2¶m=3。前面的代码片段中没有指定multiple属性,因此p是Stringcd而且仅仅d了参数的W一个倹{后面的代码片段中指定了multiple属性的|因此ps是String[]cd的包含所有参数的倹{?/p>
<bean:parameter id="p" name="param"/> <bean:write name="p"/>
<bean:parameter id="ps" multiple="true" name="param"/> <logic:iterate id="p" name="ps"> <bean:write name="p"/><br/> </logic:iterate>
bean:resource标签取回指定的web应用E序的资源,以InputStream或String的Ş式保存到page作用域中q且创徏scripting变量。采用什么Ş式取决于标签的input属性,如果指定input则以InputStream的Ş式保存,如果没有指定input则以String的Ş式保存?/p>
下面的两个代码片D늤例了bean:resource标签Q其中resource.txt是要使用的资源文件。前面的代码片段中没有指定input属性,因此以String的Ş式处理资源文Ӟbean:write标签输出资源文g的内宏V后面的代码片段中指定了input属性的|因此以InputStream的Ş式用资源文Ӟ两个bean:write标签分别输出InputStream对象的实例名(如java.io.ByteArrayInputStream@16dadf9)和类?如class java.io.ByteArrayInputStream)?
<bean:resource id="str" name="/resource.txt"/> <!-- 其它标签通过l定到page作用域中的属性用该?--> <bean:write name="str"/><br/> <!-- JSP脚本通过scripting变量使用该?--> <% out.println(str+"<br/>"); %>
<bean:resource id="is" input="true" name="/resource.txt"/> <!-- 其它标签通过l定到page作用域中的属性用该?--> <bean:write name="is"/><br/> <bean:write name="is" property="class"/> <!-- JSP脚本通过scripting变量使用该?--> <% out.println(is+"<br/>"); out.println(is.getClass()+"<br/>"); %>
bean:size标签创徏一个java.lang.Integercd的beanQ这个bean的gؓ(f)该标{指定的Collection或Map中所含元素的个数?q可以和logic:iterate标签配合使用Q因为logic:iterate标签不能得到所叠代的集合的元素的个敎ͼq有时候很不方ѝ?
下面的代码片D늤例了bean:size标签取出persons中还有元素的个数Q其中listForm和persons的定义参见bean:define标签部分Q?/p>
<logic:notEmpty name="listForm" property = "persons"> <bean:size id="size" name="listForm" property = "persons"/> <bean:write name="size"/> </logic:notEmpty>
bean:struts标签取回Struts的内部对象formBean、forward或mapping的|然后用idl定到page作用域中(q种l定是ؓ(f)了其它标{能够用该?Qƈ创徏对应的scripting变量(q种变量是ؓ(f)了JSP脚本能够使用该??/p>
下面的代码片D늤例了bean:struts标签取出listForm对象Q让我们先来看一下listForm的定义在M码:(x)
<!-- listForm的定?lt;form-bean name="listForm" type="org.solo.struts.form.ListForm" /> --> <bean:struts id="listFormBean" formBean="listForm"/> name:<bean:write name="listFormBean" property="name"/><br/> type:<bean:write name="listFormBean" property="type"/><br/> dynamic:<bean:write name="listFormBean" property="dynamic"/><br/>
上面代码q行的结果ؓ(f)Q?/p>
name:listForm type:org.solo.struts.form.ListForm dynamic:false
bean:write标签指定的bean的属性值写到当前的JspWriter中,q且可以对输行格式化?/p>
下面的代码片D늤例了bean:write标签输出User-AgentQ?/p>
<logic:present header="User-Agent"> <bean:header id="header" name="User-Agent"/> <bean:write name="header"/> </logic:present>
下面的代码片D늤例了bean:write标签格式化输出当前日期,其中now是在DataForm中定义的一个java.util.Datecd的域(gؓ(f)new Date())Qformat.date.standard是在资源文g中的一个键(format.date.standard=yyyy-MM-dd)Q?/p>
<bean:define id="date" name="dataForm" property="now"/> <br/><bean:write name="date"/> <br/><bean:write name="date" format="MM/dd/yyyy"/> <br/><bean:write name="date" formatKey="format.date.standard"/>
上面代码q行的结果ؓ(f)Q?/p>
Sun Jun 04 17:04:05 CST 2006 06/04/2006 2006-06-04
虽然q里的标题是html:base标签Q但是这里也是这指南要介绍的第一个Struts html标签。因此我惛_q里从整体上单的介绍一下,最后给Z个对照表。其中的l大多数标签׃一一介绍了,要介l的也不?x)在q里介绍Q而是其独立出来以显重要性?/p>
从用户处攉数据是动态web应用非常重要的一个方面,因此构徏输入表单也就自然而然的成为struts框架的一个重要内宏VStruts html标签库含有创建Struts输入表单的标{,和其它标{ֺ(bean、logic、nested和tiles)中的标签一起协作就可以产生Zhtml的用L(fng)面?/p>
下面的对照表?x)?zhn)对Struts html标签库有一个整体的印象Q?/p>
html:cancel标签生成一个取消按钮。当点击该按钮后action servlet?x)绕q相应的form bean的validate()Ҏ(gu)Q同时将控制权交l相应的action。在该action中可以用Action.isCancelled(HttpServletRequest)Ҏ(gu)判断是否被取消了。如果返回true表示q个action被取消了Q否则表C个action没有被取消?/p>
h意,如果(zhn)修改了html:cancel标签的property属性|那么struts提供的cancel探测机制失效了Q?zhn)自己必须提供cM的机制?/p>
下面是可取消的action的配|文Ӟ注意<set-property property="cancellable" value="true"/>q一行,如果不添加Struts?x)抛出org.apache.struts.action.InvalidCancelException异常。这是我在完成本指南的过E中发现的唯一向下不兼容的地方?/p>
<action path="/cancel" type="org.solo.struts.action.CancelAction" name="cancelForm" scope="request"> <set-property property="cancellable" value="true"/> <forward name="success" path="/cancel.jsp" /> </action>
下面是html:cancel标签的代码:(x)
<html:cancel>取消</html:cancel>
下面是对应的action中的代码Q?/p>
if(isCancelled(request)){ //action被取消时要做的事情写在这? return mapping.findForward("cancel"); }else{ //action没有被取消时要做的事情写在这? return mapping.findForward("success"); }
html:select标签生成一个select元素。是单选还是多选取决于该标{multiple属性。如果指定了multiple="true"则ؓ(f)多选,此时对应的属性应该是一个数l。如果没有指定multiple="true"则ؓ(f)单选,此时对应的属性应该是标量?/p>
注意Qؓ(f)了正的处理没有做Q何的选择的情况,在ActionForm中的reset()Ҏ(gu)中必d标量属性设|ؓ(f)默认D将数组的长度置??/p>
另外的一个重要问题就是struts如何生成option元素了,q个dstruts交给了html:option、html:options和html:optionsCollection三个标签?/p>
html:option标签
html:option标签生成一个HTML的option元素。该标签必须嵌在html:select标签中。它的显C文本来自其标签体,也可以来自于资源文g。它的value属性用来指定什么值将要被提交?/p>
<html:option value="one">one</html:option> <html:option value="two">two</html:option>
html:options标签
html:options标签生成多个HTML的option元素。该标签必须嵌在html:select标签中。而且工作方式有些Ҏ(gu)Q它的name与property属性和其它标签的name与property属性意义不一_(d)让我们具体看一下它的工作方式?/p>
指定collection属?/p>
让我通过CZ来介l在指定collection属性时该标{工作方式Q首先要说明selectForm中的persons和listForm中的persons完全一致。请参见bean:define标签?/p>
下面的代码先利用bean:define标签selectForm中的persons取到page作用域中Q然后html:options标签再依据collection="personCollection"选中q个personsq将其中的每一个对?Personcd)生成一个option元素。该标签的property="id"表示persons中的对象(Personcd)的id属性将作ؓ(f)option元素的value倹{该标签的labelProperty="name"表示persons中的对象(Personcd)的name属性将作ؓ(f)option元素的label倹{?/p>
当这个select提交时所选择的值将被提交到selectForm(name="selectForm")中的person对象(q是在SelectForm中声明的一个Personcd的域专门用来接收提交的?的id属性中(property="person.id")?/p>
<bean:define id="personCollection" name="selectForm" property="persons"/> <html:select name="selectForm" property="person.id" size="1"> <html:options collection="personCollection" property="id" labelProperty="name"/> </html:select>
没有指定collection属?/p>
让我通过CZ来介l没有指定collection属性时该标{工作方式Q先来看看ids和names的定义:(x)
private List<String> ids = null; private List<String> names = null;
上面的代码来自SelectFormQ其中ids是一个String的列表,names也是一个String的列表。我们暂时假定这两个列表含有相同数目的元素。有了这些让我们开始介l下面的代码。html:options标签用ids中的Wi个g为option元素的value值同时用names中相同位|的?Wi个?作ؓ(f)option元素的label倹{如果ids比names镉K么多出的ids中的值将即作为option的value又作为option的label。如果ids比names短那么多出的names的g(x)被丢掉?/p>
当这个select提交时所选择的值将被提交到selectForm(name="selectForm")中的person对象(q是在SelectForm中声明的一个Personcd的域专门用来接收提交的?的id属性中(property="person.id")?/p>
<html:select name="selectForm" property="person.id" size="1"> <html:options property="ids" labelProperty="names"/> </html:select>
html:optionsCollection标签
html:optionsCollection标签生成多个HTML的option元素。该标签必须嵌在html:select标签中。它的功能和html:options标签的相同,但是它的name与property属性和其它标签的name与property属性意义一_(d)理解h比较自然?/p>
让我通过CZ来介lhtml:optionsCollection标签的用法。首先依据name="selectForm"和property="persons"取到selectForm中的persons列表Q然后将列表中的对象(Personcd)的id属性作为option元素的value?value="id")Q将列表中的对象(Personcd)的name属性作为option元素的label?label="name")?/p>
<html:select name="selectForm" property="person.id" size="1"> <html:optionsCollection name="selectForm" property="persons" label="name" value="id"/> </html:select>
下面是一个多选的CZQ虽然示例中使用了html:options标签Q但是html:option和html:optionsCollection也能够用来多选。而且(zhn)还必须意识到html:option、html:options和html:optionsCollectionq三个标{֏以同时用。代码中的personIds是SelectForm中声明的一个String[]cd的数l用来接收提交的多个倹{?/p>
<html:select name="selectForm" property="personIds" multiple="true" size="2"> <html:options property="ids" labelProperty="names"/> </html:select>
html:check标签生成一个checkbox。这里的value值可以是trueQyes或on。如果?zhn)要提交其它的?如某UŞ式的标识)应该考虑使用html:multibox标签?/p>
注意:Z正确的处理没有选中的checkbox(zhn)必dreset()中设|对应的属性ؓ(f)false?/p>
下面的代码示例了html:checkbox标签的用法,其中CheckboxForm中声明了三个booleancd的域Q如下:(x)
<!-- 略掉了getҎ(gu)(也可以是isXXX形式)和setҎ(gu) --> private boolean one = false; private boolean two = false; private boolean three = false;
<html:checkbox name="checkboxForm" property="one">One</html:checkbox> <html:checkbox name="checkboxForm" property="two">Two</html:checkbox> <html:checkbox name="checkboxForm" property="three">Three</html:checkbox>
如果选中后被提交则相应的属性的gؓ(f)true?/p>
html:radio标签生成一个radio。主要的用法有两U,下面我们通过代码来示例?/p>
下面的代码示例了html:radio标签的一般用法,如果被提交则选中的radio的value值将被提交到radioForm中的id中?/p>
<html:radio name="radioForm" property="id" value="00001">One</html:radio> <html:radio name="radioForm" property="id" value="00002">Two</html:radio>
下面的代码示例了html:radio标签的典型用法,其中的persons和bean:define标签中的一_(d)(zhn)可以参考bean:define标签。我只介l这?lt;html:radio idName="person" property="id" value="id">QidName指定html:radio要用的bean(q里为person)Qvalue="id"表示person的id属性将作ؓ(f)radio元素的valueDproperty="id"表示提交旉中的radio的值将被提交给radioForm中的id属性?
<logic:notEmpty name="radioForm" property="persons"> <logic:iterate id="person" name="radioForm" property="persons"> <html:radio idName="person" property="id" value="id"> <bean:write name="person" property="name"/> </html:radio> </logic:iterate> </logic:notEmpty>
html:multibox标签生成多个checkbox。当(zhn)要使用大量的checkbox时用这个标{N常方便,可以使?zhn)避免在ActionForm中声明大量的booleancd的变量,带之以一个数l就行了?/p>
注意:Z正确的处理没有选中的checkbox(zhn)必dreset()中设|数l的长度??/p>
下面的代码示例了html:multibox标签的一般用法,如果被提交则选中的所有checkbox的value值将被提交到multiboxForm中的selectedItems中,q是一个String[]数组?/p>
<html:multibox name="multiboxForm" property="selectedItems" value="00001"/> <html:multibox name="multiboxForm" property="selectedItems" value="00002"/>
下面的代码示例了html:multibox标签的典型用法:(x)
<logic:iterate id="person" name="multiboxForm" property="persons"> <html:multibox property="selectedItems"> <bean:write name="person" property="id"/> </html:multibox> <bean:write name="person" property="name"/> </logic:iterate>
html:link标签生成一个锚?<a>)元素。我从html:link标签如何构造基本url和如何构造query参数两个斚w来介l这个标{?/p>
构造基本url是依据该标签的如下四个属性进行的Q这四个属性一ơ只能出C个。让我们看看它们Q?
构造query参数Q下面列举了可能的Ş式,其中baseurl只是一个占位符Q?
下面我们以代码示例来说明每一Uhtml:link的用法,首先让我们花Ҏ(gu)间看看相关action中的代码Q?/p>
<!-- 下面所有代码的数据都是在这里构造的 --> public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) { DataForm dataForm = (DataForm) form; dataForm.setParam("00001"); HashMap paramSingleMap = new HashMap(); paramSingleMap.put("p1","00001"); paramSingleMap.put("p2","00002"); paramSingleMap.put("p3","00003"); dataForm.setParamSingleMap(paramSingleMap); HashMap paramMultiMap = new HashMap(); paramMultiMap.put("p",new String[]{"00001","00002","00003"}); dataForm.setParamMultiMap(paramMultiMap); HashMap paramSMMap = new HashMap(); paramSMMap.put("p1","00001"); paramSMMap.put("p2","00002"); paramSMMap.put("p",new String[]{"00001","00002","00003"}); dataForm.setParamSMMap(paramSMMap); List<Person> persons = new ArrayList<Person>(); Person person1 = new Person(); person1.setId("00001"); person1.setName("赵辰"); Person person2 = new Person(); person2.setId("00002"); person2.setName("李ؓ(f)?); Person person3 = new Person(); person3.setId("00003"); person3.setName("王微"); persons.add(person1); persons.add(person2); persons.add(person3); dataForm.setPersons(persons); return mapping.findForward("success"); }
<!-- q用来设|一个位|?--> <html:link linkName="top"/> <!-- q用来定位到上面的那个位|?--> <html:link page="/link.do" anchor="top">Go Top</html:link>
<html:link page="/link.do" paramId="p" paramName="dataForm" paramProperty="param">单参单?lt;/html:link><br/> <html:link page="/link.do" name="dataForm" property="paramSingleMap">多参单?lt;/html:link><br/> <html:link page="/link.do" name="dataForm" property="paramMultiMap">单参多?lt;/html:link><br/> <html:link page="/link.do" name="dataForm" property="paramSMMap">混合</html:link>
下面的代码示例了html:link标签的indexed属性和indexId属性的用法Q这两个属性只有html:link标签嵌套在logic:iterate标签中时才可用?/p>
<logic:iterate id="person" name="dataForm" property="persons"> <html:link action="/link.do" paramId="person" paramName="person" paramProperty="id" indexed="true" indexId="number">person</html:link> <br/> </logic:iterate> <!-- 下面是上面代码的q行l果(产生的html) <a href="/struts-demo/link.do?person=00001&number=0">赵辰</a><br/> <a href="/struts-demo/link.do?person=00002&number=1">李ؓ(f)?lt;/a><br/> <a href="/struts-demo/link.do?person=00003&number=2">王微</a><br/> 其中的number是由indexId="number"定的,而该参数的gؓ(f)元素在集合中的位|? -->
html:rewrite标签和html:link标签cM只是不生成锚?<a>)Q而是单的输出字符丌Ӏ?/p>
html:errors标签和html:messages标签的功能相|所以我们放Ch介绍?/p>
html:errors标签由name属性指定的ActionMessages、ActionErrors、String和String[]直接输出到页面中?/p>
html:messages标签用由name属?注意message属性值对它的影响)指定的ActionMessages、ActionErrors、String和String[]创徏一个新的属性和scripting变量Q用id属性g为名U?/p>
html:errors标签和html:messages标签的property属性是用来为errors和messages分类的。我们可以给q两个标{指定property属性,以便只显C某一cȝ错误或消息?/p>
在资源文件增加了如下的内容:(x)
# -- standard errors -- errors.header=<ul> errors.prefix=<li> errors.suffix=</li> errors.footer=</ul> error=error with none value . error1=error1 with one value is {0} . error2=error2 with two values are {0} , {1} . error3=error3 with three values are {0} , {1} , {2} . error4=error4 with four values are {0} , {1} , {2} ,{3} .
下面的代码示例了actionErrors的构造:(x)
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) { ActionErrors actionErrors = new ActionErrors(); actionErrors.add("property1", new ActionMessage("error")); actionErrors.add("property2", new ActionMessage("error1","value0")); actionErrors.add("property2",new ActionMessage("error2","value0","value1")); actionErrors.add("property3",new ActionMessage("error3","value0","value1","value2")); actionErrors.add("property3",new ActionMessage("error4","value0","value1","value2","value3")); actionErrors.add("property4", new ActionMessage("error1",new Object[]{"value0"})); actionErrors.add("property4", new ActionMessage("error2",new Object[]{"value0","value1"})); actionErrors.add("property4", new ActionMessage("error3",new Object[]{"value0","value1", "value2"})); actionErrors.add("property5",new ActionMessage("error4",new Object[]{"value0","value1", "value2","value3"})); actionErrors.add("notBundle",new ActionMessage("not a bundle key",false)); return actionErrors; }
errors标签代码CZQ?/p>
<html:errors/> <br/> <html:errors property="property4"/>
messages标签代码CZQ?/p>
<logic:messagesPresent> <ul> <html:messages id="message"> <li><bean:write name="message"/></li> </html:messages> </ul> </logic:messagesPresent> <br/> <logic:messagesPresent> <ul> <html:messages id="message" property="property4"> <li><bean:write name="message"/></li> </html:messages> </ul> </logic:messagesPresent>
html:javascript标签生成用于校验的javascript脚本代码?/p>
下面的代码片D늤例了html:javascript标签的基本用法,其中formName属性的值是在validation.xml文g?lt;formset>中定义的form的名U。有一点值得注意的是在确?lt;formset>时要使用合适的language属性倹{?/p>
<html:javascript formName="dataForm"/>
html:xhtml标签在页面中一出现是告诉该页的所有其它的Struts html标签以XHTML1.0兼容的Ş式输出。这和将html:html标签的xhtml属性值指定ؓ(f)true有些cM。如果上q情况都没有出现QStruts html标签以html4.01兼容的Ş式输出?/p>
logic:iterate标签用来q代集合Q?zhn)可以使用如下方式来?f)q个标签指定其要叠代的集合:(x)
上面所提到的集合可以是Q?/p>
如果(zhn)叠代的集合中含有null的|q时需要采取一定的措施Q因时logic:iterate不会(x)在page作用域中创徏对象。一般是使用<logic:present>标签?lt;logic:notPresent>标签来判断一下?/p>
下面是logic:iterate叠代ArrayList的示例的对象引用关系和部分代码:(x)
图中的persons列表是在ListAction中填充的Q在q里只是单的加入了三个Person对象Q在实际的应用中q些数据应该取自数据库。具体的代码如下Q?/p>
public ActionForward execute(ActionMapping mapping,ActionForm form, HttpServletRequest request, HttpServletResponse response) { ListForm listForm = (ListForm) form; List<Person> persons = new ArrayList<Person>(); Person person1 = new Person(); person1.setId("00001"); person1.setName("赵辰"); Person person2 = new Person(); person2.setId("00002"); person2.setName("李ؓ(f)?); Person person3 = new Person(); person3.setId("00003"); person3.setName("王微"); persons.add(person1); persons.add(person2); persons.add(person3); listForm.setPersons(persons); return mapping.findForward("success"); }
标签输出的结果ؓ(f)Q?/p>
00001-->赵辰 00002-->李ؓ(f)? 00003-->王微
如果指定的值出现该标签׃(x)创徏其标{体内的内容。该标签用于以下情况Q?/p>
下面的代码示例了logic:present标签(g)查具有指定名UUser-Agent的header是否出现Q?/p>
<logic:present header="User-Agent"> (zhn)的览器是<bean:header id="userAgent" name="User-Agent"/> <bean:write name="userAgent"/>?lt;br/> </logic:present>
logic:notPresent标签的应用正好和logic:present标签相反?/p>
logic:messagesPresent标签用于以下情况Q?/p>
标签的message属性gؓ(f)true时将以Globals.MESSAGE_KEY为key在request作用域中查找MessageQ其它情况下Q将name的g为key查找Q如果name 没有出现Q默认gؓ(f)Globals.ERROR_KEY?
下面的代码示例了logic:messagesPresent标签的典型用法:(x)
<logic:messagesPresent> <ul> <html:messages id="message"> <li><bean:write name="message"/></li> </html:messages> </ul> </logic:messagesPresent>
标签logic:messagesNotPresent的应用正好和logic:messagesPresent的应用相反?/p>
logic:empty标签是用来判断是否ؓ(f)I的。如果ؓ(f)I,该标{体中嵌入的内容׃(x)被处理。该标签用于以下情况Q?/p>
下面的代码示例了logic:empty标签判断集合persons是否为空Q?/p>
<logic:empty name="listForm" property = "persons"> <div>集合persons为空!</div> </logic:empty>
logic:notEmpty标签的应用正好和logic:empty标签相反?/p>
logic:match标签用来处理子串匚w问题?/p>
如果指定的值匹配该标签׃(x)创徏其标{体内的内容。该标签用于以下情况Q?
下面的代码示例了logic:match标签的典型用法:(x)
<logic:present header="User-Agent"> <logic:match header="User-Agent" value="MSIE 6.0">MS IE 6.0</logic:match> </logic:present>
logic:notMatch标签的应用正好和logic:match标签相反?/p>
q里要介l的不只是logic:equal(=)标签Q而是要介l一cL{,q类标签完成比较q算Q包括:(x)
该类标签的用法类|我们只介llogic:equal标签Q其它的留给(zhn)自己去完成?/p>
logic:equal是用来判断是否相{的。如果相{,该标{体中嵌入的内容׃(x)被处理。该标签用于以下情况Q?/p>
我觉得将forward和redirectq两个动作放C起对比着介绍更加有利于理解,Z此原因也将logic:forward和logic:redirectq两个标{也拿到q里一起介l了?/p>
让我们看看这两个动作的区别:(x)
redirect比forward慢,因ؓ(f)览器要做二ơ请求。还有就是要注意Q在W一ơ的h作用?request作用?内的bean对于W二ơ请求是不可见的?/p>
理解了上面描q的区别也就知道了什么时候该选用logic:forward标签什么时候该选用logic:redirect标签了。logic:forward标签完成PageContext.forward()或HttpServletResponse.sendRedirect()Q如何选择由控制器军_。logic:redirect标签完成HttpServletResponse.sendRedirect()?/p>
在用logic:redirect标签时我们可以向使用html:link一h造baseurl和query参数。如果?zhn)感兴可以参考html:link标签?/p>
q篇指南的背景是Struts-1.2.9Q其中的所有的代码CZ也都是在q个版本下调试通过的。目前Struts仍然在快速的发展中,但是从开发者应用的角度来讲q是比较E_的。因此我有理q信其中的代码CZ也可以很好的q行在其它的版本之上。最后希望这指南能够让(zhn)心情愉快!
一. XML的大本营
XML是由W3C(World Wide Web Consortium)国际l织负责开发和制定标准的。关于XML最权威Q最新的消息都来自W3C?br />
|址是:(x)http://w3c.org/XML/
另外一个名为OASIS的前著名的SGML研究l织也在一h动XML的发展,|址是:(x)http://www.oasis-open.org/
? XML指南
http://www.w3.org/TR/REC-xml
W3C关于XML规范的详l,完整的说明。不用多_(d)l对权威?br />
http://www.xml.com/axml/testaxml.htm
q是Tim Bary写的XML规范说明书,非常的详l和严密Q是学习(fn)XML规范的好帮手?/p>
? XML常见问题
Peter Flynn的XML FAQ
http://www.ucc.ie/xml/
包含大量详细的资料,l常更新Q由W3C协会(x)XMLl维护?br />
Lisa Rein’s finetuning XML FAQs
http://www.finetuning.com/faq.html
q个FAQ列表有侧重点Q主要包含XSLT FAQ,XPath FAQ和IE5中的XSL FAQ?br />
Dave Pawson’s XSL FAQ
http://www.dpawson.co.uk/xsl/idx.html
提供最好的关于XSL斚w的FAQQ创Z1999q?br />
jGuru’s Extensible Markup Language (XML) FAQ
http://www.jguru.com/jguru/faq/faqpage.jsp?name=XML
q个FAQ列表是一个典型的"老百?QQ何问题,从普通的到非常细节的XML问题都可以在q里扑ֈ?br />
Ronald Bourret’s XML Namespaces FAQ
http://www.informatik.tu-darmstadt.de/DVS1/staff/bourret/xml/NamespacesFAQ.htm
创徏?000初,是关于namespaces概要的FAQ?/p>
? XML主题|站
http://www.xml.com/
一个以XMLZ题的内容丰富的网?br />
http://www.xml-zone.com/
另一个比较知名的XML|站Q提供XML的新d资讯?br />
http://www.xmlinfo.com/
|站创徏者James Tauber’s是W3Cl织XML发展l的成员之一Q他的网站提供了大量的连接和例子?br />
http://www.simonstl.com/
|站创徏者Simon St. Laurent也是XML发展l的成员。他是W3C中XML初入门教程的作者,他的站点主要提供有关XML的发展信息?br />
http://msdn.microsoft.com/xml/c-frame.htm#/xml/default.asp
微Y的MSDN关于XML的主题网站。微软在推进XML应用斚w不遗余力?br />
http://www.xmlsoftware.com/
是XML info的姐妹网站,内容包括XML/DTD/XSL~辑软gQXML API软g{?br />
http://xmlhack.com/
1999q?月徏立的大型XML新闻|站Q同时提供XML人才信息?br />
http://xml.apache.org/
Apache软g基金?ASF),提供了大量open source的XML和XSL的工兯Y件?br />
http://www.biztalk.org/
BizTalk是微软发L(fng)以XML商业应用为目标的l织。BizTalk不是一个标准组l?/p>
? XML的编辑Y?/strong>
目前XML文档的编辑Y件依然很。虽然我们可以手工编写,但是如果有一个好的Y?cM用DW/FP~写HTML)Q可以减差错和提高效率。下面是现有的一些编辑Y件?br />
http://www.macromedia.com/software/dreamweaver/
Macromedia最新的Dreamweaver 4.0已经支持XML文档的编写。推荐用?br />
http://www.microsoft.com/xml/notepad/intro.asp
微Y在这斚w向来不会(x)落后Q它推出的XML Notepad是一个非常小巧灵zȝXML文档~辑器。推荐用?br />
http://www.adobe.com/prodindex/framemaker/prodinfosgml.html
Adobe公司的Framemaker plus是目前较好的XML~辑软g?br />
http://www.arbortext.com/
Arbortext公司是重点开发XML游戏的公司?br />
http://www.inso.com/
InsoQ好象是用来处理大型SGML或者XML文档的Y件?br />
http://www.softquad.com/
Softquad 是HTML和SGML软g的开发商Q对XML自然不会(x)放过?/p>
? 支持XML的浏览器
http://www.microsoft.com/windows/ie/
IE 5.X是目前流行浏览器唯一支持XML的,它可以在微Y的网站免费下载到?br />
http://developer.netscape.com/software/communicator/ngl/index.html?cp=dev09fg01
Gecko是另一U支持XML的浏览器Q但目前只是试版?/p>
? XML parser
Parser是一个检查XML文档语法是否W合DTD定义Qƈq行解析的Y件?br />
在线的parser
http://validator.w3.org/
W3Cl织提供的一个在Upaeser。可以根据你在线提交的XML文档URLQ进行验证和解吸?br />
http://www.stg.brown.edu/service/xmlvalid/
一个Brown大学U技组提供的parserQ非常方便和Ҏ(gu)理解。?br />
可下载的Parser
有很多可以下载到本机上运行的parser,下面列出一些主要的Q?br />
http://www.jclark.com/xml/expat.html
James Clark是在SGML/XML领域的元老,他写的parser被广泛的q用?br />
http://www.alphaworks.ibm.com/tech/xml
一个以Java语言~写的ParserQ来自IBM?br />
http://www.microsoft.com/xml/parser/cparser.asp
微Y的XML ParserQ用C++写成?br />
http://www.stud.ifi.uio.no/~larsga/download/python/xml/xmlproc.html
用Python写的parser?br />
http://www.jeremie.com/Dev/XML/
用Javascript写的parserQ只用来(g)查语法,不进行解吸析?br />
http://w3c.org/RDF/Implementations/SiRPAC/
来自W3Cl织的SiRPACQ全U是Simple RDF Parser and Compiler?/p>
? Schema~辑软g
Schema我们前面介绍q,DTD是一USchemaQ我们可以手工写DTDQ但现在已经有一些Schema~辑软g来帮助我们更方便的徏立DTD?br />
http://www.extensibility.com/
Extensibilityq个软g被称为XML权威。可以以囑Ş化方式徏立和~辑schemaQ包括DTD文g?br />
? 国内XML资源
http://www.xml.net.cn/
XML中国论坛是一个非赢利的学术网站。由北京大学计算机科学与技术研I所创办Q北大方正集团公司提供赞助?br />
http://www.xml.org.cn:8188
中国XML联盟徏立ؓ(f)国内W一个开放性网l标准组l,提供XML技术认证、咨询和交流。由上v易方公司赞助?br />
http://www.xml.com.cn/
chinaasp.com的子站,提供XML文章和技术交等?br />
http://www.egroups.com/group/china_xml_list/info.html
中国XML邮gl包括中文XML资源, XML的最新资?同行的交空间。由非盈利性组l中国XML联盟负责l护?br />
http://weblab.crema.unimi.it/xmlzh/XML_FAQ.htm
一个XML FAQ邮g列表的中文翻译,可惜?998q?0月的?br />
-------------- 全文?----------