您的位置:首页 > 编程语言 > Java开发

Struts2 表单和非表单标签

2017-06-02 08:46 260 查看
学习内容
Struts 2表单标签
 Struts 2非表单标签
能力目标
 熟练使用Struts 2表单标签开发表单
 熟练使用Struts 2非表单标签 

本章简介
上一章讲述了ognl和Struts2标签库中的数据访问标签和逻辑控制标签。本章将重点介绍Struts2标签库中的表单标签和非表单标签。
表单标签主要用于生成HTML中的表单。
非表单标签主要包含一些常用的功能标签,例如显示日期或树形菜单。熟练使用Struts2标签将大大简化视图页面的代码编辑工作,提高视图页面的维护效率。
核心技能部分 
 

7.1 表单标签

 Struts的表单标签,可分为两种:form标签本身和单个表单元素的标签。form标签本身的行为不同于表单元素标签。Struts 2的表单元素标签都包含了非常多的属性,但有很多属性完全是通用的。

7.1.1 表单标签的通用属性

所有表单标签处理类都继承了UIBean类,UIBean包含了一些通用属性,这些通用属性分成3种:
模板相关属性。
 JavaScript相关属性。
 通用属性。
除了这些属性之外,所有表单元素标签都存在一个特殊的属性:form,这个属性引用表单元素所在的表单,通过该form属性,可以实现表单元素和表单之间的交互。例如,我们可以通过${ parameters.form. id }来取得表单元素所在表单的ID。下面详细列出这些表单标签的通用属性。
模板相关的通用属性如下:
 templateDir:指定该表单所用的模板文件目录。
 theme:指定该表单所用的主题。
 template:指定该表单所用的模板。
Javascript相关的通用属性如下:
 onclick:指定鼠标在该标签生成的表单元素上单击时触发的JavaScript函数。
 onmousedown:指定鼠标在该标签生成的表单元素上按下时触发的JavaScript函数。
 onmouseup:指定鼠标在该标签生成的表单元素上松开时触发的JavaScript函数。
 onmouseover:指定鼠标在该标签生成的表单一元素上悬停时触发的JavaScript函数。
 onmouseout:指定鼠标移出该标签生成的表单元素时触发的JavaScript函数。
 onfocus:指定该标签生成的表单元素得到焦点时触发的函数。
 onblur:指定该标签生成的表单元素失去焦点时触发的函数。
 onkeypress:指定单击键盘上某个键时触发的函数。
 onkeyup:指定松开键盘某个键时触发的函数。
 onkeydown:指定按下键盘上某个键时触发的函数。
 onselect:对下拉列表项等可以选择表单元素,指定选中该元素时触发的JavaScript函数。
 onchange:对于文本框等可以接受输入的表单元素,指定当值改变时触发的JavaScript函数。
因为HTML元素本身的限制,并不是每个HTML元素都可以触发以上的所有函数。因此,上面的属性并不是对Struts 2的每个标签都有效。
Struts 2还允许为表单元素设置提示,但鼠标在这些元素上悬停时,系统将出现提示,
Struts 2将这种特性称为Tooltip。与Tooltip相关的通用属性如下:
 tooltip:设置此组件的Tooltip。
 tooltipIcon:设置Tooltip图标的URL路径。
 tooltipAboveMousePointer:是否在光标位置上显示Tooltip。也可通过设置tooltipOffseY属性,设置Tooltip与光标位置的垂直位移。
 tooltipBgColor:设置Tooltip的背景色。
 tooltipBgImg:设置Tooltip的背景图片。
 tooltipBorderWidth:设置Tooltip边框的宽度。
 tooltipBorderColor:设置Tooltip边框的颜色。
 tooltipDelay:设置显示Tooltip的时间延迟(单位是毫秒)。
 tooltipFixCoordinateX:设置固定Tooltip在指定的X坐标上,与tooltipSticky属性结合时很有用。
 tooltipFixCoordinateY设置固定Tooltip在指定的Y坐标上,与tooltipSticky属性结合时很有用。
 tooltipFontColor:设置Tooltip的字体颜色。
 tooltipFontFace:设置Tooltip的字体,例如verdana.  geneva,  sans-serif等。
 tooltipFontSize:设置Tooltip的字体大小,例如30px。
 tooltipFontWeight:设置Tooltip的字体是否使用粗体,可以接受normal和bold(粗体)两个值。
 tooltipLeftOfMousePointer:设置是否在光标左侧显示Tooltip,默认是在右边显示。
 tooltipOffsetX:设置Tooltip相对光标位置的水平位移。
 tooltipOffsetY:设置Tooltip相对光标位置的垂直位移。
 tooltipOpacity:设置Tooltip的透明度,设置值可以是0(完全透明)和100(不透明)之间的数字。Opera浏览器不支持该属性。
 tooltipPadding:指定Tooltip的内部间隔。例如,边框和内容之间的间距。
 tooltipShadowColor:使用指定的颜色为Tooltip创建阴影。
 tooltipShadowWidth:使用指定的宽度为Tooltip创建阴影。
 tooltipStatic:设置Tooltip是否随着光标的移动而移动。
 tooltipSticky:设置Tooltip是否一直停留在它初始的位置,直到另外一个Tooltip被激活,或者浏览者点击了HTML页面。
 tooltipStayAppearTime:指定一个Tooltip消失的时间间隔(毫秒),即使鼠标还在相关的HTML元素上不动。设置值<=0,就和没有定义一样。
 tooltipTextAlign:设置Tooltip的标题和内容的对齐方式,可以是right(右对齐)、left(左对齐)或justify(居中对齐)。
 tooltipTitle:设置Tooltip的标题文字。
 tooltipTitleColor:设置Tooltip的标题文字的颜色。
 tooltipWidth:设置Tooltip的宽度。
