Struts2官方教程:表单标签 Form Tags

介绍

本篇教程中我们回探索Struts2其它表单的控制。在先前解释了如何使用Struts2表单(《处理表单》,《表单验证》,《消息资源文件》)的教程里,我们讲解了如何使用Struts2的head、form、textfield控制以及键属性。本篇教程将会探究使用Struts2的select,radio,checkbox以及checkboxlist表单控制。

示例应用

支持本篇教程的示例应用展示如何使用Struts2表单标签,让用户可以编辑个人信息。能够被编辑的个人信息封装在Person类的一个对象实例中。一个Person对象有这些信息:名字,姓氏,最爱的运动,性别,居住国,是否年过21,以及拥有的车模(what?)
为了让用户可以编辑保存再Person对象中的个人信息,需要创建这样的表单:(截图略)
表单允许用户做一些改变。在提交表单后,Struts2框架会更新Person对象的状态信息。
通过使用Struts2的textfield标签,名字和姓氏在表单上展示,这在前面的教程中已经讲解过了。

Struts2的select标签

用户可以再几个选项中选择自己最喜爱的运动。示例教程使用Struts2的select标签来提供select框的列表。

Struts2的select标签代码

<s:select key="personBean.sport" list="sports" />

在这些表单标签里,我们使用已经在《消息资源文件》教程中讨论过的键属性。键属性被Struts2框架使用,来决定其它属性的取值(例如标签和标签的值)。我们也使用一个关联到EditAction类的属性文件,来基于键属性取值提供标签的取值(回头读读《消息资源文件》教程来复习属性文件的使用)。

注意,Struts2表单标签有许多的属性,大部分镜像于HTML标签关联的属性。可以阅读Struts2文档来直销所有的Struts2表单标签属性。

Struts2中select标签里list属性的取值被框架使用来决定调用动作类的哪个方法来创建选项取值。在我们的示例应用里,“sports”这个list属性的取值是框架调用EditAction类的getSports方法的结果。这个方法返回了一个包含“足球”、“棒球”以及“篮球”的字符串数组。这些取值被用来创建在select标签中的选项标签。
Struts2框架决定那个选项是被默认选择的,通过使用键属性的取值来调用一个方法作用于personBean实例。由于键属性的取值是“personBean.sport”,框架调用了personBean实例的“getSport”方法。如果方法返回的取值匹配了选项取值中的一个,那么选项会被标记为“已选择”。
这里是使用了上述Struts2的select标签的HTML结果。

由Struts2 select标签创建的HTML代码

<tr>
    <td class="tdLabel">
        <label for="save_personBean_sport" class="label">Favorite sport:</label>
    </td>
    <td>
        <select name="personBean.sport" id="save_personBean_sport">
            <option value="football">football</option>
            <option value="baseball">baseball</option>
            <option value="basketball" selected="selected">basketball</option>
        </select>
    </td>
</tr>

注意,当使用Struts2 select标签时,Struts2框架创建的表的格式。在style sheets中定义的CSS类被Struts2 的s:head标签所引入。Struts2的s:head标签被放在edit.jsp的head区之中。
由于personBeans的getSport方法返回了“篮球”,所以“篮球”这个选项取值被标记为已选择。

血泪史

原官方教程在这里(以及前面译者偷懒没译的两篇教程)都没有提到:除了要在页面上添加select标签行,还需要将动作类实现Preparable接口、同时在动作类中重写prapare方法,对select标签中使用的list进行初始化,方能正确地在所需页面上显示。即:

package com.myweb.struts2;
import org.apache.struts.register.model.Person;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;//引入Prepareble
import java.util.HashMap;

public class Register extends ActionSupport implements Preparable{//实现接口
    private static final long serialVersionUID=1L;
    private Person personBean;

    HashMap<Integer,String> sports=new HashMap<Integer,String>();

