javaweb学习6——自定义标签

声明:本文只是自学过程中,记录自己不会的知识点的摘要,如果想详细学习JavaWeb,请到孤傲苍狼博客学习,JavaWeb学习点此跳转

本文链接:https://www.cnblogs.com/xdp-gacl/p/3916946.html

        https://www.cnblogs.com/xdp-gacl/p/3916968.html

        https://www.cnblogs.com/xdp-gacl/p/3917714.html

传统标签接口中的各个方法可以返回的返回值说明:

  下图列举了Tag接口、IterationTag接口和BodyTag接口中的主要方法及它们分别可以返回的返回值的说明。

  

在JSP API中也提供了IterationTag接口的默认实现类TagSupport、IterationTag接口的默认实现类TagSupportBodyTag接口的实现类BodyTagSupport我们在编写自定义标签的标签处理器类时,可以继承和扩展TagSupport类、IterationSupport类和BodyTagSupport类。

开发简单标签实现页面逻辑

  1.控制jsp页面某一部分内容是否执行

    编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面是否调用jspFrament.invoke方法来控制标签是否执行。

package me.gacl.web.simpletag;import java.io.IOException;import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;/*** @author gacl* SimpleTagSupport类实现了SimpleTag接口,* SampleTagDemo1类继承SimpleTagSupport*/
public class SimpleTagDemo1 extends SimpleTagSupport {/* 简单标签使用这个方法就可以完成所有的业务逻辑* @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()* 重写doTag方法,控制标签体是否执行*/@Overridepublic void doTag() throws JspException, IOException {//得到代表jsp标签体的JspFragmentJspFragment jspFragment = this.getJspBody();//得到jsp页面的的PageContext对象//PageContext pageContext = (PageContext) jspFragment.getJspContext();//调用JspWriter将标签体的内容输出到浏览器//jspFragment.invoke(pageContext.getOut());//将标签体的内容输出到浏览器jspFragment.invoke(null);}
}

  2.控制jsp页面内容重复执行

    编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法里面重复调用jspFrament.invoke方法即可。

package me.gacl.web.simpletag;import java.io.IOException;import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;/*** @author gacl* SimpleTagSupport类实现了SimpleTag接口,* SampleTagDemo2类继承SimpleTagSupport*/
public class SimpleTagDemo2 extends SimpleTagSupport {/* 简单标签使用这个方法就可以完成所有的业务逻辑* @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()* 重写doTag方法,控制标签执行5次*/@Overridepublic void doTag() throws JspException, IOException {// 得到代表jsp标签体的JspFragmentJspFragment jspFragment = this.getJspBody();for (int i = 0; i < 5; i++) {// 将标签体的内容输出到浏览器jspFragment.invoke(null);}}
}

  3.修改jsp页面内容输出

    编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法调用jspFrament.invoke方法时,让执行结果写一个自定义的缓冲中即可,然后开发人员可以取出缓冲的数据修改输出。

package me.gacl.web.simpletag;import java.io.IOException;
import java.io.StringWriter;import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;/*** @author gacl* SimpleTagSupport类实现了SimpleTag接口,* SampleTagDemo3类继承SimpleTagSupport*/
public class SimpleTagDemo3 extends SimpleTagSupport {/* 简单标签使用这个方法就可以完成所有的业务逻辑* @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()* 重写doTag方法,修改标签体里面的内容,将标签体的内容转换成大写*/@Overridepublic void doTag() throws JspException, IOException {// 得到代表jsp标签体的JspFragmentJspFragment jspFragment = this.getJspBody();StringWriter sw = new StringWriter();//将标签体的内容写入到sw流中
        jspFragment.invoke(sw);//获取sw流缓冲区的内容String content = sw.getBuffer().toString();content = content.toUpperCase();PageContext pageContext = (PageContext) this.getJspContext();//将修改后的content输出到浏览器中
        pageContext.getOut().write(content);}
}

  4.控制整个jsp页面是否执行

    编写一个类继承SimpleTagSupport,然后再重写doTag方法,在doTag方法抛出SkipPageException异常即可,jsp收到这个异常,将忽略标签余下jsp页面的执行。

示例代码如下:

package me.gacl.web.simpletag;import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;/*** @author gacl* SimpleTagSupport类实现了SimpleTag接口,* SampleTagDemo4类继承SimpleTagSupport*/
public class SimpleTagDemo4 extends SimpleTagSupport {/* 简单标签使用这个方法就可以完成所有的业务逻辑* @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()* 重写doTag方法,控制标签余下的Jsp不执行*/@Overridepublic void doTag() throws JspException, IOException {//抛出一个SkipPageException异常就可以控制标签余下的Jsp不执行throw new SkipPageException();}
}

tld文件中标签体类型设置细节

<tag><!-- 标签名 --><name>demo2</name><!-- 标签处理器类--><tag-class>me.gacl.web.simpletag.SimpleTagDemo2</tag-class><!-- 标签体允许的内容 ,scriptless表示标签体的内容不允许是java脚本代码--><body-content>scriptless</body-content>
</tag>

