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读取本地文件并转换为MultipartFile对象的方法

《使用Java读取本地文件并转换为MultipartFile对象的方法》在许多JavaWeb应用中,我们经常会遇到将本地文件上传至服务器或其他系统的需求,在这种场景下,MultipartFile对象非... 目录1. 基本需求2. 自定义 MultipartFile 类3. 实现代码4. 代码解析5. 自定

Python文本相似度计算的方法大全

《Python文本相似度计算的方法大全》文本相似度是指两个文本在内容、结构或语义上的相近程度,通常用0到1之间的数值表示,0表示完全不同,1表示完全相同,本文将深入解析多种文本相似度计算方法,帮助您选... 目录前言什么是文本相似度?1. Levenshtein 距离(编辑距离)核心公式实现示例2. Jac

聊聊springboot中如何自定义消息转换器

《聊聊springboot中如何自定义消息转换器》SpringBoot通过HttpMessageConverter处理HTTP数据转换,支持多种媒体类型,接下来通过本文给大家介绍springboot中... 目录核心接口springboot默认提供的转换器如何自定义消息转换器Spring Boot 中的消息

Python中高级文本模式匹配与查找技术指南

《Python中高级文本模式匹配与查找技术指南》文本处理是编程世界的永恒主题,而模式匹配则是文本处理的基石,本文将深度剖析PythonCookbook中的核心匹配技术,并结合实际工程案例展示其应用,希... 目录引言一、基础工具:字符串方法与序列匹配二、正则表达式:模式匹配的瑞士军刀2.1 re模块核心AP

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

Python如何调用另一个类的方法和属性

《Python如何调用另一个类的方法和属性》在Python面向对象编程中,类与类之间的交互是非常常见的场景,本文将详细介绍在Python中一个类如何调用另一个类的方法和属性,大家可以根据需要进行选择... 目录一、前言二、基本调用方式通过实例化调用通过类继承调用三、高级调用方式通过组合方式调用通过类方法/静

java -jar example.jar 产生的日志输出到指定文件的方法

《java-jarexample.jar产生的日志输出到指定文件的方法》这篇文章给大家介绍java-jarexample.jar产生的日志输出到指定文件的方法,本文给大家介绍的非常详细,对大家的... 目录怎么让 Java -jar example.jar 产生的日志输出到指定文件一、方法1:使用重定向1、

Python自定义异常的全面指南(入门到实践)

《Python自定义异常的全面指南(入门到实践)》想象你正在开发一个银行系统,用户转账时余额不足,如果直接抛出ValueError,调用方很难区分是金额格式错误还是余额不足,这正是Python自定义异... 目录引言:为什么需要自定义异常一、异常基础:先搞懂python的异常体系1.1 异常是什么?1.2

Linux中的自定义协议+序列反序列化用法

《Linux中的自定义协议+序列反序列化用法》文章探讨网络程序在应用层的实现,涉及TCP协议的数据传输机制、结构化数据的序列化与反序列化方法,以及通过JSON和自定义协议构建网络计算器的思路,强调分层... 目录一,再次理解协议二,序列化和反序列化三,实现网络计算器3.1 日志文件3.2Socket.hpp

C语言自定义类型之联合和枚举解读

《C语言自定义类型之联合和枚举解读》联合体共享内存,大小由最大成员决定,遵循对齐规则;枚举类型列举可能值,提升可读性和类型安全性,两者在C语言中用于优化内存和程序效率... 目录一、联合体1.1 联合体类型的声明1.2 联合体的特点1.2.1 特点11.2.2 特点21.2.3 特点31.3 联合体的大小1