除此之外,Struts 2还有其他的通用属性,用于设置表单元素的CSS样式等。
 cssClass:设置该表单元素的class属性。
 cssStyle:设置该表单一元素的style属性,使用内联的CSS样式。
 title:设置表单元素title属性。
 disabled:设置表单元素的disabled属性。
 label:设置表单元素的label属性。
 labelPosition:设置表单元素label所在位置,可接受的值为top(上面)和left(左边),默认是在左边。
 requiredposition:定义必填标记(默认以*作为必填标记)位于label元素的位置,可接受的值为left(左面)和right(右边),默认是在右边。
 name:定义表单一元素的name属性,该属性值用十与Action的属性形成对应。
 required:定义是否在表单元素的label上增加必填标记(默认以*作为必填标记),设置为true时增加必填标记,否则不增加。
 tabIndex:设置表单元素的tabindex属性。
 value:设置表单兀素的value属性。
7.1.2 表单标签的name和value属性
对于表单元素而言,name和value属性之间存在一个独特的关系:因为表单元素的name属性会映射到Action的属性,当该表单对应的Action已经被实例化,且对应属性有值时,表单元素会显示出该属性的值,该值就是表单元素的value值。
name属性设置表单元素的名字,表单元素的名字实际上封装着一个请求参数,而请求参数是被封装到Action属性的。因此,可以将该name属性指定为你希望绑定值的表达式。    例如如下代码:
<!--将下面文本框的值绑定到Action的person属性的firstName属性 -- >
      <s:textfield  name="person.firstName”/>
大多数场景下,我们希望表单元素里可以显示出对应Action的属性值,此时就可以通过指定该表单元素的value属性来完成该工作。例如使用如下代码:
    <!--使用表达式生成表单元素的值一>
      <s:textfield name=”person.firstName” value=”${person.firstName}”/>
事实上,因为name和value属性的特殊关系,如果我们使用Struts 2的标签库,则无需指定value属性,因为Struts 2会为我们处理这些。
对于如下代码:
    <!一将下面文本框的值绑定到Action的person属性的firstName属性一>
      <s:textfield name=”person.firstName"/>
虽然上面的文本框没有指定value属性,但Struts 2一样会在该文本框中输出对应Action里的属性值。

7.1.3 常用表单标签

1.  <s:form>标签
该标签的主要属性是action和namespace,例如下面的代码:
<s:form action="tag1.action" namespace="/tags">
</s:form>
生成的HTML代码如下所示:
<form action="tag1.action" method="post">
2. 文本类标签
此类标签包括文本框(<s:textfield />)、密码框(<s:password />)、文本区域(<s:textarea>),下面是一个简单的示例。
示例7.1
<body>
<s:form action="tag1" namespace="/tags">
<s:textfield name="loginname" label="登录名称"></s:textfield>
<s:password name="pwd" label="登录密码"></s:password>
<s:textarea name="info" label="个人简介" cols="28" rows="10"></s:textarea>
<s:submit value="提交"></s:submit>
<s:reset value="重填"></s:reset>
</s:form>
</body>


 
图7.1.1 文本类标签
上述代码生成的HTML如下所示。
<body>
<form action="/Struts8/tags/tag1.action" method="post">
<table class="wwFormTable">
<tr>
<td class="tdLabel">
<label for="tag1_loginname" class="label">登录名称:</label></td>
<td>
<input type="text" name="loginname"/></td>
</tr>
<tr>
<td class="tdLabel"><label for="tag1_pwd" class="label">登录密码:</label>
</td>
<td>
<input type="password" name="pwd" id="tag1_pwd"/></td>
</tr>
<tr>
<td class="tdLabel">
<label for="tag1_info" class="label">个人简介:</label>
</td>
<td>
<textarea name="info" cols="28" rows="10"></textarea>
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="提交"/></td>
</tr>
<tr>
<td colspan="2"><input type="reset" value="重填"/></td>
</tr>
</table>
</form>
</body>3. checkboxlist标签
checkboxlist标签可以一次创建多个复选框,用于一次生成多个HTML标签中的<input type="checkbox"…/>,它根据list属性指定的集合来生成多个复选框。因此,使用该标签指定一个list属性。除此之外,其他属性大部分是通用属性,此处不再赘述。
除此之外,checkboxlist表单还有两个常用属性:
 listKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的value。如果集合是Map,则可以使用key和value值分别代表Map对象的key和value作为复选框的value 。
 listValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使key和value值分别代表Map对象的key和value作为复选框的标签。
