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

相关文章

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

自定义类型:结构体(续)

目录 一. 结构体的内存对齐 1.1 为什么存在内存对齐? 1.2 修改默认对齐数 二. 结构体传参 三. 结构体实现位段 一. 结构体的内存对齐 在前面的文章里我们已经讲过一部分的内存对齐的知识,并举出了两个例子,我们再举出两个例子继续说明: struct S3{double a;int b;char c;};int mian(){printf("%zd\n",s

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1(高级消息队列协议)是一种网络协议,它允许遵从该协议的客户端(Publisher或者Consumer)应用程序与遵从该协议的消息中间件代理(Broker,如RabbitMQ)进行通信。 AMQP 0-9-1模型的核心概念包括消息发布者(producers/publisher)、消息(messages)、交换机(exchanges)、

EMLOG程序单页友链和标签增加美化

单页友联效果图: 标签页面效果图: 源码介绍 EMLOG单页友情链接和TAG标签,友链单页文件代码main{width: 58%;是设置宽度 自己把设置成与您的网站宽度一样,如果自适应就填写100%,TAG文件不用修改 安装方法:把Links.php和tag.php上传到网站根目录即可,访问 域名/Links.php、域名/tag.php 所有模板适用,代码就不粘贴出来,已经打

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

Spring 源码解读:自定义实现Bean定义的注册与解析

引言 在Spring框架中,Bean的注册与解析是整个依赖注入流程的核心步骤。通过Bean定义,Spring容器知道如何创建、配置和管理每个Bean实例。本篇文章将通过实现一个简化版的Bean定义注册与解析机制,帮助你理解Spring框架背后的设计逻辑。我们还将对比Spring中的BeanDefinition和BeanDefinitionRegistry,以全面掌握Bean注册和解析的核心原理。

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m