自定义Button功能描述:
<tangs:button items="apple,orange,banana"/>
解析后为:
<input type="button" name="apple" value="apple" />
<input type="button" name="orange" value="orange" />
<input type="button" name="banana" value="banana" />
文件配置:
tangs.tld
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>2.2.3</tlib-version> <jsp-version>1.2</jsp-version> <short-name>tangs</short-name> <uri>/tangs</uri> <display-name>"Tangs Tags"</display-name> <tag> <name>button</name> <tag-class>com.gq.tag.button.ButtonTag</tag-class> <body-content>empty</body-content> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>这里要注意的是:<rtexpvalue>true</rtexpvalue> 时候,可以使用 JSP 表达式
rtexprvalue的全称是 Run-time Expression Value, 它用于表示是否可以使用JSP表达式.
当在<attribute>标签里指定<rtexprvalue>true</rtexprvalue>时, 表示该自定义标签的某属性的值可以直接指定或者通过动态计算指定, example as follow:
<sql:query var="result" >
select * from mytable order by nameid
</sql:query>
<%request.setAttribute("nameid", "2"); %>
<myTag:cupSize cupSize="1" cupSizes="${result}"></myTag:cupSize>
<myTag:cupSize cupSize="${nameid}" cupSizes="${result}"></myTag:cupSize>
当在<attribute>标签里指定<rtexprvalue>false</rtexprvalue>时, 表示该自定义标签的某属性的值只能直接指定, example as follow:
<myTag:cupSize cupSize="1" cupSizes="${result}"></myTag:cupSize>
_________________________________________________________________________
ButtonTag.java
/** *创建日期 :2011-11-16 *创建用户 :GongQiang *变更情况 : *文档位置 $Archive:test_struct2/com.gq.tag.button/ButtonTag.java$ *最后变更 $Author: $ *变更日期 $Date: $ *当前版本 $Revision: $ * *Copyright (c) 2004 Sino-Japanese Engineering Corp, Inc. All Rights Reserved. */ package com.gq.tag.button; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.components.Component; import org.apache.struts2.views.jsp.ComponentTagSupport; import com.opensymphony.xwork2.util.ValueStack; public class ButtonTag extends ComponentTagSupport { private static final long serialVersionUID = 1L; private String items; public String getItems() { return items; } public void setItems(String items) { this.items = items; } /** * getBean 在类ComponentTagSupport中为抽象,子类必须实现 */ @Override public Component getBean(ValueStack valueStack, HttpServletRequest request, HttpServletResponse response) { return new ButtonService( valueStack ); } @Override protected void populateParams() { super.populateParams(); ButtonService buttonService = (ButtonService) getComponent(); buttonService.setItems( getItems() ); } }
_________________________________________________________________________
ButtonService.java
/** *创建日期 :2011-11-16 *创建用户 :GongQiang *变更情况 : *文档位置 $Archive:test_struct2/com.gq.tag.button/ButtonService.java$ *最后变更 $Author: $ *变更日期 $Date: $ *当前版本 $Revision: $ * *Copyright (c) 2004 Sino-Japanese Engineering Corp, Inc. All Rights Reserved. */ package com.gq.tag.button; import java.io.IOException; import java.io.Writer; import org.apache.struts2.components.Component; import com.opensymphony.xwork2.util.ValueStack; public class ButtonService extends Component { private String items; public String getItems() { return items; } public void setItems(String items) { this.items = items; } /** * Component 没有默认构造器,子类必须指明构造器 * * @param valueStack */ public ButtonService(ValueStack valueStack) { super(valueStack); } @Override public boolean start(Writer writer) { String[] itemValues = getItemValues(); //如下操作,仅仅显示出itemValues 的button StringBuilder sb = new StringBuilder(); for( String value : itemValues ){ sb.append( "<input type=\"button\" name=\"" + value + "\" value=\"" + value + "\">" ); } try { writer.write( sb.toString() ); } catch (IOException e) { throw new RuntimeException( "Construct <tangs:button /> error" ); } return super.start(writer); } private String[] getItemValues( ){ if( items == null || items.trim().equals( "" ) ){ return new String[]{}; } // 直接给属性items 赋值, <tangs:button items="apple,orange,banana"/> if( items.contains( "," ) ){ //假设必须是多个 return items.split( "," ); } // 通过JSP运行获取值,<tangs:button items="fruits"/> else{ return (String[])this.getStack().findValue( items ); //这样写,只支持struts2 的ongl语法 } } }
通过如上三个文件,tangs.tld、ButtonTag.java 和 ButtonService.java 的定义 <tangs:button />自定义标签已经完成,下面演示使用:
struts.xml 配置文件中添加 ButtonTag:
<!-- 演示标签 --> <package name="tag" extends="struts-default" namespace="/tag"> <action name="Tag" class="com.gq.action.TagTestAction"> <result name="success">/tagTest/tags.jsp</result> <interceptor-ref name="defaultStack"/> </action> <action name="ButtonTag" class="com.gq.tag.button.ButtonActionTest"> <result name="success">/tagTest/buttonTag.jsp</result> <interceptor-ref name="defaultStack"/> </action> </package>
/** *创建日期 :2011-11-16 *创建用户 :GongQiang *变更情况 : *文档位置 $Archive:test_struct2/com.gq.tag.button/ButtonActionTest.java$ *最后变更 $Author: $ *变更日期 $Date: $ *当前版本 $Revision: $ * *Copyright (c) 2004 Sino-Japanese Engineering Corp, Inc. All Rights Reserved. */ package com.gq.tag.button; import com.opensymphony.xwork2.ActionSupport; public class ButtonActionTest extends ActionSupport { private static final long serialVersionUID = 1L; public String[] getFruits(){ return new String[]{ "apple", "apple", "apple"}; } @Override public String execute() throws Exception { return SUCCESS; } }
<%@ page language="java" pageEncoding="UTF-8"%> <%@taglib prefix="s" uri="/struts-tags" %> <%@taglib prefix="tangs" uri="/tangs" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'buttonTag.jsp' starting page</title> </head> <body> 页面直接给定属性<br/> <tangs:button items="apple,orange,banana"/> <br/> <br/> 运行时获取值<br/> <tangs:button items="fruits"/> </body> </html>