下面是使用该标签的代码示例,其中分别使用了简单集合、简单Map对象、集合里放置Java实例来创建多个复选框。
下面是该JSP页面代码:
<body>
<h2>使用checkboxlist标签</h2>
<s:form>
<!-- 使用字符串集合生成多个复选框 -->
<s:checkboxlist
list="{'JSP','Servlet','Struts2','Ajax'}" name="skills"
label="熟悉技术">
</s:checkboxlist>
<!-- 使用Map对象来生成多个复选框 -->
<s:checkboxlist name="skillsarea" label="你所关注的技术领域"
list="#{'java':'JAVA', '.net':'.NET', 'db':'Database','ajax':'Ajax'}"
listKey="key"
listValue="value"/>
</s:form>
</body>在上面代码中,简单集合对象和简单Map对象都是通过OGNL表达式直接生成,但实际使用中一般是从后台查询出一个javaBean集合然后传递到页面进行显示。该JavaBean的类代码如下:
public class Book
{
private int id;
     private  String bookName;
private  String author;
//getter setter方法省略…….
}
Jsp页面代码:
<%
//模拟后台查询到的数据 并转发到页面
List books = new ArrayList();
books.add(new Book(1,"杀杀人,喝喝酒---水浒传","施耐庵"));
books.add(new Book(2,"疯狂的猴子---西游记","吴承恩"));
books.add(new Book(3,"疯狂的石头---红楼梦","曹雪芹"));
books.add(new Book(4,"大哥,我们动手吧---三国演义","罗贯中"));
request.setAttribute("bs",books);
%>
<s:form>
<!-- 使用字符串集合生成多个复选框 -->
<s:checkboxlist
list="{'JSP','Servlet','Struts2','Ajax'}" name="skills"
label="熟悉技术">
</s:checkboxlist>
<!-- 使用Map对象来生成多个复选框 -->
<s:checkboxlist name="skillsarea" label="你所关注的技术领域"
list="#{'java':'JAVA', '.net':'.NET', 'db':'Database','ajax':'Ajax'}"
listKey="key"
listValue="value"/>

<s:checkboxlist label="你喜欢的图书" name="lb" list="#attr.bs"
listKey="id" listValue="bookName" value="1"
>
</s:checkboxlist>
</s:form>当我们在浏览器中浏览该页面时,将看到如图7.1.2所示的页面。 

图7.1.2 checklist标签
生成的HTML代码如下所示:
<html>
<head>
<base href="http://localhost:8080/test23/">

<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>

<body>

<form id="" action="/test23/" method="post">
<table class="wwFormTable">
<!-- 使用字符串集合生成多个复选框 -->

<tr>
<td class="tdLabel"><label for="_skills" class="label">熟悉技术:</label></td>
<td
>
<input type="checkbox" name="skills" value="JSP" id="skills-1"/>
<label for="skills-1" class="checkboxLabel">JSP</label>
<input type="checkbox" name="skills" value="Servlet" id="skills-2"/>
<label for="skills-2" class="checkboxLabel">Servlet</label>
<input type="checkbox" name="skills" value="Struts2" id="skills-3"/>
<label for="skills-3" class="checkboxLabel">Struts2</label>
<input type="checkbox" name="skills" value="Ajax" id="skills-4"/>
<label for="skills-4" class="checkboxLabel">Ajax</label>
<input type="hidden" id="__multiselect__skills" name="__multiselect_skills" value="" /> </td>
</tr>
<!-- 使用Map对象来生成多个复选框 -->
<tr>
<td class="tdLabel"><label for="_skillsarea" class="label">你所关注的技术领域:</label></td>
<td
>
<input type="checkbox" name="skillsarea" value="java" id="skillsarea-1"/>
<label for="skillsarea-1" class="checkboxLabel">JAVA</label>
<input type="checkbox" name="skillsarea" value=".net" id="skillsarea-2"/>
<label for="skillsarea-2" class="checkboxLabel">.NET</label>
<input type="checkbox" name="skillsarea" value="db" id="skillsarea-3"/>
<label for="skillsarea-3" class="checkboxLabel">Database</label>
<input type="checkbox" name="skillsarea" value="ajax" id="skillsarea-4"/>
<label for="skillsarea-4" class="checkboxLabel">Ajax</label>
<input type="hidden" id="__multiselect__skillsarea" name="__multiselect_skillsarea" value="" /> </td>
</tr>
<tr>
<td class="tdLabel"><label for="_lb" class="label">你喜欢的图书:</label></td>
<td
>
<input type="checkbox" name="lb" value="1" id="lb-1" checked="checked"/>
<label for="lb-1" class="checkboxLabel">杀杀人,喝喝酒---水浒传</label>
<input type="checkbox" name="lb" value="2" id="lb-2"/>
<label for="lb-2" class="checkboxLabel">疯狂的猴子---西游记</label>
<input type="checkbox" name="lb" value="3" id="lb-3"/>
<label for="lb-3" class="checkboxLabel">疯狂的石头---红楼梦</label>
<input type="checkbox" name="lb" value="4" id="lb-4"/>
<label for="lb-4" class="checkboxLabel">大哥,我们动手吧---三国演义</label>
<input type="hidden" id="__multiselect__lb" name="__multiselect_lb" value="" /> </td>
</tr>
</table></form>
</body>
</html>从图7.1.2中可以看出,通过指定checkboxlist标签的listKey和listValue属性,可以分别指定多个复选框的value和标签。
4. radio标签
该标签与上面的checkboxlist标签的用法几乎完全相同,都是通过指定list、listKey、listValue等属性来生成HTML元素。不同的是,checkboxlist标签生成的是复选框,而radio标签生成的是单选框。
下面我们看一个实例,代码如下所示:
示例7.2
<body>
<h2>使用radio标签</h2>
<s:form>
<!-- 使用字符串集合来生成多个单选框 -->
<s:radio
   list="{'JSP','Servlet','Struts2','Ajax'}" name="skills"
     label="熟悉技术">
