jsp标签编程『续』---简单开发
在jsp1.2之前如果想要对标签库进行开发,要么继承TagSupport类,要么继承BodyTagSupport类,而且必须覆写其中的doStartTag(),doAfterBody(),doEndTag()方法,而且还必须清楚这些方法的返回值类型;这样的过程太复杂了,到了JSP2.0后,简化标签的开发,专门增加了一个制作简单的标签库SimpleTagSupport类。直接覆写其中的doTag()方法即可;
SimpleTagSupport类的定义如下:
public class TagSupport extends Object implements SimpleTag
?此类实现了SimpleTag接口,SimpleTag接口如下:
public interface SimpleTag extends JspTag{ public void doTag() throws JspException,IOException; public void setParent(JspTag parent); public JspTag getParent(); public void setJspContext(JspContext pc); public void setJspBody(JspFragment jspBody);}
?SimpleTagSupport类的主要方法:
No方法类型描述1public void doTag() throws JspException,IOException普通完成具体标签功能的编写2public JspContext getJspContext()普通取得JSP上下文,主要用于输出3protected JspFragment getJspBody()普通取得JspFragment对象,主要用于迭代输出SimpleDateTag:
package com.keith.tag;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.SimpleTagSupport;public class SimpleDateTag extends SimpleTagSupport {//接受格式化数据private String format;@Overridepublic void doTag() throws JspException, IOException {//日期格式化SimpleDateFormat sdf = new SimpleDateFormat(this.format);try {//输出格式化后的日期super.getJspContext().getOut().write(sdf.format(new Date()));} catch (IOException e) {e.printStackTrace();}}public String getFormat() {return format;}public void setFormat(String format) {this.format = format;}}
?simpledatetag.tld:
<?xml version="1.0" encoding="UTF-8"?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"><tlib-version>1.0</tlib-version><short-name>simpledatetag</short-name><tag> <name>simpledate</name> <tag-class>com.keith.tag.SimpleDateTag</tag-class> <body-content>empty</body-content> <attribute> <name>format</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute></tag></taglib>
?index.jsp:
<%@ taglib prefix="simpledatetag" uri="simpledate"%> <body> <simpledatetag:simpledate format="yyyy-MM-dd HH:mm:ss.SSS"/> </body>
?测试看下结果!
要是面对迭代问题呢?在以前,是通过TagSupport类实现的迭代操作,则可以通过控制返回值的方式,让程序循环执行doAfterBody()方法,但先在通过SimpleTagSupport类实现的doTag()方法,本身没有返回值,如果想达到循环的效果,就必须通过JspFragment类完成控制。
在SimpleTagSupport类中存在一个getJspBody()方法,此方法返回的就是一个Fragment对象,利用此对象的invoke()方法即可完成标签体内容的输出;
SimpleIterateTag:
package com.keith.tag;import java.io.IOException;import java.util.Iterator;import java.util.List;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.SimpleTagSupport;public class SimpleIterateTag extends SimpleTagSupport {private String id;private String name;private String scope;@Overridepublic void doTag() throws JspException, IOException {Object value = null;// 是否是page范围if ("page".equals(this.scope)) {value = super.getJspContext().getAttribute(name,PageContext.PAGE_SCOPE);} else if ("request".equals(this.scope)) {// 是否是request范围value = super.getJspContext().getAttribute(name,PageContext.REQUEST_SCOPE);} else if ("session".equals(this.scope)) {// 是否是session范围value = super.getJspContext().getAttribute(name,PageContext.SESSION_SCOPE);} else {// 是否是application范围value = super.getJspContext().getAttribute(name,PageContext.APPLICATION_SCOPE);}// 如果是List接口的实例if (value != null && value instanceof List<?>) {Iterator<?> iter = ((List<?>) value).iterator();while (iter.hasNext()) {super.getJspContext().setAttribute(id, iter.next());super.getJspBody().invoke(null);}}}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}}
?simpleiteratetag.tld:
<?xml version="1.0" encoding="UTF-8"?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <tlib-version>1.0</tlib-version> <short-name>simpleiteratetag</short-name> <tag> <name>iterate</name> <tag-class>com.keith.tag.SimpleIterateTag</tag-class> <!-- 标签体内容, scriptless:表示标签体内容可以是文本,EL,JSP语法.不能包含JSP的脚本元素; empty:没有标签体; JSP:标签体可以包含文本,EL,或JSP标签,但是对于简单标签无效; tagdependent:表示标签体交由标签本身去解析处理,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器; --> <body-content>scriptless</body-content> <attribute> <name>id</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>scope</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag></taglib>
?web.xml:
<taglib> <taglib-uri>simpleiterate</taglib-uri> <taglib-location>/WEB-INF/simpleiteratetag.tld</taglib-location> </taglib>
?index.jsp:
<%@ taglib prefix="simpleiteratetag" uri="simpleiterate"%> <body><%List<String> all = new ArrayList<String>();all.add("Java");all.add("C");all.add("Linux");request.setAttribute("all",all); %> <simpleiteratetag:iterate name="all" scope="request" id="names"> ${names }<br /> </simpleiteratetag:iterate> </body>
访问页面进行测试!
?DynamicAttributes接口:
每一个标签都可以定义属性,当使用一个标签时,只能编写指定个数及名称属性。在JSP2.0之后专门增加了一个DynamicAttribute接口,此接口的主要功能是用于完成动态属性的设置,即用户在使用一个标签时可以根据自己的需要,任意设置多个属性。
DynamicAttributes接口的定义如下:
public interface DynamicAttribute{ public void setDynamicAttribute(String uri,String localName,Object value)throws JspException;}
?在这个接口里,只定义了一个setDynamicAttribute()方法,在此方法中秩序关心localName(表示动态设置的属性名词)和value(动态设置的属性内容)这2个参数!
下面使用动态属性完成一个动态加法操作,用户可以直接在加法的标签中设置任意多个参数,并通过标签将计算的结果输出:
DynamicAddTag:
package com.keith.tag;import java.io.IOException;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import javax.servlet.jsp.JspException;import javax.servlet.jsp.tagext.DynamicAttributes;import javax.servlet.jsp.tagext.SimpleTagSupport;public class DynamicAddTag extends SimpleTagSupport implements DynamicAttributes{//实现动态属性接口private Map<String,Float> num = new HashMap<String,Float>();@Overridepublic void doTag() throws JspException, IOException {//定义变量保存相加的结果Float sum = 0.0f;//迭代输出Iterator<Map.Entry<String,Float>> iter = this.num.entrySet().iterator();while (iter.hasNext()) {//取出每一个Map.EntryMap.Entry<String, Float> value = iter.next();//执行累加操作sum += value.getValue();}//输出计算的结果super.getJspContext().getOut().write(sum+"");}public void setDynamicAttribute(String uri, String localName, Object value)throws JspException {//取出设置的动态属性内容num.put(localName, Float.parseFloat(value.toString()));}}
?dynamicaddtag.tld:
<?xml version="1.0" encoding="UTF-8"?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <tlib-version>1.0</tlib-version><short-name>dynamicadd</short-name><tag> <name>add</name> <tag-class>com.keith.tag.DynamicAddTag</tag-class> <body-content>empty</body-content> <!-- 接受动态属性 --> <dynamic-attributes>true</dynamic-attributes></tag></taglib>
?web.xml:
<taglib> <taglib-uri>dynamicaddtest</taglib-uri> <taglib-location>/WEB-INF/dynamicaddtag.tld</taglib-location> </taglib>
?index.jsp:
<%@ taglib prefix="dynamicadd" uri="dynamicaddtest"%> <body>计算结果:<dynamicadd:add num1="11.11" num2="10.12" num3="12.1"/> </body>
?测试结果:计算结果:33.33