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

相关文章

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

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

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各

使用Python实现文本转语音(TTS)并播放音频

《使用Python实现文本转语音(TTS)并播放音频》在开发涉及语音交互或需要语音提示的应用时,文本转语音(TTS)技术是一个非常实用的工具,下面我们来看看如何使用gTTS和playsound库将文本... 目录什么是 gTTS 和 playsound安装依赖库实现步骤 1. 导入库2. 定义文本和语言 3

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Python实现常用文本内容提取

《Python实现常用文本内容提取》在日常工作和学习中,我们经常需要从PDF、Word文档中提取文本,本文将介绍如何使用Python编写一个文本内容提取工具,有需要的小伙伴可以参考下... 目录一、引言二、文本内容提取的原理三、文本内容提取的设计四、文本内容提取的实现五、完整代码示例一、引言在日常工作和学

解决Java中基于GeoTools的Shapefile读取乱码的问题

《解决Java中基于GeoTools的Shapefile读取乱码的问题》本文主要讨论了在使用Java编程语言进行地理信息数据解析时遇到的Shapefile属性信息乱码问题,以及根据不同的编码设置进行属... 目录前言1、Shapefile属性字段编码的情况:一、Shp文件常见的字符集编码1、System编码

浅析CSS 中z - index属性的作用及在什么情况下会失效

《浅析CSS中z-index属性的作用及在什么情况下会失效》z-index属性用于控制元素的堆叠顺序,值越大,元素越显示在上层,它需要元素具有定位属性(如relative、absolute、fi... 目录1. z-index 属性的作用2. z-index 失效的情况2.1 元素没有定位属性2.2 元素处

基于Spring实现自定义错误信息返回详解

《基于Spring实现自定义错误信息返回详解》这篇文章主要为大家详细介绍了如何基于Spring实现自定义错误信息返回效果,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录背景目标实现产出背景Spring 提供了 @RestConChina编程trollerAdvice 用来实现 HTT