</s:radio>
<!-- 使用Map对象来生成多个单选框 -->
<s:radio name="skillsarea" label="你所关注的技术领域"
    list="#{'java':'JAVA', '.net':'.NET', 'db':'Database','ajax':'Ajax'}"
  listKey="key"
  listValue="value"
  value="'java'"/>
</s:form>
</body>
该页面的运行效果如图7.1.3所示。

 
<body>
<h2>使用radio标签</h2>
<form action="/Struts8/s-radio.jsp" method="post">
<table class="wwFormTable">
<!-- 使用字符串集合来生成多个单选框 -->
<tr>
<td class="tdLabel">
<label for="s-radio_skills" class="label">熟悉技术:</label></td>
<td>
<input type="radio" name="skills" value="JSP"/>
<label for="s-radio_skillsJSP">JSP</label>
<input type="radio" name="skills" value="Servlet"/>
<label for="s-radio_skillsServlet">Servlet</label>
<input type="radio" name="skills" value="Struts2"/>
<label for="s-radio_skillsStruts2">Struts2</label>
<input type="radio" name="skills" value="Ajax"/>
<label for="s-radio_skillsAjax">Ajax</label>
</td>
</tr>
<!-- 使用Map对象来生成多个单选框 -->
<tr>
<td class="tdLabel"><label for="s-radio_skillsarea" class="label">
你所关注的技术领域:</label></td>
<td>
<input type="radio" name="skillsarea" checked="checked" value="java"/>
<label for="s-radio_skillsareajava">JAVA</label>
<input type="radio" name="skillsarea" value=".net"/>
<label for="s-radio_skillsarea.net">.NET</label>
<input type="radio" name="skillsarea" value="db"/>
<label for="s-radio_skillsareadb">Database</label>
<input type="radio" name="skillsarea" value="ajax"/>
<label for="s-radio_skillsareaajax">Ajax</label>
</td>
</tr>
</table>
</form>
</body>

5. select标签
select标签用于生成一个下拉列表框,通过为该元素指定list属性,系统会使用list属性指定的集合来生成下拉列表框的选项。这个list属性指定的集合,既可以是普通集合,也可以是Map对象,还可以是集合元素是对象的集合。
除此之外,select表单还有如下几个常用属性:
Ø listKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的value。如果集合是Map,则可以使用key和value值分别代表Map对象的key和value作为复选框的value。
Ø listValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map ,则可以使用key和value值分别代表Map对象的key和value作为复选框的标签。
Ø multiple:设置该列表框是否允许多选。
从上面介绍中可以看出,select标签的用法与checkboxlist标签的用法非常相似。
下面我们看一个实例,其中分别使用了简单集合、简单Map对象、集合里放置Java实例来创建多个复选框。代码如下所示:
示例7.3
 
     <body>
  <h2>使用select标签</h2>
<!-- 使用字符串集合来生成下拉列表框 -->
<s:elect list="{'Struts2从入门到精通' , 'Spring2开发宝典' , 'Ajax实战'}"
     name="books" label="图书列表">
</s:select>
<br><br>
<!-- 使用简单对象来生成下拉列表框 -->
<s:select name="books_map" label="图书列表"
    list="#{'struts2':'Struts2从入门到精通', 'spring2':'Spring2开发宝典',
             'ajax':'Ajax实战'}"
listKey="key"
listValue="value"/>
<br><br>
<s:select name="b" label="图书列表"
          multiple="true"
            list="#attr.bs"
          listKey="id"
            listValue="bookName" value="2"/>
  </body>
 
该页面的运行效果如图7.1.4所示。 


图7.1.4  使用select标签
注意:可以使用select的value属性设置<s:select>标签生成下拉框时的初始值,默认情况下将以生成下拉框的第一项为初始值。
6. doubleselect标签
    doubleselect标签会生成一个级联列表框(会生成两个下拉列表框),当选择第一个下
