WebWork 2 : TutorialLesson04-02
This page last changed on Sep 16, 2004 by vitorsouza.
4.2: 在WebWork中使用Velocity有两种方法可以利用Velocity作为视图.
为使用第二种方式, 必须修改web.xml文件加入WebWorkVelocityServlet的servlet定义及其映射, 如下: <servlet> <servlet-name>velocity</servlet-name> <servlet-class>com.opensymphony.webwork.views.velocity.WebWorkVelocityServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping> 进一步阅读: xwork.xml 使用velocity结果类型意味着Velocity模版仅能通过活动进行绘制, 换言之, 访问.vm页面将不会进行绘制而直接返回文本内容. 如果你选择这种方式, 推荐你将Velocity文件放在WEB-INF目录下使其不可访问. 使用WebWorkVelocityServlet意味着Velocity模版可以通过对.vm页面的请求进行绘制. 这也意味着需要对模版实现安全检查, 以便用户不能绕过活动(如果这是必需的)直接访问它.不管你选择哪种方式(你也可以选择同时使用两种方式), 当你编写模版时不仅可以使用全部Velocity的特性, 还可以使用WebWork提供的其他功能. 这里假设你已经熟悉了Velocity, 因此我们仅关注WebWork提供的特性. 如果你不熟悉, 清在继续阅读之前参阅'开始Velocity之旅'. 主要特性是提供了对值栈中对象方便的访问途径, 这里包含了WebWork自动提供的一些内容, 因为你在某些地方会发现它的价值. 这是值栈中包含的部分对象:
要访问值栈中的数据, 你只须使用适当的Velocity引用:
下面的例子完成了与第三课相同的功能, 但是现在使用Velocity模版做为结果. 需要注意的是<property value="person" />标签被替换成$person引用, 它返回同样的内容: 活动类的一个属性. 本例中我们使用了velocity结果类型方式. xwork.xml:<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <!-- Include webwork defaults (from WebWork JAR). --> <include file="webwork-default.xml" /> <!-- Configuration for the default package. --> <package name="default" extends="webwork-default"> <!-- Default interceptor stack. --> <default-interceptor-ref name="defaultStack" /> <!-- Action: Lesson 4.2: HelloAction using Velocity as result. --> <action name="helloVelocity" class="lesson03.HelloAction"> <result name="error" type="dispatcher">ex01-index.jsp</result> <result name="success" type="velocity">ex01-success.vm</result> </action> </package> </xwork> HelloAction.java (与第三课相同):package lesson03; import com.opensymphony.xwork.ActionSupport; public class HelloAction extends ActionSupport { String person; public String getPerson() { return person; } public void setPerson(String person) { this.person = person; } public String execute() throws Exception { if ((person == null) || (person.length() == 0)) return ERROR; else return SUCCESS; } } ex01-index.jsp (与第三课相同):<html> <head> <title>WebWork Tutorial - Lesson 3 - Example 2</title> </head> <body> <p>What's your name?</p> <form action="hello.action" method="post"> <p><input type="text" name="person" /><input type="submit" /></p> </form> </body> </html> ex01-success.vm:<html> <head> <title>WebWork Tutorial - Lesson 4.2 - Example 1</title> </head> <body> Hello, $person </body> </html> 试试这个例子! 在Velocity使用WebWork的UI标签:如你所知, 从JSP转换到Velocity时失去了使用JSP标签的能力. 但WebWork的VelocityServlet提供一个方法: 使用#tag, #bodytag和#paramVelocity宏定义(velocimacros). 语法如下:#tag (name-of-tag list-of-attributes) – 或 – #bodytag (name-of-tag list-of-attributes) #param (key value) #param (key value) ... #end 让我们回顾4.1.1的表单示例来演示在velocity中使用UI标签的用法: xwork.xml:<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN" "http://www.opensymphony.com/xwork/xwork-1.0.dtd"> <xwork> <!-- Include webwork defaults (from WebWork JAR). --> <include file="webwork-default.xml" /> <!-- Configuration for the default package. --> <package name="default" extends="webwork-default"> <!-- Default interceptor stack. --> <default-interceptor-ref name="defaultStack" /> <!-- Actions: Lesson 4.2: FormProcessingAction using Velocity. --> <action name="formProcessingVelocityIndex" class="lesson04_02.FormProcessingIndexAction"> <result name="success" type="velocity">ex02-index.vm</result> </action> <action name="formProcessingVelocity" class="lesson04_01_01.FormProcessingAction"> <result name="input" type="velocity">ex02-index.vm</result> <result name="success" type="velocity">ex02-success.vm</result> <interceptor-ref name="validationWorkflowStack" /> </action> </package> </xwork> ex02-index.vm:<html> <head> <title>WebWork Tutorial - Lesson 4.2 - Example 2</title> <style type="text/css"> .errorMessage { color: red; } </style> </head> <body> <p>UI Form Tags Example using Velocity:</p> #bodytag (Form "action='formProcessingVelocity.action'" "method='post'") #tag (Checkbox "name='checkbox'" "label='A checkbox'" "fieldValue='checkbox_value'") #tag (File "name='file'" "label='A file field'") #tag (Hidden "name='hidden'" "value='hidden_value'") #tag (Label "label='A label'") #tag (Password "name='password'" "label='A password field'") #tag (Radio "name='radio'" "label='Radio buttons'" "list={'One', 'Two', 'Three'}") #tag (Select "name='select'" "label='A select list'" "list={'One', 'Two', 'Three'}" "emptyOption=true") #tag (Textarea "name='textarea'" "label='A text area'" "rows='3'" "cols='40'") #tag (TextField "name='textfield'" "label='A text field'") #tag (Submit "value='Send Form'") #end </body> </html> ex02-success.vm:<html> <head> <title>WebWork Tutorial Lesson 4.2 - Example 2</title> </head> <body> <p>UI Form Tags Example result using Velocity:</p> <ul> <li>checkbox: $!checkbox</li> <li>file: $!file</li> <li>hidden: $!hidden</li> <li>password: $!password</li> <li>radio: $!radio</li> <li>select: $!select</li> <li>textarea: $!textarea</li> <li>textfield: $!textfield</li> </ul> </body> </html> FormProcessingAction.java (与4.1.1相同):package lesson04_01_01; import com.opensymphony.xwork.ActionSupport; public class FormProcessingAction extends ActionSupport { private String checkbox; private String file; private String hidden; private String password; private String radio; private String select; private String textarea; private String textfield; public String getCheckbox() { return checkbox; } public String getFile() { return file; } public String getHidden() { return hidden; } public String getPassword() { return password; } public String getRadio() { return radio; } public String getSelect() { return select; } public String getTextarea() { return textarea; } public String getTextfield() { return textfield; } public void setCheckbox(String checkbox) { this.checkbox = checkbox; } public void setFile(String file) { this.file = file; } public void setHidden(String hidden) { this.hidden = hidden; } public void setPassword(String password) { this.password = password; } public void setRadio(String radio) { this.radio = radio; } public void setSelect(String select) { this.select = select; } public void setTextarea(String textarea) { this.textarea = textarea; } public void setTextfield(String textfield) { this.textfield = textfield; } public String execute() throws Exception { return SUCCESS; } } FormProcessingAction-validation.xml (与4.1.1相同):<!DOCTYPE validators PUBLIC "-//OpenSymphony Group//XWork Validator 1.0//EN" "http://www.opensymphony.com/xwork/xwork-validator-1.0.dtd"> <validators> <field name="checkbox"> <field-validator type="requiredstring"> <message>Please, check the checkbox.</message> </field-validator> </field> <field name="file"> <field-validator type="requiredstring"> <message>Please select a file.</message> </field-validator> </field> <field name="password"> <field-validator type="requiredstring"> <message>Please type something in the password field.</message> </field-validator> </field> <field name="radio"> <field-validator type="requiredstring"> <message>Please select a radio button.</message> </field-validator> </field> <field name="select"> <field-validator type="requiredstring"> <message>Please select an option from the list.</message> </field-validator> </field> <field name="textarea"> <field-validator type="requiredstring"> <message>Please type something in the text area.</message> </field-validator> </field> <field name="textfield"> <field-validator type="requiredstring"> <message>Please type something in the text field.</message> </field-validator> </field> </validators> 试试这个例子! — 上面的例子没有使用#param标签. 因此, 让我们回顾4.1.1中的另一个例子 - 定制组件:ex03.vm:<html> <head> <title>WebWork Tutorial - Lesson 4.2 - Example 3</title> </head> <body> <p>Custom Component Example:</p> <p> #bodytag (Component "template=datefield.vm") #param ("label" "Date") #param ("name" "mydatefield") #param ("size" "3") #end </p> </body> </html> /template/xhtml/datefield.vm (与4.1.1相同):#set ($name = $parameters.get('name')) #set ($size = $parameters.get('size')) #set ($yearSize = $size * 2) $parameters.get('label'): <input type="text" name="${name}.day" size="$size" /> / <input type="text" name="${name}.month" size="$size" /> / <input type="text" name="${name}.year" size="$yearSize" /> (dd/mm/yyyy) 注意, 这次我们没有像使用JSP标签那样将Date和mydatefield用单引号框起来. 试试这个例子! 上一课 | 下一课 |
Document generated by Confluence on Dec 14, 2004 16:36 |