Jstl自定义标签及其生命周期、属性标签、及其读取文本练习、JspFragment输出标签体(2)
2016-09-02 00:50
531 查看
什么是自定义标签?
标签处理器可以做哪些操作呢?
属性标签
输出一个文件-利用自定义标签
利用JspFragment输出标签体的自定义标签
什么是自定义标签?
SimlpeTagSuPPort类的生命周期:
1.当jsp容器遇到自定义标签时。jsp容器会调用标签处理类的默认构造方法来建立一个标签处理类的实例。必须为每个标签都创建一个新的实例。
2.实例创建后,jsp容器会调用setJspContext()方法。并以一个JspContext实例提供上下文信息。如果是一个嵌套标签,还讲调用setParent()方法。
3.然后容器会调用该标签中所定义的每个属性的set方法,这样标签处理类实例就已经初始化完成了。
4.接着就由容器调用setJspBody()方法。将该标签的主题设置为JspFragment实例。如果标签主题是空的,则将null值传到setJspBody().JspFragment实例代表标签主题片段的引用。
5.接下来,由容器调用doTag()方法标签要实现的所有逻辑、循环、主体赋值等都在该方法中发生。
6.在doTag()方法返回后,标签处理类中所有的变量都是同步的。
如何创建自定义标签?
1、写一个标签处理类,实现SimpleTag接口方法
2、建议在WEB-INF下配置文件tld文件
3、在jsp中taglib导入标签库描述文件,使用即可
HelloSimpleTag
mytld.tld
mytag.jsp
标签处理器可以做哪些操作呢?
通过jsp引擎调用,把代表jsp页面的pageContext对象传入,由于pageContext可以获取jsp页面其他的8个隐含对象,所以凡是jsp页面可以做的,标签处理器都可以做
还是上例中mytld.tld、mytag.jsp不过变化
HelloSimpleTag 做如下修改
属性标签
1.先在标签处理类中定义setter方法,建议属性都设置为String类型
2.在tld文件中来描述属性
mytld.tld
mytag.jsp
HelloSimpleTag
输出一个文件-利用自定义标签
mytld.tld
mytag.jsp
ReadFileTag
看下目录结构:
浏览器输出结果如下:
利用JspFragment输出标签体的自定义标签
它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段
WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:
getJspContext方法用于返回代表调用页面的JspContext对象.
public abstract voidinvoke(java.io.Writer out)
用于执行JspFragment对象所代表的JSP代码片段,参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
mytld.tld
mytag.jsp
ReadFileTag
带标签体的自定义标签练习
mytld.tld
Customer
PrintUpperTag
mytag.jsp
浏览器输入http://localhost:8080/day01/mytag.jsp
输出结果如下:
主要来说下
如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
在PrintUpperTag进行了如下操作:
然后在jsp页面中进行获取即可
标签处理器可以做哪些操作呢?
属性标签
输出一个文件-利用自定义标签
利用JspFragment输出标签体的自定义标签
什么是自定义标签?
SimlpeTagSuPPort类的生命周期:
1.当jsp容器遇到自定义标签时。jsp容器会调用标签处理类的默认构造方法来建立一个标签处理类的实例。必须为每个标签都创建一个新的实例。
2.实例创建后,jsp容器会调用setJspContext()方法。并以一个JspContext实例提供上下文信息。如果是一个嵌套标签,还讲调用setParent()方法。
3.然后容器会调用该标签中所定义的每个属性的set方法,这样标签处理类实例就已经初始化完成了。
4.接着就由容器调用setJspBody()方法。将该标签的主题设置为JspFragment实例。如果标签主题是空的,则将null值传到setJspBody().JspFragment实例代表标签主题片段的引用。
5.接下来,由容器调用doTag()方法标签要实现的所有逻辑、循环、主体赋值等都在该方法中发生。
6.在doTag()方法返回后,标签处理类中所有的变量都是同步的。
如何创建自定义标签?
1、写一个标签处理类,实现SimpleTag接口方法
2、建议在WEB-INF下配置文件tld文件
3、在jsp中taglib导入标签库描述文件,使用即可
HelloSimpleTag
package com.safly; import java.io.IOException; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.JspTag; import javax.servlet.jsp.tagext.SimpleTag; public class HelloSimpleTag implements SimpleTag { public void doTag() throws JspException, IOException { System.out.println("doTag"); } public JspTag getParent() { System.out.println("getParent"); return null; } public void setJspBody(JspFragment jspBody) { System.out.println("setJspBody"); } public void setJspContext(JspContext pc) { System.out.println("setJspContext"); } public void setParent(JspTag parent) { System.out.println("setParent"); } }
mytld.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"> <description>MyTag 1.0 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.0</tlib-version> <short-name>safly</short-name> <uri>http://www.safly.com/mytld/core</uri> <tag> <name>hello</name> <tag-class>com.safly.HelloSimpleTag</tag-class> <body-content>empty</body-content> </tag> </taglib>
mytag.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%@taglib uri="http://www.safly.com/mytld/core" prefix="safly"%> <html> <body> <!-- //prefix可用其他,但是<safly:hello/>相对应 --> <safly:hello/> </body> </html>
标签处理器可以做哪些操作呢?
通过jsp引擎调用,把代表jsp页面的pageContext对象传入,由于pageContext可以获取jsp页面其他的8个隐含对象,所以凡是jsp页面可以做的,标签处理器都可以做
还是上例中mytld.tld、mytag.jsp不过变化
HelloSimpleTag 做如下修改
package com.safly; import java.io.IOException; import javax.servlet.http.HttpServletRequest; 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 HelloSimpleTag implements SimpleTag { // 标签体逻辑实际编写到该方法中 public void doTag() throws JspException, IOException { System.out.println("doTag"); pageContext.getOut().println("helloworld"); HttpServletRequest request = (HttpServletRequest) pageContext .getRequest(); pageContext.getOut().print("Hello" + request.getParameter("name")); } public JspTag getParent() { System.out.println("getParent"); return null; } public void setJspBody(JspFragment jspBody) { System.out.println("setJspBody"); } private PageContext pageContext; // jsp引擎调用,把代表jsp页面的pagecontext对象传入 public void setJspContext(JspContext pc) { System.out.println("setJspContext"); System.out.println(pc instanceof PageContext); this.pageContext = (PageContext) pc; } public void setParent(JspTag parent) { System.out.println("setParent"); } }
属性标签
1.先在标签处理类中定义setter方法,建议属性都设置为String类型
2.在tld文件中来描述属性
mytld.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"> <description>MyTag 1.0 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.0</tlib-version> <short-name>safly</short-name> <uri>http://www.safly.com/mytag/core</uri> <tag> <name>hello</name> <tag-class>com.safly.HelloSimpleTag</tag-class> <body-content>empty</body-content> <attribute> <name>value</name> <required>true</required> <!-- 当前属性是否可以接受运行时表达式的动态值 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>count</name> <required>true</required> <!-- 当前属性不可以接受运行时表达式的动态值 --> <rtexprvalue>false</rtexprvalue> </attribute> </tag> </taglib>
mytag.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%@taglib uri="http://www.safly.com/mytag/core" prefix="safly"%> <html> <body> <safly:hello value="${param.name}" count="5"/> </body> </html>
HelloSimpleTag
package com.safly; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspContext; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; 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 HelloSimpleTag implements SimpleTag { //建议把所有的属性定义成String类型 private String value; private String count; public void setValue(String value) { this.value = value; } public void setCount(String count) { this.count = count; } // 标签体逻辑实际编写到该方法中 public void doTag() throws JspException, IOException { System.out.println("doTag"); JspWriter out = pageContext.getOut(); int c = 0; c = Integer.parseInt(count); for (int i = 0; i < c; i++) { out.print(i + ":" + value); out.print("<br>"); } } public JspTag getParent() { System.out.println("getParent"); return null; } public void setJspBody(JspFragment jspBody) { System.out.println("setJspBody"); } private PageContext pageContext; // jsp引擎调用,把代表jsp页面的pagecontext对象传入 public void setJspContext(JspContext pc) { System.out.println("setJspContext"); System.out.println(pc instanceof PageContext); this.pageContext = (PageContext) pc; } public void setParent(JspTag parent) { System.out.println("setParent"); } }
输出一个文件-利用自定义标签
mytld.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"> <description>MyTag 1.0 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.0</tlib-version> <short-name>safly</short-name> <uri>http://www.safly.com/mytag/core</uri> <tag> <name>readerFile</name> <tag-class>com.safly.ReadFileTag</tag-class> <body-content>empty</body-content> <attribute> <name>src</name> <required>true</required> <!-- 当前属性是否可以接受运行时表达式的动态值 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
mytag.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%@taglib uri="http://www.safly.com/mytag/core" prefix="safly"%> <html> <body> <safly:readerFile src="/WEB-INF/abc.txt"/> </body> </html>
ReadFileTag
package com.safly; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ReadFileTag extends SimpleTagSupport { private String src; public void setSrc(String src){ this.src = src; } @Override public void doTag() throws JspException, IOException { super.doTag(); PageContext pageContext = (PageContext) getJspContext(); InputStream in = pageContext.getServletContext().getResourceAsStream(src); BufferedReader reader = new BufferedReader(new InputStreamReader(in) ); String str = null; while ((str=reader.readLine())!=null) { pageContext.getOut().write(str); pageContext.getOut().write("<br>"); } } }
看下目录结构:
浏览器输出结果如下:
利用JspFragment输出标签体的自定义标签
public void setJspBody(JspFragment jspBody) { System.out.println("setJspBody"); }
它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段
WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:
getJspContext方法用于返回代表调用页面的JspContext对象.
public abstract voidinvoke(java.io.Writer out)
用于执行JspFragment对象所代表的JSP代码片段,参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象中,如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
mytld.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"> <description>MyTag 1.0 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.0</tlib-version> <short-name>safly</short-name> <uri>http://www.safly.com/mytag/core</uri> <tag> <name>testJspFragment</name> <tag-class>com.safly.ReadFileTag</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
mytag.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%@taglib uri="http://www.safly.com/mytag/core" prefix="safly"%> <html> <body> <safly:testJspFragment>HelloWorld</safly:testJspFragment> </body> </html>
ReadFileTag
package com.safly; import java.io.IOException; import java.io.StringWriter; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ReadFileTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { //自己定义的方法getJspBody JspFragment bodyContent= getJspBody(); //参数为字符流,若为null则输出getJspContext().getOut()到页面上 StringWriter sw = new StringWriter(); bodyContent.invoke(sw); String content = sw.toString().toUpperCase(); getJspContext().getOut().print(content); } }
带标签体的自定义标签练习
mytld.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"> <description>MyTag 1.0 core library</description> <display-name>MyTag core</display-name> <tlib-version>1.0</tlib-version> <short-name>safly</short-name> <uri>http://www.safly.com/mytag/core</uri> <tag> <name>printUpper</name> <tag-class>com.safly.PrintUpperTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>time</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>forEach</name> <tag-class>com.safly.PrintUpperTag</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>
Customer
package com.safly; public class Customer { private Integer id; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Customer(Integer id, String name) { super(); this.id = id; this.name = name; } public Customer() { // TODO Auto-generated constructor stub } }
PrintUpperTag
package com.safly; import java.io.IOException; import java.io.StringWriter; import java.util.Collection; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class PrintUpperTag extends SimpleTagSupport { private String time; public void setTime(String time) { this.time = time; } private Collection<?>items; private String var; public void setItems(Collection<?> items) { this.items = items; } public void setVar(String var) { this.var = var; } ///////////////////////////////////////// @Override public void doTag() throws JspException, IOException { JspFragment bodyContent = getJspBody(); StringWriter sw = new StringWriter(); bodyContent.invoke(sw); String content = sw.toString(); content = content.toUpperCase(); int count = 1; try { count = Integer.parseInt(time); } catch (Exception e) { } for (int i = 0; i < count; i++) { getJspContext().getOut().print(content+"<br>"); } if (items!=null) { for (Object obj: items) { getJspContext().setAttribute(var, obj); getJspBody().invoke(null); } } } }
mytag.jsp
<%@ page language="java" import="java.util.*" pageEncoding="GB18030"%> <%@page import="com.safly.Customer"%> <%@taglib uri="http://www.safly.com/mytag/core" prefix="safly"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <body> <safly:printUpper time="5"> hello</safly:printUpper> <% List<Customer> customers = new ArrayList<Customer>(); customers.add(new Customer(1,"AAA")); customers.add(new Customer(2,"BBB")); customers.add(new Customer(3,"CCC")); request.setAttribute("customers",customers); Map<String,Customer> customerMap = new HashMap<String,Customer>(); customerMap.put("a",customers.get(0)); customerMap.put("b",customers.get(1)); customerMap.put("c",customers.get(2)); request.setAttribute("customerMap",customerMap); %> <c:forEach items="${customerMap }" var ="cust"> ${pageScope.cust.key }--${cust.value.id }---${cust.value.name } </c:forEach> <safly:forEach items="${customers }" var ="cust"> ${pageScope.cust.id }--${cust.name } </safly:forEach> </body> </html>
浏览器输入http://localhost:8080/day01/mytag.jsp
输出结果如下:
&NBSP;HELLO &NBSP;HELLO &NBSP;HELLO &NBSP;HELLO &NBSP;HELLO b--2---BBB c--3---CCC a--1---AAA -- 1--AAA 2--BBB 3--CCC
主要来说下
<safly:forEach items="${customers }" var ="cust"> ${pageScope.cust.id }--${cust.name } </safly:forEach>
如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,可以理解为写给浏览器)
在PrintUpperTag进行了如下操作:
if (items!=null) { for (Object obj: items) { getJspContext().setAttribute(var, obj); getJspBody().invoke(null); } }
然后在jsp页面中进行获取即可
相关文章推荐
- 以页面片段作为属性的标签----JspFragment
- jsp输出xml内容的字符串,保证标签输出成文本,保证换行空格缩进格式
- html基础--标签,属性,文本格式化标签,计算机输出标签,引用和术语定义
- jsp常用标签及其属性说明
- 读取xml文档(标签 属性 文本)--------------②
- jsp页面上读取和设置select标签下的选中项和radio属性的选中项
- JSP指令标签的练习:errorPage属性和isErrorPage属性
- JSP中Session用法及其属性介绍
- 复习html标签及其属性
- jsp 标签生命周期详细介绍
- html常用标签及其属性用法
- JS读取并输出xml文件节点及属性(兼容IE,FF)
- jsp中影响编码的属性及其设置小结(contentType,pageEncoding,charset,setCharacterEncoding)
- jsp中影响编码的属性及其设置小结(contentType,pageEncoding,charset,setCharacterEncoding
- 使用struts标签在JSP格式化输出日期型属性值
- flex4.0精确读取xml标签与属性
- JSP自定义标签(2):带属性的自定义标签
- 读取一个文本文档,例如有1~10行,要求按10~1行的顺序输出.并保存予原文件
- jsp中影响编码的属性及其设置(嘿嘿,别人的好文章!)
- jsp中用JSTL标签如何判断非空后输出List元素