    @Override public void prepare() {//重写prepare方法
        sports.put(1, "足球");
        sports.put(2, "棒球");
        sports.put(3, "篮球");
    }

同时还有另一件需要注意的事:不能直接访问页面,必须通过动作来访问。例如直接访问Register动作对应的Register.jsp,页面会返回500错误,提示tag ‘select’, field ‘list’, name ‘personBean.sport’: The requested list key ‘sports’ could not be resolved as a collection/array/map/enumeration/iterator type;而访问Register.action就不会。
这是因为:我们需要实现动作类的Preparable接口,并且对prepare方法进行重写、加入list对象的初始化数据加入工作;完成这两件之后,访问动作类才会让页面在渲染前先准备好list供页面调用;否则list是空的,便会出现上述的错误。
sports在示例代码中使用了HashMap;听说也可以使用ArrayList。

Struts 2 Radio标签

Struts2的Radio标签——正如它标准HTML对应的那货——被用来显示两个或多个选项,其中只有一个可以被用户所选择。这里是来自示例应用中的Struts2radio按钮。

Struts 2 Radio Tag

<s:radio key="personBean.gender" list="genders" />

再次强调:键属性的取值决定了标签及其取值。标签的文本从EditAction.properties文件中导出(personBean.gender键)。就像Struts2的select标签,Struts2 Radio标签的list属性让框架调用EditAction类的getGenders方法。被返回的字符串数组被用来创建个性化按钮。

Struts2 Radio标签所创建的HTML代码

<tr>
    <td class="tdLabel">
        <label for="save_personBean_gender" class="label">Gender:</label>
    </td>
    <td>
        <input type="radio" name="personBean.gender" id="save_personBean_gendermale" value="male"/>
        <label for="save_personBean_gendermale">male</label>

        <input type="radio" name="personBean.gender" id="save_personBean_genderfemale" value="female"/>
        <label for="save_personBean_genderfemale">female</label>

