Jstl自定义标签及其生命周期、属性标签、及其读取文本练习、JspFragment输出标签体(2)

本文主要是介绍Jstl自定义标签及其生命周期、属性标签、及其读取文本练习、JspFragment输出标签体(2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是自定义标签?
标签处理器可以做哪些操作呢?
属性标签
输出一个文件-利用自定义标签
利用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;}@Overridepublic 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 {@Overridepublic void doTag() throws JspException, IOException {//自己定义的方法getJspBodyJspFragment 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;}/@Overridepublic 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">&nbsp;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页面中进行获取即可

这篇关于Jstl自定义标签及其生命周期、属性标签、及其读取文本练习、JspFragment输出标签体(2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1125253

相关文章

使用Java将实体类转换为JSON并输出到控制台的完整过程

《使用Java将实体类转换为JSON并输出到控制台的完整过程》在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用JSON格式,用Java将实体类转换为J... 在软件开发的过程中,Java是一种广泛使用的编程语言,而在众多应用中,数据的传输和存储经常需要使用j

Spring Security自定义身份认证的实现方法

《SpringSecurity自定义身份认证的实现方法》:本文主要介绍SpringSecurity自定义身份认证的实现方法,下面对SpringSecurity的这三种自定义身份认证进行详细讲解,... 目录1.内存身份认证(1)创建配置类(2)验证内存身份认证2.JDBC身份认证(1)数据准备 (2)配置依

如何使用 Python 读取 Excel 数据

《如何使用Python读取Excel数据》:本文主要介绍使用Python读取Excel数据的详细教程,通过pandas和openpyxl,你可以轻松读取Excel文件,并进行各种数据处理操... 目录使用 python 读取 Excel 数据的详细教程1. 安装必要的依赖2. 读取 Excel 文件3. 读

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

基于Python实现读取嵌套压缩包下文件的方法

《基于Python实现读取嵌套压缩包下文件的方法》工作中遇到的问题,需要用Python实现嵌套压缩包下文件读取,本文给大家介绍了详细的解决方法,并有相关的代码示例供大家参考,需要的朋友可以参考下... 目录思路完整代码代码优化思路打开外层zip压缩包并遍历文件:使用with zipfile.ZipFil

C#TextBox设置提示文本方式(SetHintText)

《C#TextBox设置提示文本方式(SetHintText)》:本文主要介绍C#TextBox设置提示文本方式(SetHintText),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录C#TextBox设置提示文本效果展示核心代码总结C#TextBox设置提示文本效果展示核心代

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

CSS will-change 属性示例详解

《CSSwill-change属性示例详解》will-change是一个CSS属性,用于告诉浏览器某个元素在未来可能会发生哪些变化,本文给大家介绍CSSwill-change属性详解,感... will-change 是一个 css 属性,用于告诉浏览器某个元素在未来可能会发生哪些变化。这可以帮助浏览器优化

CSS去除a标签的下划线的几种方法

《CSS去除a标签的下划线的几种方法》本文给大家分享在CSS中,去除a标签(超链接)的下划线的几种方法,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧... 在 css 中,去除a标签(超链接)的下划线主要有以下几种方法:使用text-decoration属性通用选择器设置:使用a标签选择器,将tex

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S