标签执行过程
前提:tomcat服务器启动时,加载到每个web应用,加载每个web应用的WEB-INF目录下的所有文件。如web.xml和tld文件等。
1)浏览器访问带有标签的jsp页面。
2)tomcat服务器把jsp文件翻译成java源文件,然后编译成class二进制文件,然后构造类对象,然后调用_jspService()方法。
3)检查jsp文件的taglib指令,判断是否存在一个uri为http://xxxx的tld文件,如果没有则报错,如果有读取tld文件。
4)当读到jsp文件中的标签时,到tld文件中查询是否存在name对应的标签
5)找到标签则读<tag-class>中类,并构造对象,然后调用对应类中的方法。
自定义标签步骤
以自定义choose-when-otherwise为列
1)创建每个标签对应的java类,java类继承于SimpleTagSupport
choose类
1 public class Choose extends SimpleTagSupport { 2 //设置flag来存储when--text的判断条件 3 private boolean flag; 4 5 public boolean isFlag() { 6 return flag; 7 } 8 9 public void setFlag(boolean flag) { 10 this.flag = flag; 11 } 12 13 @Override 14 public void doTag() throws JspException, IOException { 15 this.getJspBody().invoke(null); 16 } 17 }
when类
1 public class When extends SimpleTagSupport { 2 //设置属性 3 private boolean test; 4 5 public void setTest(boolean test) { 6 this.test = test; 7 } 8 @Override 9 public void doTag() throws JspException, IOException { 10 if (test) { 11 this.getJspBody().invoke(null); 12 } 13 14 Choose parent = (Choose) this.getParent(); 15 parent.setFlag(test); 16 } 17 }
otherwise类
1 public class OtherWise extends SimpleTagSupport { 2 @Override 3 public void doTag() throws JspException, IOException { 4 Choose parent = (Choose)this.getParent(); 5 boolean test = parent.isFlag(); 6 if (!test) { 7 this.getJspBody().invoke(null); 8 } 9 } 10 }
2)在WEB-INF目录下创建tld文件,文件内容如下:
nick.tld
1 <?xml version="1.0" encoding="UTF-8" ?> 2 3 <taglib xmlns="http://java.sun.com/xml/ns/j2ee" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 5 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 6 version="2.0"> 7 8 <description>nick library</description> 9 <display-name>nick core</display-name> 10 <tlib-version>1.1</tlib-version> 11 <short-name>nick</short-name> 12 <uri>http://nick.com</uri> 13 14 <tag> 15 <name>choose</name> 16 <tag-class>com.nick.taglib.Choose</tag-class> 17 <body-content>scriptless</body-content> 18 </tag> 19 <tag> 20 <name>when</name> 21 <tag-class>com.nick.taglib.When</tag-class> 22 <body-content>scriptless</body-content> 23 <attribute> 24 <name>test</name> 25 <required>true</required> 26 <rtexprvalue>true</rtexprvalue> //是否支持EL表达式 27 </attribute> 28 </tag> 29 <tag> 30 <name>otherwise</name> 31 <tag-class>com.nick.taglib.OtherWise</tag-class> 32 <body-content>scriptless</body-content> 33 34 </tag> 35 </taglib>
3)jsp页面中调用
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@ taglib uri="http://nick.com" prefix="nick" %> //导入自定义的标签 4 <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> 5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 6 <html> 7 <head> 8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 9 <title>Insert title here</title> 10 </head> 11 <body> 12 <c:set var="score" value="60"></c:set> 13 <nick:choose> 14 <nick:when test="${score>90 }"> 15 优秀 16 </nick:when> 17 <nick:when test="${score<=90 && score>60}"> 18 及格 19 </nick:when> 20 <nick:otherwise> 21 无药可救 22 </nick:otherwise> 23 </nick:choose> 24 </body> 25 </html>
4)SimpleTagSupport类生命周期
simleTagSupport类创建对象时按照以下顺序进行方法的调用:
<1>void setJspContext(JspContest pc) --设置pageContext对象,传入pageContext(一定调用)
通过getJspContext()方法得到pageContext对象。
<2>void setParent(JspTag parent)--设置父标签对象,传入父标签对象,如果没有父标签不会调用此方法。
通过getParent()方法得到父标签对象。
<3>void setXXX(值)--设置标签中的属性值
<4>void setJspBody(JspFragment jspBody)--设置标签体内容。标签体内容封装在JspFragment对象中,然后传入方法中。如果没有标签体内容不会调用此方法。
通过getJspBody()方法得到标签体的内容。
<5>void doTag()--执行标签时调用的方法。(一定调用)