4.1.1、WebWork UI标记
(1)创建表单
WebWork UI标记和HTML标记很相似,很容易从它的名字辨认出。你可以直接使用这些标记创建表单,和HTML标记的区别在于:参数使用双引号和单引号括起,这是因为要和Value Stack中的名字区分。看下面的例子:
ex01-index.jsp:
<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
.errorMessage { color: red; }
</style>
</head>
<body>
<p>UI Form Tags Example:</p>
<ww:form action="'formProcessing.action'" method="'post'">
<ww:checkbox name="'checkbox'" label="'A checkbox'" fieldValue="'checkbox_value'" />
<ww:file name="'file'" label="'A file field'" />
<ww:hidden name="'hidden'" value="'hidden_value'" />
<ww:label label="'A label'" />
<ww:password name="'password'" label="'A password field'" />
<ww:radio name="'radio'" label="'Radio buttons'" list="{'One', 'Two', 'Three'}" />
<ww:select name="'select'" label="'A select list'" list="{'One', 'Two', 'Three'}"
emptyOption="true" />
<ww:textarea name="'textarea'" label="'A text area'" rows="'3'" cols="'40'" />
<ww:textfield name="'textfield'" label="'A text field'" />
<ww:submit value="'Send Form'" />
</ww:form>
</body>
</html>
经WebWork处理后的HTML结果如下:
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 1</title>
<style type="text/css">
.errorMessage { color: red; }
</style>
</head>
<body>
<p>UI Form Tags Example:</p>
<table>
<form action="formProcessing.action" method="post" >
<tr><td valign="top" colspan="2">
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td valign="top">
<input type="checkbox" name="checkbox" value="checkbox_value" />
</td>
<td width="100%" valign="top">
<span class="checkboxLabel">
A checkbox
</span>
</td></tr>
</table>
</td></tr>
<tr><td align="right" valign="top">
<span class="label">
A file field:
</span>
</td>
<td>
<input type="file" name="file" />
</td></tr>
<input type="hidden" name="hidden" value="hidden_value" />
<tr><td align="right" valign="top">
<span class="label">
A label:
</span>
</td>
<td>
<label> </label>
</td></tr>
<tr><td align="right" valign="top">
<span class="label">
A password field:
</span>
</td>
<td>
<input type="password" name="password" />
</td></tr>
<tr><td align="right" valign="top">
<span class="label">
Radio buttons:
</span>
</td>
<td>
<input type="radio" name="radio" id="radioOne" value="One" />
<label for="radioOne">One</label>
<input type="radio" name="radio" id="radioTwo" value="Two" />
<label for="radioTwo">Two</label>
<input type="radio" name="radio" id="radioThree" value="Three" />
<label for="radioThree">Three</label>
</td></tr>
<tr><td align="right" valign="top">
<span class="label">
A select list:
</span>
</td>
<td>
<select name="select">
<option value=""></option>
<option value="One">One</option>
<option value="Two">Two</option>
<option value="Three">Three</option>
</select>
</td></tr>
<tr><td align="right" valign="top">
<span class="label">
A text area:
</span>
</td>
<td>
<textarea name="textarea" cols="40" rows="3" ></textarea>
</td></tr>
<tr><td align="right" valign="top">
<span class="label">
A text field:
</span>
</td>
<td>
<input type="text" name="textfield" />
</td></tr>
<tr><td colspan="2">
<div align="right" ><input type="submit" value="Send Form" /></div>
</td></tr>
</form>
</table>
</body>
</html>
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-2.1 JAR). -->
<include file="webwork-default.xml" />
<!-- Configuration for the default package. -->
<package name="default" extends="webwork-default">
<action name="formProcessing" class="lesson04_01_01.FormProcessingAction">
<result name="input" type="dispatcher">ex01-index.jsp</result>
<result name="success" type="dispatcher">ex01-success.jsp</result>
<interceptor-ref name="validationWorkflowStack" />
</action>
</package>
</xwork>
FormProcessingAction.java:
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:
<!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>
ex01-success.jsp:
<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 1</title>
</head>
<body>
<p>UI Form Tags Example result:</p>
<ul>
<li>checkbox: <ww:property value="checkbox" /></li>
<li>file: <ww:property value="file" /></li>
<li>hidden: <ww:property value="hidden" /></li>
<li>password: <ww:property value="password" /></li>
<li>radio: <ww:property value="radio" /></li>
<li>select: <ww:property value="select" /></li>
<li>textarea: <ww:property value="textarea" /></li>
<li>textfield: <ww:property value="textfield" /></li>
</ul>
</body>
</html>
Form的缺省布局是表格,左边是标签,右边是表单域。可以使用模板系统创建自己的布局。
注意Action配置中validationWorkflowStack的引用。这使得WebWork会根据Action类相同位置上的验证配置文件(FormProcessingAction-validation.xml),对传递给Action的参数进行验证。如果有非法参数,WebWork会阻止Action的执行,将请求指派的input结果页面,将错误信息显示到对应的表单域。
(2)模板系统
WebWork使用Velocity模板系统为所有的UI标记呈现实际的HTML输出。所有模板的缺省实现包含在webwork-2.1.jar的/template/xhtml目录下。这些模板可以被编辑或替换来定制HTML输出结果。
如果你想使用不同的布局来显示UI组件,你可以:
l 编辑或替换/template/xhtml目录下的文件
l 编辑webwork.properties文件(要放在/WEB-INF/classes目录下)的webwork.ui.theme,指向模板位置。
l 使用标记的theme或template属性为单个标记指定模板位置
下面是使用第三种方法的例子:
ex02.jsp:
<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 2</title>
</head>
<body>
<p>Template Change Example:</p>
<p><ww:checkbox name="'checkbox'" label="'A checkbox'"
fieldValue="'checkbox_value'" theme="/files/templates/components" /></p>
<p><ww:textfield name="'textfield'" label="'A text field'"
template="/files/templates/components/mytextfield.vm" /></p>
</body>
</html>
/files/templates/components/checkbox.vm:
<div align="center">
<input type="checkbox"
name="$!webwork.htmlEncode($parameters.name)"
value="$!webwork.htmlEncode($parameters.fieldValue)"
#if ($parameters.nameValue) checked="checked" #end
#if ($parameters.disabled == true) disabled="disabled" #end
#if ($parameters.tabindex) tabindex="$!webwork.htmlEncode($parameters.tabindex)" #end
#if ($parameters.onchange) onchange="$!webwork.htmlEncode($parameters.onchange)" #end
#if ($parameters.id) id="$!webwork.htmlEncode($parameters.id)" #end
/><br />
$!webwork.htmlEncode($parameters.label)
</div>
/files/templates/components/mytextfield.vm:
<div align="center">
<input type="text"
name="$!webwork.htmlEncode($parameters.name)"
#if ($parameters.size) size="$!webwork.htmlEncode($parameters.size)" #end
#if ($parameters.maxlength) maxlength="$!webwork.htmlEncode($parameters.maxlength)" #end
#if ($parameters.nameValue) value="$!webwork.htmlEncode($parameters.nameValue)" #end
#if ($parameters.disabled == true) disabled="disabled" #end
#if ($parameters.readonly) readonly="readonly" #end
#if ($parameters.onkeyup) onkeyup="$!webwork.htmlEncode($parameters.onkeyup)" #end
#if ($parameters.tabindex) tabindex="$!webwork.htmlEncode($parameters.tabindex)" #end
#if ($parameters.onchange) onchange="$!webwork.htmlEncode($parameters.onchange)" #end
#if ($parameters.id) id="$!webwork.htmlEncode($parameters.id)" #end
/><br />
$!webwork.htmlEncode($parameters.label)
</div>
ex02.jsp被处理后的HTML输出结果:
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 2</title>
</head>
<body>
<p>Template Change Example:</p>
<p><div align="center">
<input type="checkbox"
name="checkbox"
value="checkbox_value"
/><br />
A checkbox
</div></p>
<p><div align="center">
<input type="text"
name="textfield"
/><br />
A text field
</div></p>
</body>
</html>
(3)创建自定义UI组件
有时WebWork的UI组件没法满足你的需求,你可以创建自定义的组件。你可以使用WebWork推荐的方法创建布局干净、有错误检查、可重用的自定义组件。
要创建自定义组件,只要为它创建Velocity模板,使用<ww:component />标记将它放到Web页面中,使用template属性指定模板位置。要传递参数给模板,可以在<ww:component />标记中使用<ww:param />标记。下面的例子创建一个自定义的Date域:
ex03.jsp:
<%@ taglib uri="webwork" prefix="ww" %>
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 3</title>
</head>
<body>
<p>Custom Component Example:</p>
<p>
<ww:component template="/files/templates/components/datefield.vm">
<ww:param name="label" value="'Date'" />
<ww:param name="name" value="'mydatefield'" />
<ww:param name="size" value="3" />
</ww:component>
</p>
</body>
</html>
/files/templates/components/datefield.vm:
#set ($name = $tag.params.get('name'))
#set ($size = $tag.params.get('size'))
#set ($yearSize = $size * 2)
$tag.params.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)
ex03.jsp被处理后的HTML输出结果:
<html>
<head>
<title>WebWork Tutorial - Lesson 4.1.1 - Example 3</title>
</head>
<body>
<p>Custom Component Example:</p>
<p>
Date:
<input type="text" name="mydatefield.day" size="3" /> /
<input type="text" name="mydatefield.month" size="3" /> /
<input type="text" name="mydatefield.year" size="6" /> (dd/mm/yyyy)
</p>
</body>
</html>