• struts2常用标签详解


    博客分类:

     

    struts2框架是一个非常优秀的mvc框架,时至今日已有很多公司采用其作为表示层的控制转发工具,我非常喜欢struts2的拦截器特性和一整套的自定义标签。在这根据个人使用struts2的经验,与大家分享一些常用的struts2标签,希望对大家有所帮助。

    • 实例场景
    假设有这样一个网站:需要用户填写个人的信息,包括:编号、姓名、密码、生日、性别、城市、爱好。其中编号需要填入整数,姓名是字符串,密码在页面中必须以密码框的形式显示,生日必须是日期格式,性别单选,城市用下拉列表选择,爱好复选框可以多选。那么用户填写完信息以后,点击“提交”按钮,到下一个页面显示用户填写的信息。
    • 需求分析
    这是一个非常常见的需求,里面囊括了整形、字符串和日期类型等处理,另外用到了文本框、密码框、单选、复选和下拉列表等控件。
    如果采用servlet/jsp的开发模式是可以实现该功能的,但是很多地方可能需要一些复杂处理,比如用户点击提交到后台需要通过request.getParameter的形式把页面的字段逐个取出来解析;单选、复选和下拉列表中的数据需要使用jsp代码逐个迭代显示;如果加上表单验证的话,这又需要花费更大的精力。
    struts2提供了一整套的自定义标签解决方案,其功能在原生html标签基础上做了很大的改进:控件的name属性可以采用对象图的形式定义,点击提交按钮通过拦截器自动封装属性,这样在后台就不需要用request获取每个属性字段了;struts2对的单选、复选和下拉列表等控件进行了改进,开发人员只需要用一行代码设置集合数据和key/value即可显示出与html同样功能的组件;同时它提供了独有的错误显示标签,用于显示验证不通过的错误信息,非常方便。
    • 实例效果
    按照我的习惯,我首先把运行的效果展示出来,再根据效果分析每个功能的具体实现。
     
    【表单数据填写页面】
     

     
    【验证不通过显示的错误消息】


     
    【提交成功后的页面】


     
    • 后台java代码
    为了减少大家看代码的疲惫感,我尽量将每个类的核心内容展示出来,具体的代码实现在此就省略掉,如果需要全部代码,可在附件中下载。
     
    首先创建一个UserBean存放用户信息,这是一个javabean:
    Java代码  收藏代码
    1. public class UserBean implements Serializable{  
    2.     private static final long serialVersionUID = -5808037703808170288L;  
    3.       
    4.     private int userId;   //编号  
    5.     private String userName; //姓名  
    6.     private String password; //密码  
    7.     private Date birthday = new Date(); //生日:格式yyyy-MM-dd,默认为当前时间  
    8.     private int sex;   //性别:0男,1女  
    9.     private int[] hobby; //爱好,数组  
    10.     private int city; //所属 城市  
    11.          
    12.         getter、setter...  
    13. }  
     
    UserBean中的性别、爱好和所属城市均使用int表示,但是在页面中,需要用字符串来展示每个int对应的内容(key/value),所以需要分别创建它们对应的javabean,下面以SexBean为例,其它与此完全类似:
    Java代码  收藏代码
    1. public class CityBean implements Serializable{  
    2.     private static final long serialVersionUID = -6562852059776509594L;  
    3.       
    4.     private int cityId;  
    5.     private String cityValue;  
    6.       
    7.     public CityBean(int cityId, String cityValue) {  
    8.         super();  
    9.         this.cityId = cityId;  
    10.         this.cityValue = cityValue;  
    11.     }  
    12.   
    13.         getter、setter  
    14. }  
     
    然后编写一个TagsService,用于处理业务逻辑,供action调用:
    Java代码  收藏代码
    1. public class TagsService {  
    2.       
    3.     /** 
    4.      * Function  : 获取城市的集合 
    5.      */  
    6.     public List<CityBean> getCitys()  
    7.       
    8.     /** 
    9.      * Function  : 获取兴趣的集合 
    10.      */  
    11.     public List<HobbyBean> getHobbis()  
    12.       
    13.     /** 
    14.      * Function  : 获取性别的集合 
    15.      */  
    16.     public List<SexBean> getSexs()  
    17.       
    18.     /** 
    19.      * Function  : 获取被选中的兴趣爱好集合 
    20.      */  
    21.     public List<HobbyBean> getCheckedHobbies(int hobbies[])  
    22.       
    23.     /** 
    24.      * Function  : 获取被选择的城市集合 
    25.      */  
    26.     public CityBean getSelectedCity(int cityId)  
    27. }  
     
    最后是mvc的核心Controller-TagsAction,有经验的人看了下面代码或许会觉得有些地方不合理,因为相同功能会有多种实现,我这是做例子,随后会告诉大家哪种方式会更好。
    Java代码  收藏代码
    1. public class TagsAction extends ActionSupport {  
    2.     private static final long serialVersionUID = 4361410156958515185L;  
    3.     private TagsService tagsService = new TagsService();  
    4.       
    5.     //****formbean*****  
    6.     private List<CityBean> lstCityBean;  
    7.     private List<HobbyBean> lstHobbyBean;  
    8.     private UserBean userBean;  
    9.       
    10.     //*******action method***********  
    11.     /**  
    12.      * 进入表单填写页面  
    13.      */  
    14.     public String goIndex(){  
    15.         userBean = new UserBean();  
    16.         HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);  
    17.         request.setAttribute("lstSexBean", tagsService.getSexs());  
    18.         return SUCCESS;  
    19.     }  
    20.     /** 
    21.      * Function  : 提交表单 
    22.      */  
    23.     public String doSubmit(){  
    24.         HttpServletRequest request = (HttpServletRequest) ActionContext.getContext().get(ServletActionContext.HTTP_REQUEST);          
    25.         request.setAttribute("lstHobby", tagsService.getCheckedHobbies(userBean.getHobby()));  
    26.         request.setAttribute("cityBean", tagsService.getSelectedCity(userBean.getCity()));  
    27.         return SUCCESS;  
    28.     }  
    29.     /** 
    30.      * Function  : 验证表单数据 
    31.      */  
    32.     public void validateDoSubmit(){  
    33.         if(userBean.getCity()<1){  
    34.             this.addFieldError("userBean.city", "请选择城市!");  
    35.             return;  
    36.         }  
    37.     }  
    38.   
    39.     public List<CityBean> getLstCityBean() {  
    40.         return tagsService.getCitys();  
    41.     }  
    42.   
    43.     public List<HobbyBean> getLstHobbyBean() {  
    44.         return tagsService.getHobbis();  
    45.     }  
    46.   
    47.         gettter、setter........  
    48. }  
     
    • 表单数据填写页面代码分析
    要使用struts2标签,必须引用struts2的taglib
    Java代码  收藏代码
    1. <%@ taglib prefix="s" uri="/struts-tags"%>  
     
    【表单数据填写页面】
    Html代码  收藏代码
    1. <body>  
    2.     <h3>Debug标签</h3>  
    3.     <s:debug></s:debug>  
    4.     <hr/>  
    5.     <h3>表单标签</h3>  
    6.     <form action="<%=root%>/doSubmit.action" method="post">  
    7.         <s:fielderror cssStyle="color:red"></s:fielderror>  
    8.         <table>  
    9.             <tr>  
    10.                 <td>编号:</td>  
    11.                 <td><s:textfield name="userBean.userId"/></td>  
    12.             </tr>  
    13.             <tr>  
    14.                 <td>姓名:</td>  
    15.                 <td><s:textfield name="userBean.userName"></s:textfield></td>  
    16.             </tr>  
    17.             <tr>  
    18.                 <td>密码:</td>  
    19.                 <td><s:password name="userBean.password"></s:password></td>  
    20.             </tr>  
    21.             <tr>  
    22.                 <td>生日:</td>  
    23.                 <td>  
    24.                     <s:textfield name="userBean.birthday">  
    25.                         <s:param name="value">  
    26.                             <s:date name="userBean.birthday" format="yyyy-MM-dd hh:MM:ss" />  
    27.                         </s:param>  
    28.                     </s:textfield>  
    29.                 </td>  
    30.             </tr>  
    31.             <tr>  
    32.                 <td>性别:</td>  
    33.                 <td><s:radio name="userBean.sex" list="#request.lstSexBean" listKey="sexId" listValue="sexValue"></s:radio></td>  
    34.             </tr>  
    35.             <tr>  
    36.                 <td>城市:</td>  
    37.                 <td><s:select name="userBean.city" list="lstCityBean" listKey="cityId" listValue="cityValue" headerKey="0" headerValue="--请选择--"></s:select></td>  
    38.             </tr>  
    39.             <tr>  
    40.                 <td>爱好:</td>  
    41.                 <td><s:checkboxlist name="userBean.hobby" list="lstHobbyBean" listKey="hobbyId" listValue="hobbyValue"></s:checkboxlist></td>  
    42.             </tr>  
    43.             <tr>  
    44.                 <s:hidden></s:hidden>  
    45.                 <td><s:submit value="提交"/></td>  
    46.                 <td><s:reset value="重置"/></td>  
    47.             </tr>  
    48.         </table>  
    49.     </form>  
    50.       
    51. </body>  
     
    <s:textfield>标签:文本框标签,可填写文本内容,同时该标签含有很多有用的属性:
    readonly 只读属性
    disabled  可用/不可用属性,如果设置为不可用在提交表单的时候该文本框的值不会传到后台
    cssClass 指定css的class
    cssStyle  自定义css样式
    maxlength 文本框可输入的文字个数
    tooltip 冒泡提示
    上面只是一小部分属性,另外还有各种事件属性:


     
    <s:password>标签:密码框标签,其附带的属性与textfield相似
    <s:textarea>标签:定义多行的文本输入控件,其核心属性cols和rows分别指定文本域的宽度和高度
    <s:date>标签:时间显示标签,用于显示指定格式的时间对象,很多人不知道如何在文本框中显示指定日期格式,大家可以参考通过<s:textfield>+<s:date>的形式:
    Java代码  收藏代码
    1. <s:textfield name="userBean.birthday">  
    2.     <s:param name="value">  
    3.         <s:date name="userBean.birthday" format="yyyy-MM-dd hh:MM:ss" />  
    4.     </s:param>  
    5. </s:textfield>  
      <s:radio>标签:单选按钮,该控件依然采用key/value的形式处理数据,即key值传到后台,value值显示给用户,结合上面的例子,我们知道性别男的key=0,value="男",性别女的key=1,value="女",这就是为什么在后台将性别以SexBean这种javabean的形式来存储。开发用struts2的<s:radio>标签展示单选按钮完全是傻瓜式的操作:设置需要显示的数据集合(collection或array),设置key和value,如下面的代码:
    Html代码  收藏代码
    1. <s:radio name="userBean.sex" list="#request.lstSexBean" listKey="sexId" listValue="sexValue"></s:radio>  
      注意list就是从后台获取的集合数据,listKey的值最终会赋给name="userBean.sex",listValue用于显示给用户。
    从后台向页面传list数据有多种方式,第一种方法是通过request.setAttribut的形式:
    Java代码  收藏代码
    1. request.setAttribute("lstSexBean", tagsService.getSexs());  
      第二种更加好些,这也是个人推荐的:首先在action中定义一个集合formbean,设置formbean的get方法,然后重写get方法,返回集合数据:
    Java代码  收藏代码
    1. private List<SexBean> lstSexBean;  
    2.     public List<SexBean> getLstSexBean(){  
    3.         return tagsService.getSexs();  
    4.     }  
      其实<s:radio>最后还是转换成html的radio标签显示内容,我们可以看看通过<s:radio>转换后的代码:
    Html代码  收藏代码
    1. <input type="radio" name="userBean.sex" id="userBean_sex0" checked="checked" value="0"/><label for="userBean_sex0">男</label>  
    2. <input type="radio" name="userBean.sex" id="userBean_sex1" value="1"/><label for="userBean_sex1">女</label>  
      <s:select>标签:下拉列表,该标签的使用方法跟<s:radio>标签完全类似,另外可以通过headerKey和headerValue属性设置下拉列表默认值和显示的内容
    <s:select>转换成普通html后的代码:
    Html代码  收藏代码
    1. <select name="userBean.city" id="userBean_city">  
    2.     <option value="0"  
    3.     selected="selected"  
    4.     >--请选择--</option>  
    5.     <option value="1">北京</option>  
    6.     <option value="2">上海</option>  
    7.     <option value="3">广州</option>  
    8.     <option value="4">成都</option>  
    9.     <option value="5">深圳</option>  
    10. </select>  
      <s:checkboxlist>标签:复选标签,该标签的使用方法跟<s:radio>标签完全类似
    <s:checkboxlist>转换成普通html后的代码:
    Html代码  收藏代码
    1. <input type="checkbox" name="userBean.hobby" value="1" id="userBean.hobby-1"/>  
    2. <label for="userBean.hobby-1" class="checkboxLabel">唱歌</label>  
    3. <input type="checkbox" name="userBean.hobby" value="2" id="userBean.hobby-2"/>  
    4. <label for="userBean.hobby-2" class="checkboxLabel">跳舞</label>  
    5. <input type="checkbox" name="userBean.hobby" value="3" id="userBean.hobby-3"/>  
    6. <label for="userBean.hobby-3" class="checkboxLabel">运动</label>  
    7. <input type="checkbox" name="userBean.hobby" value="4" id="userBean.hobby-4"/>  
    8. <label for="userBean.hobby-4" class="checkboxLabel">旅游</label>  
    9. <input type="checkbox" name="userBean.hobby" value="5" id="userBean.hobby-5"/>  
    10. <label for="userBean.hobby-5" class="checkboxLabel">宅神</label>  
    11. <input type="hidden" id="__multiselect_userBean_hobby" name="__multiselect_userBean.hobby" value="" />  
      <s:hidden>标签:隐藏标签,可以设置变量值,但是不在页面显示
    <s:submit>标签:表单提交按钮
    <s:reset>标签:表单重置按钮
    <s:debug>标签:struts2独有的调试标签,在开发中使用,可以在页面看到值栈中的所有信息,方便调试。
     
    • 提交后显示的页面
    点击提交按钮后,经过后台处理,数据传到另一个jsp显示:
    Html代码  收藏代码
    1. <body>  
    2.     <table>  
    3.         <tr>  
    4.             <td>编号:</td>  
    5.             <td><s:property value="userBean.userId"></s:property></td>  
    6.         </tr>  
    7.         <tr>  
    8.             <td>姓名:</td>  
    9.             <td><s:property value="userBean.userName"></s:property></td>  
    10.         </tr>  
    11.         <tr>  
    12.             <td>密码:</td>  
    13.             <td><s:property value="userBean.password"></s:property></td>  
    14.         </tr>  
    15.         <tr>  
    16.             <td>生日:</td>  
    17.             <td><s:date name="userBean.birthday" format="yyyy-MM-dd hh:MM:ss" /></td>  
    18.         </tr>  
    19.         <tr>  
    20.             <td>性别:</td>  
    21.             <td>  
    22.                 <s:if test="userBean.sex==0">  
    23.                     男  
    24.                 </s:if>  
    25.                 <s:else>  
    26.                     女  
    27.                 </s:else>  
    28.             </td>  
    29.         </tr>  
    30.         <tr>  
    31.             <td>城市:</td>  
    32.             <td>  
    33.                 <s:property value="#request.cityBean.cityValue"/>  
    34.             </td>  
    35.         </tr>  
    36.         <tr>  
    37.             <td>爱好:</td>  
    38.             <td>  
    39.             <s:if test="#request.lstHobby!=null">  
    40.                 <s:iterator value="#request.lstHobby" var="hobby" status="index" begin="0" end="#request.lstHobby.length-1">  
    41.                     第[<s:property value="%{#attr.index.index+1}"/>]条爱好:<s:property value="%{#attr.hobby.hobbyValue}"/><br/>  
    42.                 </s:iterator>  
    43.             </s:if>  
    44.             </td>  
    45.         </tr>  
    46.     </table>  
    47. </body>  
      <s:property>标签:用于显示变量值的标签,没有什么可说的
    <s:if><s:elseif><s:else>标签:这三个标签结合使用就能实现java的if...elseif...else的逻辑操作,标签中的test属性用于分之条件判断。
    <s:iterator>标签:迭代标签,这个标签的功能类似于java的for循环操作,value属性装的是集合对象,var属性是集合中的某一对象,status表示迭代的次数,begin和end表示循环开始位置和结束位置。最后看上面例子的代码:
    Html代码  收藏代码
    1. <s:iterator value="#request.lstHobby" var="hobby" status="index" begin="0" end="#request.lstHobby.length-1">  
    2. <span style="white-space: pre;">    </span>第[<s:property value="%{#attr.index.index+1}"/>]条爱好:<s:property value="%{#attr.hobby.hobbyValue}"/><br/>  
    3. </s:iterator>  
     
    • OGNL简介
    OGNL是一个功能强大的EL,通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能,它使用相同的表达式去存取对象的属性。

    之所以命名为OGNL,就是因为它处理对象很给力,struts能够将对象层层解析,把各个对象的关系以图的样式展示出来。比如userBean.userId,之所以能找到这个对象,就是因为OGNL会先找userBean对象,然后再找userBean对象里的userId属性。假设UserBean这个类还包含了名为Role的javabean的实例,Role里面包含字段roleName,我们要找到roleName就可以直接写<s:property value="user.role.roleName">,OGNL通过对象逐级导航找到子对象。

  • 相关阅读:
    第13周学习进度情况
    【Android进阶】获取Android软件的版本信息
    【Android进阶】Android程序与JavaScript之间的简单调用
    字符串长度
    约瑟夫问题
    输入n个数和输出调整后的n个数
    输入三个整数,按由小到大的顺序输出
    学校oj平台上不去
    输入10个整数
    输入三个字符串,按由小到大的顺序输出
  • 原文地址:https://www.cnblogs.com/pangting/p/6912444.html
Copyright © 2020-2023  润新知