拉列表框时,第二个下拉列表框的内容会随之改变。
    因为两个都是下拉选择框,因此需要指定两个下拉选择框的选项,因此有如下常用的属性:
 list:指定用于输出第一个卜拉列表框中选项的集合。
 listKey:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为第一个下拉列表框的value。如果集合是Map,则可以使用key和value值分别代表Map对象的key和value作为复选框的value。
 listValue:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使用key和value值分别代表Map对象的key和value作为第一个下拉列表框的标签。
 doubleList:指定用于输出第一个下拉列表框中选项的集合。
 doubleList Key:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为第一个下拉列表框的value。如果集合是Map,则可以使用key和value值分别代表Map对象的key和value作为复选框的value。
 doubleList Value:该属性指定集合元素中的某个属性(例如集合元素为Person实例,指定Person实例的name属性)作为复选框的标签。如果集合是Map,则可以使用key和value值分别代表Map对象的key和value作为第一个下拉列表框的标签。
 doubleName:指定第二个下拉列表框的name属性。
 cssStyle:设置第一级下拉框的样式。
 doubleCssStyle:设置第二级下拉框的样式。
下面看一个实例,代码如下所示:
示例7.4
(1)创建用于描述部门的实体类。
 
public class DeptInfo {
 
private String deptId;
private String deptName;
private Set<EmpInfo> empSet = new HashSet<EmpInfo>();//包含多个职工

//无参构造函数
public DeptInfo() {
super();
}
//有参构造函数
public DeptInfo(String deptId, String deptName) {
super();
this.deptId = deptId;
this.deptName = deptName;
}
//getter setter 方法省略......

}
(2)创建用于描述职工的实体类。
public class EmpInfo {
private String empId;
private String empName;
//无参构造函数
public EmpInfo() {
super();
}
//有参构造函数
public EmpInfo(String empId, String empName) {
super();
this.empId = empId;
this.empName = empName;
}
//getter setter 方法省略......
} (3)创建业务逻辑控制器。
public class DoubleSelectAction extends BaseAction
{
//用于封装用户请求的部门编号
private String deptId;
//用于封装用户请求的职工编号
private String empId;
public String execute() throws Exception
{
//获取输出对象
PrintWriter out = super.getResponse().getWriter();
out.println("<h2>你选择的信息是: <hr/>部门编号: " +
this.deptId + "<br/>");
out.println(" 职工编号: " + this.empId + "</h2>");
return null;
}
public String getDeptId() {
return deptId;
}
public void setDeptId(String deptId) {
this.deptId = deptId;
}
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
}(4)创建jsp页面。
<body>
<%
DeptInfo d1 = new DeptInfo("D001","销售部");
DeptInfo d2 = new DeptInfo("D002","财务部");
EmpInfo e1 = new EmpInfo("E001","张三");
EmpInfo e2 = new EmpInfo("E002","李四");
EmpInfo e3 = new EmpInfo("E003","王五");
EmpInfo e4 = new EmpInfo("E004","赵六");

d1.getEmpSet().add(e1);
d1.getEmpSet().add(e2);

d2.getEmpSet().add(e3);
d2.getEmpSet().add(e4);
//构造map,用于存放所有部门
Map map = new HashMap();
map.put(d1,d1.getEmpSet());
map.put(d2,d2.getEmpSet());
request.setAttribute("map",map);
%>

<s:form action="doubleSelect" namespace="/test">
级联下拉框:<hr/>
<s:doubleselect cssStyle="width:130px" list="#request.map.keySet()" listKey="deptId" listValue="deptName" name="deptId"
doubleCssStyle="width:130px" doubleList="#request.map[top]" doubleListKey="empId" doubleListValue="empName" doubleName="empId"/>
<hr>
<s:submit value="提交"/>
</s:form>
</body>运行以上Jsp页面,结果如图7.1.5所示, 

图7.1.5 DoubleSelect标签的使用
在图7.1.5中,对第一级“部门”下拉框做任意选择时,第二级“职工”下拉框内容将做相应的级联改变。
单击“提交”按钮,提交到DoubleSelectAction控制器,运行结果如图7.1.6所示。 

图7.1.6 级联下拉框提交
注意:
使用doubleselect标签时,必须放在<<s:form…/>标签中使用,且必须为该<s:form .../>标签指定action属性 
7. optiontransferselect标签
Optiontransferselect创建两个选项用来转移下拉列表项,该标签会生成两个<select/>标签,并且会生成系列的按钮,这系列的按钮可以控制选项在两个下拉列表之间移动、升降。当提交该表单时,两个<select/>标签的请求参数都会被提交。
因为该标签会生成两个下拉列表框,因此需要分别指定两个下拉列表框中的集合、Label等属性,下面是该标签常用的属性。
 addAllToLeftLabel:设置全部移动到左边按钮上的文本。
 addAllToRightLabel:设置全部移动至右边按钮上的文本。
 addToLeftLabel:设置向左移动按钮上的文本。
 addToRightLabel:设置向右移动按钮上的文本。
 a1lowAddAllToLeft:设置是否出现全部移动到左边的按钮。
 a1lowAddAllToRight:设置是否出现全部移动到右边的按钮。
 a1lowAddToLeft:设置是否出现移动到左边的按钮。
 a1lowAddToRight:设置是否出现移动到右边的按钮。
 leftTitle:设置左边列表框的标题。
 rightTitle:设置右边列表框的标题。
 a1lowSelectAll:设置是否出现全部选择按钮。
 selectAllLabel:设置全部选择按钮上的文本。
 doubleList:设置用于创建第二个下拉选择框的集合。
 doubleListKey:设置创建第二个下拉选择框的选项value的属性。
 doubleListValue:设置创建第二个下拉选择框的选项label的属性。
 doubleName:设置第二个下拉选择框的name属性。
 doubleValue:设置第二个下拉选择框的value属性。
 doubleMultiple:设置第二个下拉选择框是否允许多选。
 list:设置用于创建第一个下拉选择框的集合。
 listKey:设置创建第一个下拉选择框的选项value的属性。
 listValue:设置创建第一个下拉选择框的选项label的属性。注意此处的list ,  doubleList ,   listKey ,  doubleListKey ,  listValue和doubleListValue非常类似于checkboxlist标签中list, listKey和listValue的用法,只是此处用于生成两个下拉列表框,而前者是生成多个复选框而已。
 name:设置第一个下拉选择框的name属性。
 value:设置第一个下拉选择框的value属性。
 multiple:设置第一个下拉选择框是否允许多选。