  开发好一个标签后,在tld文件中使用<tag>来描述一个标签,描述的内容包括标签名(name),标签处理器类(tag-class),标签体的内容(body-content)。

  tld文件中有四种标签体(body-content)类型 :empty、scriptless、JSP、tagdependent 

  empty表示该标签没有标签体

  scriptless:表示该标签是有标签体的,但是标签体的内容不能是java代码

  JSP:表示该标签是有标签体的,并且标签体的内容可以是任意的,包括java代码

  tagdependent:表示标签体里面的内容是给标签处理器类使用的(tagdependent用得比较少,了解一下即可)

简单标签标签体的细节注意问题:

   在简单标签(SampleTag)中标签体body-content的值只允许是empty、scriptless、tagdependent,不允许设置成JSP,如果设置成JSP就会出现异常:

The TLD for the class me.gacl.web.simpletag.SimpleTagDemo1 specifies an invalid body-content (JSP) for a SimpleTag

tld文件中用于描述标签属性的<attribute>元素说明

  <tag>元素的<attribute>子元素用于描述自定义标签的一个属性,自定义标签所具有的每个属性都要对应一个<attribute>元素

java类: 

package me.gacl.web.tag;import java.io.IOException;import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;public class SimpleTagDemo2 extends SimpleTagSupport{private int count;public void setCount(int count){this.count = count;}@Overridepublic void doTag() throws JspException, IOException {JspFragment jspFragment = this.getJspBody();for (int i = 1; i <= count; i++){jspFragment.invoke(null);}}
}

tld代码

<tag><!-- 标签名 --><name>demo5</name><!-- 标签处理器类--><tag-class>me.gacl.web.simpletag.SimpleTagDemo5</tag-class><!-- 标签体允许的内容--><body-content>scriptless</body-content><!-- 标签的属性描述 --><attribute><description>描述标签的count属性</description><!-- 标签的count属性 --><name>count</name><required>true</required><!-- rtexprvalue用来指示标签的属性值是否可以是一个表达式,一般设置为true,true就表示允许标签的属性值可以是一个表达式--><rtexprvalue>true</rtexprvalue></attribute>
</tag>

 

<attribute>元素的子元素说明:

  

 

转载于:https://www.cnblogs.com/dulianyong/p/10271552.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/249825.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

goland 实用键

代码补全 option command v转载于:https://www.cnblogs.com/smzd/p/10313417.html

关于Mysql java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)的问题...

问题所在&#xff1a; 1.连接数据库一个是密码是否正确&#xff0c; 2.driver是否对&#xff0c; 3.有么有jar包冲突&#xff0c;转载于:https://www.cnblogs.com/java-123/p/9403412.html

vscode配置vue环境

一、安装VSCode、NodeJS VSCode&#xff1a;https://code.visualstudio.com/ NodeJS&#xff1a;https://nodejs.org/en/ 二、打开VSCode&#xff0c;安装常用插件 如图所示&#xff08;安装后重新加载即可&#xff09;: 三、项目中添加.vscode文件夹&#xff0c;文件夹中添…

秒杀核心设计(减库存部分)-防超卖与高并发

商品详情页面的静态化&#xff0c;varnish加速&#xff0c;秒杀商品库独立部署服务器这种就略过不讲了。只讨论库存部分的优化 mysql配置层面的优化可以参考我的这篇文章 《关于mysql innodb引擎性能优化的一点心得》 重点设计在数据库层面。 2张表&#xff1a; 第一张&#xf…

go strconv

strconv是golang用来做数据类型转换的一个库。 介绍下strconv最常用的两个方法, 没有解释语言那么自在可以str(int),int(string), 那还算简练。 num, err : strconv.Atoi("-42") str : strconv.Itoa(-42)转换换成bool类型. b, err : strconv.ParseBool("true&qu…

django配置templates、static、media和连接mysql数据库

1.模板文件 # templates配置 if os.path.exists(os.path.join(BASE_DIR, templates)) is False:os.mkdir(os.path.join(BASE_DIR, templates)) TEMPLATES [{# 模板引擎&#xff0c;内置的模板引擎有&#xff1a;# 1. django.template.backends.django.DjangoTemplates# 2. dj…

vue调用顺序(初学版) index.html → main.js → app.vue → index.js → components/组件 测试

关于它是怎么调用运作的&#xff1a;https://mp.csdn.net/postedit/86134414 一. 准备工作&#xff1a; 1.下载webstorm&#xff0c;安装vue。 2.创建项目&#xff0c;cd到要放项目的文件夹下 vue init webpack vue_test 3.安装各种包 npm install 4.运行 cd vue_test …

web开发:jquery之DOM

一、文档结构 二、文档操作 三、文档操作案例 四、form表单 五、正则 六、form案例 一、文档结构 jsvar $sup $(.sup);console.log($sup.children()); // 子们console.log($sup.parent()); // 父console.log($sup.prev()); // 上兄弟console.log($sup.next()); // 下兄弟c…

NO.8:自学python之路------并行socket网络编程

摘要 一到放假就杂事很多&#xff0c;这次的作业比较复杂&#xff0c;做了一个周&#xff0c;进度又拖了。不过结果还不错。 正文 粘包 在上一节中&#xff0c;如果连续发送过多数据&#xff0c;就可能发生粘包。粘包就是两次发送的数据粘在一起被接收&#xff0c;损坏了数据的…

vue项目中主要文件的加载顺序(index.html、App.vue、main.js)

先后顺序&#xff1a; index.html > App.vue的export外的js代码 > main.js > App.vue的export里面的js代码 > Index.vue的export外的js代码 测试的页面代码块&#xff1a; 文件的加载先后顺序&#xff1a; Index.vue的mounted()中的输出没有执行。why&#…

Http请求报头设置(C#)

1、添加一个SetHeaderValue方法&#xff1a; public static void SetHeaderValue(WebHeaderCollection header, string name, string value) { var property typeof(WebHeaderCollection).GetProperty("InnerCollection",BindingFlags.Instance | BindingFlags.NonP…

vue-cli3使用cdn引入

1. index.html引入&#xff1a; <script src"https://cdn.bootcss.com/moment.js/2.20.1/moment.min.js"></script> <script src"https://cdn.bootcss.com/moment.js/2.20.1/locale/zh-cn.js"></script>2. vue.config.js配置&…

vue常用属性

Vue实例常用属性 1.数据 data:Vue 实例的数据对象 components&#xff1a;Vue实例配置局部注册组件 1.类方法 computed:计算属性 watch&#xff1a;侦听属性 filters&#xff1a;过滤器 methods:Vue实例方法 render&#xff1a;渲染函数&#xff0c;创建虚拟DOM 1.生命周期 c…

凸包算法

转载自&#xff1a;https://blog.csdn.net/bone_ace/article/details/46239187 凸包问题的五种解法 2015年05月29日 17:58:51 阅读数&#xff1a;33660前言&#xff1a; 首先&#xff0c;什么是凸包&#xff1f; 假设平面上有p0~p12共13个点&#xff0c;过某些点作一个多边形&a…

一个优雅的占位图解决方案。适用于 UITableView 和 UICollectionView。

FMListPlaceholder 项目地址&#xff1a;https://github.com/yfming93/FMListPlaceholder 一个优雅的占位图解决方案。适用于 UITableView 和 UICollectionView。 一行代码处理空列表占位图逻辑 0x001 与其他的同类三方库对比的优点&#xff1a; 首次进入列表占位图是不显示的。…

es7 async 前置依赖

https://stackoverflow.com/questions/33527653/babel-6-regeneratorruntime-is-not-defined 移动端 px2rem-loader 转载于:https://www.cnblogs.com/smzd/p/10560176.html

vue中 关于$emit的用法

1、父组件可以使用 props 把数据传给子组件。 2、子组件可以使用 $emit 触发父组件的自定义事件。 vm.$emit( event, arg ) //触发当前实例上的事件 vm.$on( event, fn );//监听event事件后运行 fn&#xff1b; 例如&#xff1a;子组件&#xff1a; <template><di…

SSO阅读有感

SSO比较详细且理解。赞 链接&#xff1a;https://www.cnblogs.com/ywlaker/p/6113927.html转载于:https://www.cnblogs.com/z1j2r3/p/9408480.html

C语言——反弹球游戏(第二阶段

#include<stdio.h> #include<stdlib.h> #include<windows.h> #include<conio.h>#define High 15 //游戏画面尺寸 #define Width 20//全局变量 int ball_x,ball_y; //小球的坐标 int ball_vx,ball_vy; //小球的速度 int canvas[High][W…

docker运行我们的容器

docker images docker pull nginx 运行 docker images 查看Nginx镜像是否获取成功&#xff0c;若为如下所示即为获取成功&#xff1a; docker run -p 8080:80 -d nginx docker run –name 容器名 -d&#xff08;后台运行&#xff09;-p 本地端口:容器端口 -v(挂载) 挂载本地路径…