一、自定义标签,步骤 * 确定需求 * <my:date /> 输出当前系统的时间 yyyy-MM-dd hh:mm:ss:SSS * 编写Java类 新建包名:com.yxl.tag,新建类MyDateTag,实现SimpleTag接口 * 只要与此接口有关的实现类,javax.servlet.jsp.tagext.JspTag * 需要实现具体的接口 * javax.servlet.jsp.tagext.SimpleTag,简单标签,JSP2.0**,选择这个 * javax.servlet.jsp.tagext.Tag,经典标签 package com.yxl.tag; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class MyDateTag implements SimpleTag { public MyDateTag(){ System.out.println("默认构造"); } private PageContext pageContext; /** * 1、被调用的方法,tomcat调用 */ public void setJspContext(JspContext pc) { // System.out.println(pc); // System.out.println("setJspContext"); this.pageContext = (PageContext) pc; } /** * 2、tomcat调用 * 建议,在doTage方法中完成整个tag的功能 * 需要再doTage方法之前,完成准备工作 */ public void doTag() throws JspException, IOException { // System.out.println("doTag"); //输出当前系统的时间 yyyy-MM-dd hh:mm:ss:SSS SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS"); String date = format.format(new Date()); //将获得的时间输出到浏览器 this.pageContext.getOut().print(date); } @Override public JspTag getParent() { // TODO Auto-generated method stub return null; } @Override public void setJspBody(JspFragment arg0) { // TODO Auto-generated method stub } @Override public void setParent(JspTag arg0) { // TODO Auto-generated method stub } } * 编写tld文件 在WEB-INF下新建文件夹tld,在tld文件夹下新建mytag.tld * tld文件是xml文档 * 扩展名为*.tld * 位置:必须放置到WEB-INF目录下 * 内容: <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> <!-- 建议引入当前便签库是,使用的简写 @taglib prefix="my" --> <short-name>my</short-name> <!-- 为当前标签库配置文件,起一个名称 * 内容:自定义,全球唯一 --> <uri>http://www.yxl.cn/jsp/mytag</uri> <!-- <my:date / > 注册标签 --> <tag> <!-- 确定标签名称 --> <name>date</name> <!-- 确定实现类 --> <tag-class>com.yxl.tag.MyDateTag</tag-class> <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 --> <body-content>empty</body-content> </tag> </taglib> * 在JSP页面引入 * <%@ taglib uri="http://www.yxl.cn/jsp/mytag" prefix="my"%> * 测试 * <my:date /> 二、案例 * 需求:<my:maxVal num1="12" num2="13" /> package com.yxl.tag; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class MyMaxValueTag implements SimpleTag { public MyMaxValueTag() { System.out.println("默认构造"); } private PageContext pageContext; private Integer num1; private Integer num2; // num1 public void setNum1(Integer num) { this.num1 = num; } public void setNum2(Integer num) { this.num2 = num; } /** * 1、被调用的方法,tomcat调用 */ public void setJspContext(JspContext pc) { // System.out.println(pc); // System.out.println("setJspContext"); this.pageContext = (PageContext) pc; } /** * 2、tomcat调用 建议,在doTage方法中完成整个tag的功能 需要再doTage方法之前,完成准备工作 */ public void doTag() throws JspException, IOException { System.out.println(this.num1); System.out.println(this.num2); // 判断两个数据的大小,然后输出 if (this.num1 > this.num2) { this.pageContext.getOut().print(num1 + "大于" + num2); } else if (this.num1 < this.num2){ this.pageContext.getOut().print(num1 + "小于" + num2); } else{ this.pageContext.getOut().print(num1 + "等于" + num2); } } @Override public JspTag getParent() { // TODO Auto-generated method stub return null; } @Override public void setJspBody(JspFragment arg0) { // TODO Auto-generated method stub } @Override public void setParent(JspTag arg0) { // TODO Auto-generated method stub } } <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> <!-- 建议引入当前便签库是,使用的简写 @taglib prefix="my" --> <short-name>my</short-name> <!-- 为当前标签库配置文件,起一个名称 * 内容:自定义,全球唯一 --> <uri>http://www.yxl.cn/jsp/mytag</uri> <!-- <my:date / > 注册标签 --> <tag> <!-- 确定标签名称 --> <name>date</name> <!-- 确定实现类 --> <tag-class>com.yxl.tag.MyDateTag</tag-class> <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 --> <body-content>empty</body-content> </tag> <!-- <my:maxValue / > 注册标签 --> <tag> <!-- 确定标签名称 --> <name>maxValue</name> <!-- 确定实现类 --> <tag-class>com.yxl.tag.MyMaxValueTag</tag-class> <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 --> <body-content>empty</body-content> <!-- 确定当前标签使用了哪些属性 --> <attribute> <!-- 设置属性名称 --> <name>num1</name> <!-- 设置属性是否必须 * true/false * yes/no --> <required>true</required> <!-- rtexprvalue 运行时表达式的值 * runtime expression value --> <rtexprvalue>true</rtexprvalue> <!-- 确定标签类型 --> <type>java.lang.Integer</type> </attribute> <attribute> <!-- 设置属性名称 --> <name>num2</name> <!-- 设置属性是否必须 * true/false * yes/no --> <required>true</required> <!-- rtexprvalue 运行时表达式的值 * runtime expression value --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib> * 需求:<my:toUpperCase>xxYYdfsdDFwerd</my:toUpperCase> 标签体 package com.yxl.tag; import java.io.IOException; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class MyToUpperCaseTag implements SimpleTag { public MyToUpperCaseTag() { System.out.println("默认构造"); } private PageContext pageContext; private JspFragment jspBody; /** * 1、被调用的方法,tomcat调用 */ public void setJspContext(JspContext pc) { this.pageContext = (PageContext) pc; } public void setJspBody(JspFragment jspBody){ this.jspBody = jspBody; } /** * 2、tomcat调用 建议,在doTage方法中完成整个tag的功能 需要再doTage方法之前,完成准备工作 */ public void doTag() throws JspException, IOException { StringWriter stringWriter = new StringWriter(); this.jspBody.invoke(stringWriter); String data = stringWriter.toString(); this.pageContext.getOut().print(data.toUpperCase()); } @Override public JspTag getParent() { // TODO Auto-generated method stub return null; } @Override public void setParent(JspTag arg0) { // TODO Auto-generated method stub } } <!-- <my:toUpperCase / > 转换为大写 --> <tag> <!-- 确定标签名称 --> <name>toUpperCase</name> <!-- 确定实现类 --> <tag-class>com.yxl.tag.MyToUpperCaseTag</tag-class> <!-- 格式化当前标签的body内容 * empty:当前标签没有标签体 --> <!-- JSP:支持JSP所有的语法,在Tag中使用 scriptless:对于JSP页面的脚本不支持 tagdependent:标签体不做处理,原样输出 --> <body-content>scriptless</body-content> </tag> <my:toUpperCase>abcd</my:toUpperCase> * 需求:循环 使用extends SimpleTagSupport这种方式实现标签类,SimpleTagSupport已经实现了SimpleTag接口 三种循环遍历 <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> <!-- 建议引入当前便签库是,使用的简写 @taglib prefix="my" --> <short-name>my</short-name> <!-- 为当前标签库配置文件,起一个名称 * 内容:自定义,全球唯一 --> <uri>http://www.yxl.cn/jsp/mytag</uri> <!-- <my:myeach start="0" end="9" step="1" var="ss"> ${ss} ** <br/> </my:myeach> --> <tag> <name>myeach</name> <tag-class>com.yxl.tag.MyEachTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>start</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>end</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>step</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>var</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <!-- <my:myList items="${listObj}" var="yyyyy"> ${yyyyy} ## <br/> </my:myList> --> <tag> <name>myList</name> <tag-class>com.yxl.tag.MyListTag</tag-class> <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> <tag> <name>forEach</name> <tag-class>com.yxl.tag.ForEachTag</tag-class> <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> package com.yxl.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class MyEachTag extends SimpleTagSupport{ /* * <my:myeach start="0" end="9" step="1" var="ss"> ${ss} ** <br/> </my:myeach> */ private Integer start; private Integer end; private Integer step; private String var; public void setStart(Integer start) { this.start = start; } public void setEnd(Integer end) { this.end = end; } public void setStep(Integer step) { this.step = step; } public void setVar(String var) { this.var = var; } public void doTag() throws JspException, IOException { //完成功能:将获得的变量信息,输出到浏览器 for(int i = start ; i <= end ; i +=step){
//从父类中,获得pagecontext对象 this.getJspContext().setAttribute(var, i); //将el表达式的结果发送到浏览器 // * el表达式的位置 // * 如何发送 this.getJspBody().invoke(null); //this.getJspBody().invoke(this.getJspContext().getOut()); } } } package com.yxl.tag; import java.io.IOException; import java.util.Iterator; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class MyListTag extends SimpleTagSupport { /* <my:myList items="${listObj}" var="yyyyy"> ${yyyyy} ## <br/> </my:myList> */ private List items; private String var; public void setItems(List items) { this.items = items; } public void setVar(String var) { this.var = var; } @Override public void doTag() throws JspException, IOException { //完成功能:将获得的list信息遍历输出到浏览器 Iterator it = items.iterator(); while(it.hasNext()){ Object str = it.next(); //将结果放置到作用域 this.getJspContext().setAttribute(var, str); //将el表达式的结果数据到浏览器 this.getJspBody().invoke(null); } } } package com.yxl.tag; import java.io.IOException; import java.util.Arrays; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ForEachTag extends SimpleTagSupport { /* <my:myList items="${listObj}" var="yyyyy"> ${yyyyy} ## <br/> </my:myList> */ private Iterator<Object> items; private String var; public void setItems(Object items) { //list if(items instanceof List){ this.items = ((List)items).iterator(); } //map if(items instanceof Map){ this.items = ((Map)items).entrySet().iterator(); } //object[] if(items instanceof Object[]){ this.items = Arrays.asList((Object[])items).iterator(); } } public void setVar(String var) { this.var = var; } @Override public void doTag() throws JspException, IOException { //完成功能:将获得的list信息遍历输出到浏览器 while(items.hasNext()){ Object str = items.next(); //将结果放置到作用域 this.getJspContext().setAttribute(var, str); //将el表达式的结果数据到浏览器 this.getJspBody().invoke(null); } } } <my:myeach start="0" end="9" step="1" var="eeee"> ${eeee} ** <br/> </my:myeach> <% List<String> list = new ArrayList<String>(); list.add("abc"); list.add("123"); list.add("wasd"); pageContext.setAttribute("listObj",list); %> myList<br/> <my:myList items="${listObj}" var="yyyyy"> ${yyyyy} ## <br/> </my:myList> <my:forEach items="${listObj}" var="mm"> ${mm} <br/> </my:forEach> <hr/> <% Map<String,String> map = new HashMap<String,String>(); map.put("11111","11111"); map.put("22222","222222"); map.put("33333","33333"); pageContext.setAttribute("mapObj",map); %> 遍历Map<br/> <my:forEach items="${mapObj}" var="map"> ${map.key} ---- ${map.value} <br/> </my:forEach> 三、自定义函数 * 创建类,但方法必须是静态的 package com.yxl.domain; public class Calculator { private String firstNum; private String operator; private String secondNum; private String result; public String getFirstNum() { return firstNum; } public void setFirstNum(String firstNum) { this.firstNum = firstNum; } public String getOperator() { return operator; } public void setOperator(String operator) { this.operator = operator; } public String getSecondNum() { return secondNum; } public void setSecondNum(String secondNum) { this.secondNum = secondNum; } public String getResult() { return result; } public void setResult(String result) { this.result = result; } public Calculator() { } //计算方法 public static void calculator(Calculator cal){ //通过运算符,将firstNum和secondNum处理的结果,存放到result double first = Double.valueOf(cal.firstNum); double second = Double.valueOf(cal.secondNum); char ope = cal.operator.charAt(0); switch (ope) { case '+': cal.result = String.valueOf(first + second); break; case '-': cal.result = String.valueOf(first - second); break; case '*': cal.result = String.valueOf(first * second); break; case '/': cal.result = String.valueOf(first / second); break; default: throw new RuntimeException("非法操作符"); } } } * 书写配置文件tld 新建myFun.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>myfn</short-name> <uri>http://www.yxl.cn/mytag/functions</uri> <!-- 确定当前函数 myfn:calculator(cal) --> <function> <name>calculator</name> <function-class>com.yxl.domain.Calculator</function-class> <!-- 当前使用函数的声明 public static void calculator(Calculator cal) --> <function-signature>void calculator(com.yxl.domain.Calculator)</function-signature> </function> </taglib> * 引用 * <%@ taglib uri="http://www.yxl.cn/mytag/functions" prefix="myFn" %> * 测试 <jsp:useBean id="cal" class="com.yxl.domain.Calculator"></jsp:useBean> <jsp:setProperty property="firstNum" value="1" name="cal"/> <jsp:setProperty property="operator" value="+" name="cal"/> <jsp:setProperty property="secondNum" value="4" name="cal"/> ${myFn:calculator(cal)} ${cal.result} 四、总结 * 共同点: * 需要引入 * <%@ taglib uri="http://www.yxl.cn/mytag/myeach" prefix="my" %> * 都需要配置tld文件 * 区别: * 自定义标签 * 创建一个类,完成一个功能或一组功能。 * 可以选择el表达式 * 自定义函数 * 创建一个静态方法,完成一个操作。 * 必须与EL表达式结合使用 ${fn:xxxx}