下面代码是使用optiontransferselect标签的示范,它分别指定了两个简单集合来生成两个下拉列表框的列表项。下面是使用optiontransferselect标签的代码:
<!-- 使用简单集合对象来生成可移动的下拉列表框 其中list指定生成第一个下拉选择框的选项的集合
          doubleList指定生成第二个下拉选择框的选项的集合-->
      <s:optiontransferselect
        label="请选择你喜欢的图书"
              name="cnb00k"
          leftTitle="中文图书"
        rightTitle="外文图书"
        list="{'Spring2.。宝典','轻量级J2EE企业应用实战','基于J2EE的Ajax宝典'}"
          multiple="true"
        addToLeftLabel="向左移动"
        selectAllLabel="全部选择"
          addAllToRightLabel="全部右移"
            headerKey="cnKey"
        headerValue="一选择中文图书一"
          emptyOption="true"
          doubleList="{'Expert One一on一One J2EE Design and Development’,
                ,'JavaScript:The Definitive Guide’}"
              doubleName="enBook"
doubleHeaderKey="enKey"
doubleHeaderValue="-一选择外文图书-一"
doubleEmptyOption="true"
doubleMultiple="true"></s:optiontransferselect>
在浏览器中浏览该页面,将看到如图7.1.7所示的页面。 

图7.1.7  optiontransferselect标签
8. token标签
<s:token>标签用于避免刷新页面时多次提交表单,通过借助于TokenInterceptor拦截器来实现阻止页面重复提交。当Jsp使用<s:token/>标签的时候,Struts2会建立一个GUID(全局唯一的字符串)并放在Session中,同时在表单中添加一个隐藏域。而TokenInterceptor拦截器会拦截用户的请求,并判断客户端form提交的token与session中保存的token是否相等 ,如果相等,则执行action对应的方法并清空;否则,拦截器将直接返回invalid.token结果,不会执行Action对应的方法。示例7.5演示了使用token标签的过程。
示例7.5
(1)创建用于处理用户注册的业务逻辑控制器Action.
public class RegAction extends ActionSupport {
private String uid;
private String pwd;
public String execute() throws Exception
{
HttpServletResponse response = (HttpServletResponse)ActionContext.getContext().get(ServletActionContext.HTTP_RESPONSE);
response.setContentType("text/html;charset=gbk");
response.setCharacterEncoding("gbk");
PrintWriter out = response.getWriter();
Date today = new Date();
out.println("<h2>用户注册信息如下: <hr/>用户名:" + this.uid + "<br/>密 码:" + this.pwd+"<hr>");
out.println("正在进行注册 " + today.toLocaleString() + "...");
return null;
}
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}(2)创建Jsp页面,命名为“reg.jsp”。
  <body>
<font color="red"><s:actionerror/></font>
<s:form action="reg" onsubmit="return check()">
<!-- 加入token标签 -->
<s:token/>
填写会员注册信息:<hr/>
用户名:<s:textfield name="uid"/><br/>
密 码:<s:password name="pwd"/><br>
确认密码:<s:password name="surePwd"/><br>
<s:submit value="提交"></s:submit>
<s:reset value="重置"></s:reset>
</s:form>
<script type="text/javascript">
function $(elementName)
{
return document.getElementById(elementName);
}
function check()
{
if($("reg_uid").value == "")
{
alert("用户名不能为空!");
$("reg_uid").focus();
return false;
}
if($("reg_pwd").value == "")
{
alert("密码不能为空!");
$("reg_pwd").focus();
return false;
}
if($("reg_pwd").value != $("reg_surePwd").value)
{
alert("两次密码不一致!");
$("reg_surePwd").focus();
return false;
}
return true;
}
</script>
</body>(3)编写用于显示重复提交错误信息的资源文件,创建application_zh.properties中文资源文件,将文件存放于WEB-INF/classes目录下,内容为“Struts.messages.invalid.token=表单已提交,不能重复提交”,并使用native2Ascii命令进行转化。
(4)在struts.xml中配置token拦截器。
 <struts>
