今天是学习自定义标签的第二天,主要是写一个自定义的循环标签。
先看效果图:
前台页面Jsp代码
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <%@taglib prefix="myout" uri="/demo" %> <html> <head> </head><%String[] array = new String[]{"one","two","three","four","five"};pageContext.setAttribute("arr", array);%> <body><h1>我的测试页面</h1><myout:Foreach items="arr" var="item">array数组里对应的英文数字:${item}<br></myout:Foreach> </body> </html>
跟第一篇一样,还是分四部分讲解:
第一部分:自定义标签文件(*tld)
具体内容:
<?xml version="1.0" encoding="utf-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"><tlib-version>1.0</tlib-version><short-name>myout</short-name><uri>/demo</uri><!-- 循环 --><tag><name>Foreach</name><tag-class>com.tag.support.TagDemo</tag-class><!-- 标签体可以用EL表达式 --><body-content>scriptless</body-content><attribute><name>items</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute><attribute><name>var</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute></tag> </taglib>
这个地方要注意一点:关于<%@taglib prefix="myout" uri="/demo" %> 是如何找到demo.tld文件的?
两种方式:
第一种方式:就如同上面这样配置,在demo.tld文件中加上<uri>/demo</uri> ,指定uri,
但是这种方式demo.tld必须放在WEB-INF下,不然容器找不到
第二种方式:在web.xml中配置,这种方式是通过显示的指定demo.tld的位置,可以不放在WEB-INF只要指向正确就好
<jsp-config><taglib><taglib-uri>/demo</taglib-uri><taglib-location>/WEB-INF/lirui.tld</taglib-location></taglib></jsp-config>
新增一种方式:其实在jsp页面引用自定义标签还可以另一种方式(指定*.tld文件所在路径),只是这种方式不灵活。
%@taglib prefix="myout" uri="/WEB-INF/demo.tld" %
第二部分:标签具体业务实现类。
自定义的类要继承(extends)SimpleTagSupport
import java.io.IOException;import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport;public class TagDemo extends SimpleTagSupport {//注意:这个属性要与tld文件中定义的属性一致,并提供get和set方法private String items;private String var;public String getItems() {return items;}public void setItems(String items) {this.items = items;}public String getVar() {return var;}public void setVar(String var) {this.var = var;}//具体业务实现类 @Overridepublic void doTag() throws JspException, IOException {//this.getJspContext()获得JspContext对象也就是前台页面的PageContext//可以看出页面输出Hello World注意是这里的write方法实现的JspContext jspContext = this.getJspContext();String[] arr = (String[])jspContext.getAttribute(items);for(String s: arr){jspContext.setAttribute(var, s);this.getJspBody().invoke(null);}} }
注意一点:this.getJspBody().invoke(null); 这行代码表示把标签体的内容的内容输入到浏览器,如果没有调用该方法,则忽略标签体
我一开始做的时候没有加这一行代码,
直接导致前台页面<myout:Foreach items="arr" var="item">array数组里对应的英文数字:${item}<br> </myout:Foreach> 标签体内同显示不出来,当时查了下资料才知道这里没有加this.getJspBody().invoke(null); 这一行代码。
扩充一下知识点:JspFragment是个抽象类,这个类代码很简单,具体如下:
import java.io.IOException; import java.io.Writer; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException;public abstract class JspFragment {public abstract void invoke(Writer paramWriter)throws JspException, IOException;public abstract JspContext getJspContext(); }
这个类的实例通过SimpleTagSupport类中的getJspBody()方法获得的。
该类实例封装了标签体的内容,主要方法就是invoke方法,该方法具体有两种用法:
第一种:this.getJspBody().invoke(null);表示输出到浏览器,这是原样输出的
第二种:当需要对标签体进行修改时,需要用到第二种,this.getJspBody().invoke(Writer out);
假设:我希望上面显示的页面效果使所有字母大写,效果如图
代码如下:
//具体业务实现类 @Overridepublic void doTag() throws JspException, IOException {JspContext jspContext = this.getJspContext();String[] arr = (String[])jspContext.getAttribute(items);for(String s: arr){jspContext.setAttribute(var, s);//定义一个缓冲区,把内容先输入到缓存区中,然后在打印到浏览器StringWriter sw = new StringWriter();this.getJspBody().invoke(sw);String str = sw.toString().toUpperCase();//打印的具体操作this.getJspContext().getOut().write(str);}}
这就是这两种方式的区别。
第三部分:Jsp页面引用自定义标签。
<%@taglib prefix="myout" uri="/demo" %>
关于引用自定义标签,上面第二部分已说的很清楚,这里就不多说了。
第四部分:关于定义uri的几种方式。
两种方式:(第一部分好像也说了,这里再重复一遍)
第一种方式:就如同上面这样配置,在demo.tld文件中加上<uri>/demo</uri> ,指定uri,
但是这种方式demo.tld必须放在WEB-INF下,不然容器找不到
第二种方式:在web.xml中配置,这种方式是通过显示的指定demo.tld的位置,可以不放在WEB-INF只要指向正确就好
<jsp-config><taglib><taglib-uri>/demo</taglib-uri><taglib-location>/WEB-INF/lirui.tld</taglib-location></taglib></jsp-config>
今天是学习Jsp自定义标签的第二天,刚开始写博客,如果有什么问题欢迎各位网友及时提出,谢谢。
技术的提高在于分享,而不是闭门造车。