JavaWeb学习之JSTL自定义标签库的使用、JSTL自定义函数库(7)

一、自定义标签,步骤 * 确定需求 * <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}

 

你可能感兴趣的:(javaweb)