<constant name="struts.ui.theme" value="simple" />
<constant name="struts.custom.i18n.resources" value="application" />
<package name="mypackage" extends="struts-default">
<!-- 定义拦截器栈
-->
<interceptors>
<interceptor-stack name="tokenStack">
<interceptor-ref name="token" />
<!-- 使用token拦截器
-->
<interceptor-ref name="defaultStack" />
<!-- 使用默认拦截器
-->
</interceptor-stack>
</interceptors>
<!-- 将拦截器栈token作为默认拦截器,则拦截器栈中定义的所有拦截器将作用于本包的所有Action
-->
<default-interceptor-ref name="tokenStack" />
<!-- 配置注册Action
-->
<action name="reg" class="com.zzab.entity.RegAction">
<!-- 当用户重复提交表单时,流程转到stoken.jsp
-->
<result name="invalid.token">/stoken.jsp</result>
</action>
</package>
</struts>运行reg.jsp,运行效果如图7.1.8所示。

 
图7.1.8 登录页面
单击【提交】按钮后就执行了对应的Action,如图7.1.9所示。 


图7.1.9 执行Action
此时刷新页面,则根据token拦截器配置,将进入invalid.token逻辑结果,即reg.jsp。该页面会通过<s:actionerror/>标签读取application_zh.prooperties中文资源文件的内容并显示。如图7.1.10所示。

 图7.1.10 不能重复提交

7.1 非表单标签

7.2.1 Datetimepicker标签 

datetimepicke:标签生成一个日期、时间下拉选择框,当我们使用该日期、时间选择框选择某个日期、时间时,系统会自动将选中的日期、时间输入指定文本框。
系统将指定日期、时间输入指定文本框时,必须转换成日期、时间字符串,为了设置该字符串的格式,必须使用日期、时间的格式符。datetimepicker支持如下几个格式符:
#dd:以两位数字来显示当前日期的日。
#d:试图以一位数字来显示当前日期的日,它不会使用两位数字。
#MM:以两位数字来显示当前日期的月。
#M:试图以一位数字来显示当前日期的月,它不会使用两位数字。
#YYYY:以4位数字来显示当前日期的年。
#YY:以两位数字来显示当前日期的年。
#y:以一位数字来显示当前日期的年的最后一位。
使用该标签时,有如下几个常用属性:
 displayFormat:该属性指定日期的显示格式,例如,可以使用dd/MM/yyyy作为日期格式。
 displayWeeks:该属性指定该日历能显示星期数。
 endDate:指定日期集的最后可用日期。例如2941-10-12,一旦指定了该日期,则后面的日期不可用。
 formatLength:指定日期显示的格式,这些格式值就是DateFormat中的格式,该属性支持的值有long,  short,  medium和full 4个值。
 language:指定日期显示的Locale,例如需要指定简体中文,则指定zh_ CN。
 startDate:指定日期集的最后可用日期。例如1941-10-18,一旦指定了该日期,则前面的日期不可用。
 toggleDuration:指定日期选择框出现、隐藏的切换时间。
 toggletype:指定日期选择框出现、隐藏的方式,可以选择plain, wipe, explode和fade 4个值。
 type:指定日期选择框的类型,支持的值有date和time,分别代表日期选择框、时间选择框。
 value:指定当前日期、时间。可使用today来代表今天。
 weekStartsOn:指定口期选择框中哪一天才是一周的第一天。周日是0,周六是6。
在使用datetimepicker标签之前,首先要通过MyEclipse导入struts2-dojo-plugin-2.2.1.jar文件,因为该标签包含在这个Jar文件中。
示例7.6
下面我们看一个该标签的实例,代码如下所示:  
<s:form theme="simple">
日期选择部件,指定toggleType属性,且指定value="today"<br>
<sx:datetimepicker name="order.date" label="购买日期" toggleType="explode"
value="%{'today'}"/><hr>
日期选择部件,指定了format属性<br>
<sx:datetimepicker name="order.date" label="购买日期" displayFormat=
"yyyy年MM月dd日"/><hr>
日期选择部件,指定了weekStartOn属性<br>
<sx:datetimepicker name="order.date" label="购买日期" displayFormat="yyyy年MM月dd日" weekStartsOn="2"/><hr>
</s:form>在浏览器中浏览该页面,将看到如图7.1.11所示的页面,在图7.1.11中,如果我们单击那些文本框后选择日期,将出现一个日期选择框。如果我们指定weekStartsOn属性,则可以设置口期选择框中每周中哪一天才会是第一天。 

图7.1.11 日期控件
 7.2.2 tree标签和treenode标签