        <input type="radio" name="personBean.gender" id="save_personBean_gendernot sure" checked="checked" value="not sure"/>
        <label for="save_personBean_gendernot sure">not sure</label>
    </td>
</tr>

就像Struts2 select标签那样,调用personBean对象的getGender方法所返回的结果,被用来决定哪个Radio按钮被预先选中。

Struts 2 Select 标签 - Object Backed

你可能需要创建一个能对用户显示自己不同于别人的取值的Struts2 select标签。在这里的示例教程中,用户的居住国用两个字母的缩写存储(例如KS),但表单的select框应当显示完整的州名(例如Kansas)。为了在Struts2中创建这样一个选择框,需要使用这样的代码:

Struts 2 Select Tag Object Backed

<s:select key="personBean.residency" list="states" listKey="stateAbbr" listValue="stateName" />

列表取值告诉框架,调用EditAction类的getStates方法。方法返回了一个state对象的ArrayList。每个state对象有一个getStateAbbr以及getStateName方法。
listKey属性告诉框架,使用调用了getStateAbbr方法返回的值,作为HTML的option标签属性的取值;调用getStateName方法返回的取值,作为显示给用户看的取值。这样以上Struts2 select标签代码的结果就是这样的HTML。

Struts2 select标签生成的HTML

<tr>
    <td class="tdLabel">
        <label for="save_personBean_residency" class="label">State resident:</label>
    </td>
    <td>
        <select name="personBean.residency" id="save_personBean_residency">
            <option value="AZ">Arizona</option>
            <option value="CA">California</option>
            <option value="FL">Florida</option>
            <option value="KS" selected="selected">Kansas</option>
            <option value="NY">New York</option>
        </select>
    </td>
</tr>

调用PersonBean对象的getResidency方法所返回的值,决定了select标签的选项中,哪个被标记为选中。在我们的示例里,因为getResidency返回了“KS”,选项标签等于“KS”的属性值被标记为选中。

Struts 2 勾选框Checkbox 标签

Struts2 checkbox标签被用来创建HTML输入类型等于checkbox的标签。键属性的取值告诉框架被调用的方法,来决定勾选框是否被选中。被调用的方法应当返回一个Boolean值(true或false)。一个true返回值将让勾选框被选中,false让勾选框不被选中。

Struts 2 勾选框标签

<s:checkbox key="personBean.over21" />

因为getOver21函数返回了true,所以勾选框被选中咯。

Struts2 勾选框标签生成的HTML

<tr>
    <td valign="top" align="right"></td>
    <td valign="top" align="left">
        <input type="checkbox" name="personBean.over21" value="true" checked="checked" id="save_personBean_over21"/>
        <input type="hidden" id="__checkbox_save_personBean_over21" name="__checkbox_personBean.over21" value="true" />
        <label for="save_personBean_over21" class="checkboxLabel">21 or older</label>
    </td>
</tr>

当勾选框未被选中、而表单被提交了,那么勾选框没有值会提交(这是HTML表单工作的方式)。因为Struts2框架需要更新personBeans的voer21实例域为false——勾选框未被选中——框架需要一个途径来决定,勾选框在表单提交后是未提交的。
如果查看Struts2 勾选框标签所生成的HTML代码,读者会看到,创建了一个关联到personBeanover21勾选框的隐藏域。当Struts2框架拦截到表单的提交,它将会使用这个隐藏表单域来检查,关联的勾选框域是否存在提交的表单数据。如果勾选框域不存在,那么Struts2 框架会指导,将personBean对象的over21示例变量更新为false。

Struts 2勾选框列表 checkboxlist 标签

Struts2框架提供了独特的,能够创建一系列相关联的勾选框的表单域控制,其中一个或多个勾选框可以被选中。在本示例应用中,Person类有一个字符串数组,用来存储被一个person所拥有的轿车模型。
使用Struts2的勾选框,我们可以创建一个勾选框系列,用户可能拥有每一个可能的轿车模型。每个在personBeans的carModels数组的字符串会决定勾选框是否选中。

Struts 2 勾选框列表Checkboxlist 标签

<s:checkboxlist key="personBean.carModels" list="carModelsAvailable" />

在勾选框列表标签中的list属性取值告诉Struts2框架,用来获得可能的轿车模型应当调用的方法。在本示例应用中,框架会调用EditAction类的getCarModelsAvailable方法。这个方法返回了一个字符串数组。对于每个数组的元素,Strus2框架创建一个勾选框(以及上文所描述的隐藏关联域)。
勾选框列表中,键属性的值告诉Struts2框架,调用personBean对象的哪个方法来确定勾选框是否被选中。在本示例应用中,框架会调用personBean对象的getCarModels方法。getCarModels方法返回一个字符串数组。对于数组,其中每个匹配一个字符串值被EditAction类的getCarModelsAvailable方法所返回的字符串值的字符串取值,对应的勾选框会被选中。

用Struts2勾选框列表创建的HTML

<tr>
    <td class="tdLabel">
        <label for="save_personBean_carModels" class="label">Car models owned:</label>
    </td>
    <td>
        <input type="checkbox" name="personBean.carModels" value="Ford" id="personBean.carModels-1" checked="checked"/>
        <label for="personBean.carModels-1" class="checkboxLabel">Ford</label>

        <input type="checkbox" name="personBean.carModels" value="Chrysler" id="personBean.carModels-2"/>
        <label for="personBean.carModels-2" class="checkboxLabel">Chrysler</label>

        <input type="checkbox" name="personBean.carModels" value="Toyota" id="personBean.carModels-3"/>
        <label for="personBean.carModels-3" class="checkboxLabel">Toyota</label>

        <input type="checkbox" name="personBean.carModels" value="Nissan" id="personBean.carModels-4" checked="checked"/>
        <label for="personBean.carModels-4" class="checkboxLabel">Nissan</label>
        <input type="hidden" id="__multiselect_save_personBean_carModels" name="__multiselect_personBean.carModels" value="" />
    </td>
</tr>

总结

还是有那么几个其它的Struts2表单控制,是咱也应当探究的。如果想继续深入,请上官网而不要指望译者的产出,谢谢。

猜你喜欢

转载自blog.csdn.net/u010930289/article/details/76862907