<%@ taglib prefix="标签前缀" uri="tld文件路径"%>
,而且调用<标签前缀 jsp标签使用名称>
。package taeyeon.com.jsp.tld; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; public class HelloTag extends TagSupport { @Override public int doStartTag() throws JspException { JspWriter writer = super.pageContext.getOut(); // 取得jsp的输出流对象 try { writer.println("<h2>Hello World!</h2>"); } catch (IOException e) { e.printStackTrace(); } return super.SKIP_BODY;//没有标签体 } }
<?xml version="1.0" encoding="ISO-8859-1"?> <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>hello</short-name><!--标签库在tld中的描述名称--> <uri>http://mycompany.com</uri><!--jsp页面中taglib标签中的uri映射路径,可本身定义。只要知足书写标准--> <tag> <name>hello</name><!--在jsp中使用的名称--> <tag-class>taeyeon.com.jsp.tld.HelloTag</tag-class><!--标签指向的操做类--> <body-content>empty</body-content><!--是否有标签体--> </tag> </taglib>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="hello" uri="/WEB-INF/tld/hello.tld" %> <html> <head> <title>第一个tld标签页面</title> </head> <body> <hello:hello/> </body> </html>
输出html
Hello World!
<!--映射tag的uri,操做tld文件--> <jsp-config> <taglib> <taglib-uri>hello_uri</taglib-uri> <taglib-location>/WEB-INF/tld/hello.tld</taglib-location> </taglib> </jsp-config>
注意:这里在web.xml文件中配置的 <jsp-config>,在web.xml2.4版本以前是能够书写的,可是在以后书写会报错,由于tld文件中新增了一个标签<uri>能够直接映射jsp页面中的引用uri,因此只要在tld文件中书写就能够了。具体在tld文本的那一个版本修改的有兴趣的能够本身查阅一下。前端
package taeyeon.com.jsp.tld; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.TagSupport; import java.io.IOException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; public class DateTag extends TagSupport { private String formateDate; public String getFormateDate() { return formateDate; } public void setFormateDate(String formateDate) { this.formateDate = formateDate; } @Override public int doStartTag() throws JspException { LocalDateTime date = LocalDateTime.now(); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(this.formateDate); try { super.pageContext.getOut().write(date.format(formatter)); } catch (IOException e) { e.printStackTrace(); } return TagSupport.SKIP_BODY; } }
<?xml version="1.0" encoding="ISO-8859-1"?> <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>myshortname</short-name> <uri>dateuri</uri> <tag> <name>date</name> <tag-class>taeyeon.com.jsp.tld.DateTag</tag-class> <body-content>empty</body-content> <attribute> <name>formateDate</name><!--属性名称--> <required>true</required><!--是否为必输项--> <rtexprvalue>true</rtexprvalue><!--是否支持表达式输出--> </attribute> </tag> </taglib>
-引用tldjava
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="date" uri="dateuri" %> <html> <head> <title>带属性的标签体</title> </head> <body> <h2><date:date formateDate="yyyy-MM-dd HH:mm:ss"/></h2> </body> </html>
2019-12-02 17:03:28
注意:这里没有用SimpleDateFormat类来格式化时期,实用为SimpleDateFormat类时非线程安全的,而在jdk1.8以后提供了新的DateTimeFormatter类,该类线程安全也是做用于日期的格式化,二者的具体不一样和使用,怎样让SimpleDateFormat变的线程安全能够参考我后面博文写的文章web
<名称: tld中name名称 属性="${}"/属性="<%= %>"/>
public class TagSupport extends Object implements IterationTag,Serializable
public interface IterationTag extends Tag { public final static int EVAL_BODY_AGAIN = 2; int doAfterBody() throws JspException;
public interface Tag extends JspTag { public final static int SKIP_BODY = 0; public final static int EVAL_BODY_INCLUDE = 1; public final static int SKIP_PAGE = 5; public final static int EVAL_PAGE = 6; void setPageContext(PageContext pc); void setParent(Tag t); Tag getParent(); int doStartTag() throws JspException; int doEndTag() throws JspException; void release(); }
NO | 常量或方法 | 类型 | 描述 |
---|---|---|---|
1 | protected PageContext pageContext | 属性 | 表示PageContext对象,能够操做四种属性范围 |
2 | public static final int SKIP_BODY | 常量 | 忽略标签体内容,将操做转交给doEndTag() |
3 | public static final int EVAL_BODY_INCLUDE | 常量 | 正常执行标签体操做,但不处理任何运算 |
4 | public final static int SKIP_PAGE | 常量 | 全部在jsp上操做都将中止,会将全部输出的内容马上显示在浏览器上 |
5 | public final static int EVAL_PAGE | 常量 | 正常执行jsp页面 |
6 | public final static int EVAL_BODY_AGAIN | 常量 | 重复执行标签内容,会再次调用doAfterBody(),直到出现SKIP_BODY为止 |
7 | public abstract int doStartTag() throws JspException | 方法 | 处理标签开始部分 |
8 | public abstract int doEndTag() throws JspException | 方法 | 处理标签结束部分 |
9 | public abstract int doAfterBody() throws JspException | 方法 | 处理标签主体部分 |
10 | public abstract void release() | 方法 | 释放标签资源 |
package taeyeon.com.jsp.tld; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; public class BodyTag extends TagSupport { private String name; private String scope; public String getScope() { return scope; } public void setScope(String scope) { this.scope = scope; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int doStartTag() throws JspException { Object value=null; if("page".equals(this.scope)){ value=super.pageContext.getAttribute(name , PageContext.PAGE_SCOPE); }else if("request".equals(this.scope)){ value=super.pageContext.getAttribute(name , PageContext.REQUEST_SCOPE); }else if("session".equals(this.scope)){ value=super.pageContext.getAttribute(name , PageContext.SESSION_SCOPE); }else if("application".equals(this.scope)){ value=super.pageContext.getAttribute(name , PageContext.APPLICATION_SCOPE); } if(value==null){ return super.SKIP_BODY; } else { return super.EVAL_BODY_INCLUDE; } } }
<?xml version="1.0" encoding="ISO-8859-1"?> <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>myshortname</short-name> <uri>bodytag</uri> <tag> <name>body</name> <tag-class>taeyeon.com.jsp.tld.BodyTag</tag-class> <body-content>JSP</body-content><!-- 执行标签体内容--> <attribute> <name>scope</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="body" uri="bodytag" %> <html> <head> <title>有标签体的标签</title> </head> <body> <%! String scope = "session";%> <% session.setAttribute("name", "Yoona"); %> <body:body name="name" scope="<%=scope%>"> <h2>session属性范围</h2> </body:body> </body> </html>
session属性范围
注意:编程
package taeyeon.com.jsp.tld; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.TagSupport; import java.util.Iterator; import java.util.List; public class IterationTag extends TagSupport { private String name; private String scope; private Iterator<?> iter; 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; } public Iterator<?> getIter() { return iter; } public void setIter(Iterator<?> iter) { this.iter = iter; } @Override public int doStartTag() throws JspException { Object value = null; if ("page".equals(this.scope)) { value = super.pageContext.getAttribute(name, PageContext.PAGE_SCOPE); } else if ("request".equals(this.scope)) { value = super.pageContext.getAttribute(name, PageContext.REQUEST_SCOPE); } else if ("session".equals(this.scope)) { value = super.pageContext.getAttribute(name, PageContext.SESSION_SCOPE); } else if ("application".equals(this.scope)) { value = super.pageContext.getAttribute(name, PageContext.APPLICATION_SCOPE); } if (value != null && value instanceof List<?>) { this.iter = ((List<?>) value).iterator(); if (iter.hasNext()) { super.pageContext.setAttribute("msg", iter.next()); return super.EVAL_BODY_INCLUDE; } else { return super.SKIP_BODY; } } else { return super.SKIP_BODY; } } @Override public int doAfterBody() throws JspException { if (iter.hasNext()) { super.pageContext.setAttribute("msg", iter.next()); return super.EVAL_BODY_AGAIN; } else { return super.SKIP_BODY; } } }
<?xml version="1.0" encoding="ISO-8859-1"?> <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>myshortname</short-name> <uri>iteratortag</uri> <tag> <name>iterator</name> <tag-class>taeyeon.com.jsp.tld.IterationTag</tag-class> <body-content>JSP</body-content> <attribute> <name>name</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>scope</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib prefix="iterator" uri="iteratortag" %> <html> <head> <title>迭代标签库</title> </head> <body> <% String name1 = "session"; List<String> list = new ArrayList<String>(); list.add("18"); list.add("yoona"); list.add("Korea"); session.setAttribute("name", list); %> <iterator:iterator name="name" scope="<%=name1%>"> <h2>${msg}</h2> </iterator:iterator> </body> </html>
18 yoona Korea
在获取属性值的时候必定要注意访问域的问题,否则有可能获取不到值。浏览器
public class BodyTagSupport extends TagSupport implements BodyTag
public interface BodyTag extends IterationTag { public final static int EVAL_BODY_TAG = 2; public final static int EVAL_BODY_BUFFERED = 2; void setBodyContent(BodyContent b); void doInitBody() throws JspException; }
NO | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public final static int EVAL_BODY_BUFFERED | 常量 | 表示标签体的内容应该被处理,全部的处理结果都将保存在BodyContent类中 |
2 | protected BodyContent bodyContent | 属性 | 存放标签体的处理结果 |
3 | public JspWriter getPreviousOut() | 方法 | 取得JspWriter的输出流对象 |
public abstract class BodyContent extends JspWriter
NO | 方法 | 类型 | 描述 |
---|---|---|---|
1 | public abstract void writeOut(Writer out) throws IOException | 方法 | 指定BodyContent内容的输出流对象,并进行内容输出 |
2 | public abstract String getString() | 将全部内容变为String类型 | |
3 | public abstract Reader getReader() | 方法 | 将内容变为Reader对象 |