这两个标签主要用来生成一个树形结构,例如常见的树形菜单、树形列表等。tree标签表示树根,treenode标签表示树的的节点,需要嵌套在tree标签中。在使用这两个标签之前,也需要通过MyEclipse导入struts2-dojo-plugin-2.2.1.jar文件。
示例7.7
下面是一个使用tree标签和treenode标签生成静态树形列表的示例。
<%@ page contentType="text/html; charset=utf-8" language="java" %>
<%@taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sdt" uri="/struts-dojo-tags"%>
<html>
<sdt:head parseContent="true"/>
<title>使用tree和treenode标签生成静态树</title>
<body>
<h3>使用tree和treenode标签生成静态树</h3>
<sdt:tree label="计算机编程系列图书" id="books">
<sdt:treenode label="JAVA编程系列" id="java">
<sdt:treenode label="Spring2.0开发宝典" id="spring"/>
<sdt:treenode label="Struts2.0权威指南" id="struts"/>
<sdt:treenode label="Hibernate3从入门到精通" id="hibernate"/>
</sdt:treenode>
<sdt:treenode label="Ajax编程系列" id="ajax">
<sdt:treenode label="JavaScript一百例" id="javascript"/>
<sdt:treenode label="Ajax实战" id="ajaxsz"/>
</sdt:treenode>
</sdt:tree>
</body>
</html>通过上述代码可以看到,tree和treenode标签都是通过label属性来设置树形列表文本,此案例树形列表中的文本数据都写死到里面了,实际应用中通常是从数据库查询出来并由Action返回到页面中。运行效果如图7.1.12所示。

 
图7.1.12 树形列表
本章总结
 Struts的表单标签
可分为两种:form标签本身和单个表单元素的标签。form标签本身的行为不同于表单元素标签。Struts 2的表单元素标签都包含了非常多的属性,但有很多属性完全是通用的。
 非表单标签
(1)datetimepicke:标签生成一个日期、时间下拉选择框,当我们使用该日期、时间选择框选择某个日期、时间时,系统会自动将选中的日期、时间输入指定文本框。
(2)tree标签和treenode标签。这两个标签主要用来生成一个树形结构,例如常见的树形菜单、树形列表等。tree标签表示树根,treenode标签表示树的的节点,需要嵌套在tree标签中。

任务实训部分

1:脏字过滤

训练技能点
 token标签
 token拦截器
  需求说明
在第五章的任务实现部分,我们实现了对评论进行脏字过滤功能,现在要求增加防止表单重复提交的功能。

2:简易计算器

训练技能点
 OGNL
 表单标签
  需求说明
在前面的章节中我们实现了一个简易计算器案例,现在要求使用Struts 2表单标签和OGNL对该案例进行重构。

3:动态生成树

训练技能点
 OGNL
 Tree标签
  需求说明
要求使用Struts 2 tree标签和OGNL动态生成数据。
实现思路
(1) 创建用于查询树节点信息的Action,命名为TreeAction.java。
public class TreeAction extends ActionSupport {  public String execute() { Object[][] obj = {   {"1","0","短信平台管理","#"},   {"2","1","用户管理","#"},   {"3","1","员工管理","#"},   {"4","1","短信管理","#"},   {"5","2","用户权限管理","userRight.jsp"},   {"6","2","用户列表","userList.jsp"},   {"7","3","员工信息列表","empList.jsp"},   {"8","3","员工信息修改","empUpdate.jsp"},   {"9","4","接收短信","acceptMessage.jsp"},   {"10","4","短信统计","messageCount.jsp"}   };  ServletActionContext.getRequest().setAttribute("obj",obj);  return SUCCESS; }}
(2) 配置TreeAction。
<action name="treeaction" class="com.zzzy.action.TreeAction"> <result>/sx_tree.jsp</result> </action>
(3) 创建sx_tree.jsp。
<sx:tree label="短信管理平台">  <s:iterator id="row" value="#request.obj">  <s:if test="#row[1]==1">  <sx:treenode label="%{#row[2]}">  <s:iterator id="row1" value="#request.obj">  <s:if test="#row1[1]==#row[0]">  <sx:treenode label="<a href=%{#row1[3]}>%{#row1[2]}</a>" />  </s:if>  </s:iterator>  </sx:treenode>  </s:if>    </s:iterator>  </sx:tree>
巩固练习
一、选择题
1. 以下()不属于Struts 2的表单标签。
A. <s:textfield>
B. <s:textarea>
C. <s:submit>
D. <s:tree>
2. token标签的作用是()。
A. 显示错误消息
B. 校验表单数据
C. 防止重复提交
D. 生成相应的html标签
3. Datetimepicker标签的()属性用来指定该日历能显示星期数。
A.  displayFormat
B.  endDate
C.  formatLength
D.  displayWeeks
4. 以下对checkboxlist标签描述正确的是()。
A. 其list属性指定要循环的集合
B. 该标签使用集合生成一组复选框
C. Listkey指定集合元素中的某个属性作为复选框的文本
D. listvalue指定集合元素中的某个属性作为复选框的value
5. 以下对tree 和treenode标签描述错误的是()。
A. 两个标签主要用来生成一个树形结构。
B. tree标签表示树根。
C. treenode标签表示树的的节点。
D. 可以通过treenode 的list属性指定一个集合并生成一组树节点。 
二、上机练习
 在本章的核心任务部分,我们使用doubleselect标签实现了一个省市级联列表框功能,现在要求把省市级联改成树形列表的形式。
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: