今天是学习自定义标签的第二天,主要是写一个自定义的循环标签。

先看效果图:

前台页面Jsp代码

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="myout" uri="/demo" %>
<html>
<head>
</head>
<%
String[] array = new String[]{"one","two","three","four","five"};
pageContext.setAttribute("arr", array);
%>
<body>
<h1>我的测试页面</h1>
<myout:Foreach items="arr" var="item">
array数组里对应的英文数字:${item}<br>
</myout:Foreach>
</body>
</html>

跟第一篇一样,还是分四部分讲解:

第一部分:自定义标签文件(*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">
<tlib-version>1.0</tlib-version>
<short-name>myout</short-name>
<uri>/demo</uri>
<!-- 循环 -->
<tag>
<name>Foreach</name>
<tag-class>com.tag.support.TagDemo</tag-class>
<!-- 标签体可以用EL表达式 -->
<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>

这个地方要注意一点:关于<%@taglib prefix="myout" uri="/demo" %> 是如何找到demo.tld文件的?

两种方式:

第一种方式:就如同上面这样配置,在demo.tld文件中加上<uri>/demo</uri> ,指定uri,

但是这种方式demo.tld必须放在WEB-INF下,不然容器找不到

  第二种方式:在web.xml中配置,这种方式是通过显示的指定demo.tld的位置,可以不放在WEB-INF只要指向正确就好

        <jsp-config>
<taglib>
<taglib-uri>/demo</taglib-uri>
<taglib-location>/WEB-INF/lirui.tld</taglib-location>
</taglib>
</jsp-config>

新增一种方式:其实在jsp页面引用自定义标签还可以另一种方式(指定*.tld文件所在路径),只是这种方式不灵活。

%@taglib prefix="myout" uri="/WEB-INF/demo.tld" %

第二部分:标签具体业务实现类。

自定义的类要继承(extends)SimpleTagSupport

import java.io.IOException;

import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport; public class TagDemo extends SimpleTagSupport {
//注意:这个属性要与tld文件中定义的属性一致,并提供get和set方法
private String items;
private String var;
public String getItems() {
return items;
} public void setItems(String items) {
this.items = items;
} public String getVar() {
return var;
} public void setVar(String var) {
this.var = var;
}
//具体业务实现类
@Override
public void doTag() throws JspException, IOException {
//this.getJspContext()获得JspContext对象也就是前台页面的PageContext
//可以看出页面输出Hello World注意是这里的write方法实现的
JspContext jspContext = this.getJspContext();
String[] arr = (String[])jspContext.getAttribute(items);
for(String s: arr){
jspContext.setAttribute(var, s);
this.getJspBody().invoke(null);
} }
}

注意一点:this.getJspBody().invoke(null); 这行代码表示把标签体的内容的内容输入到浏览器,如果没有调用该方法,则忽略标签体

我一开始做的时候没有加这一行代码,

直接导致前台页面<myout:Foreach items="arr" var="item">array数组里对应的英文数字:${item}<br> </myout:Foreach> 标签体内同显示不出来,当时查了下资料才知道这里没有加this.getJspBody().invoke(null); 这一行代码。

扩充一下知识点:JspFragment是个抽象类,这个类代码很简单,具体如下:

import java.io.IOException;
import java.io.Writer;
import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException; public abstract class JspFragment
{
public abstract void invoke(Writer paramWriter)
throws JspException, IOException; public abstract JspContext getJspContext();
}

这个类的实例通过SimpleTagSupport类中的getJspBody()方法获得的。

该类实例封装了标签体的内容,主要方法就是invoke方法,该方法具体有两种用法:

第一种:this.getJspBody().invoke(null);表示输出到浏览器,这是原样输出的

第二种:当需要对标签体进行修改时,需要用到第二种,this.getJspBody().invoke(Writer out);

假设:我希望上面显示的页面效果使所有字母大写,效果如图

代码如下:

//具体业务实现类
@Override
public void doTag() throws JspException, IOException {
JspContext jspContext = this.getJspContext();
String[] arr = (String[])jspContext.getAttribute(items);
for(String s: arr){
jspContext.setAttribute(var, s);
//定义一个缓冲区,把内容先输入到缓存区中,然后在打印到浏览器
StringWriter sw = new StringWriter();
this.getJspBody().invoke(sw);
String str = sw.toString().toUpperCase();
//打印的具体操作
this.getJspContext().getOut().write(str);
} }

这就是这两种方式的区别。

第三部分:Jsp页面引用自定义标签。

<%@taglib prefix="myout" uri="/demo" %>

关于引用自定义标签,上面第二部分已说的很清楚,这里就不多说了。

第四部分:关于定义uri的几种方式。

两种方式:(第一部分好像也说了,这里再重复一遍)

第一种方式:就如同上面这样配置,在demo.tld文件中加上<uri>/demo</uri> ,指定uri,

但是这种方式demo.tld必须放在WEB-INF下,不然容器找不到

  第二种方式:在web.xml中配置,这种方式是通过显示的指定demo.tld的位置,可以不放在WEB-INF只要指向正确就好

        <jsp-config>
<taglib>
<taglib-uri>/demo</taglib-uri>
<taglib-location>/WEB-INF/lirui.tld</taglib-location>
</taglib>
</jsp-config>

今天是学习Jsp自定义标签的第二天,刚开始写博客,如果有什么问题欢迎各位网友及时提出,谢谢。

技术的提高在于分享,而不是闭门造车。

Jsp2.0自定义标签(第二天)——自定义循环标签的更多相关文章

  1. Jsp2.0自定义标签(第一天)——一个简单的例子

    今天是学习自定义标签的第一天 Jsp2.0以来,自定义标签的实现比传统标签的实现容易了很多,一般只要extends类SimpleSupport重写doTag()方法即可. 先看最简单的例子,输出一个H ...

  2. JSP2.0自定义标签

    JSP1.0中可以通过继承TagSupport或者BodyTagSupport来实现自定义的tag处理方法. JSP2.0中也支持另外一种更为简单的自定tag的方法,那就是直接讲JSP代码保存成*.t ...

  3. jsp的标签库和自定义标签

    1.jstl标签库 JSP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能. JSTL支持通用的.结构化的任务,比如迭代,条件判断,XML文档操作,国际化标签,SQL标签. ...

  4. Javaweb学习笔记——(十三)——————JSTL、JSTL核心标签库、自定义标签、有标签体的标签、带有属性的标签、MVC、Javaweb三层框架

    JSTLApache提供的标签库 jar包:jstl-1.2.jar,如果传MyEclipse,他会在我们导入jar包,无需自己导入,如果没有使用MyEclipse那么需要自行导入.--------- ...

  5. jsp2.0+中的标签文件,JSP Fragment技术

    刚进新公司不久,今天在看到项目中用到了.tag文件.刚开始我还以为这个是第三方类似freemarker的模板技术.问了下项目组的其他人员,原来这是jsp2.0以来就有的JSP Fragment技术.以 ...

  6. 学会怎样使用Jsp 内置标签、jstl标签库及自定义标签

    学习jsp不得不学习jsp标签,一般来说,对于一个jsp开发者,可以理解为jsp页面中出现的java代码越少,对jsp的掌握就越好,而替换掉java代码的重要方式就是使用jsp标签.  jsp标签的分 ...

  7. ⑦JSP2.0的福利(标签文件)

    前言 本篇接着上一篇博客:[传送门] 这次讲的是JSP2.0的特性之一,我们可以编写标签文件,指没有标签处理器和标签类库描述符的定制动作指令,不编译,无标签类描述符. 本文结构: ①标签文件简介 ②第 ...

  8. Spring源码分析(九)解析默认标签中的自定义标签元素

    摘要:本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 到这里我们已经完成了分析默认标签的解析与提取过程,或许涉及的内容太多,我 ...

  9. javaweb中带标签体的自定义标签

    1.完整的示例代码: 标签体的处理器类,JspFragmentTest.java package com.javaweb.tag; import java.io.IOException; import ...

随机推荐

  1. STL学习笔记5--map and multimap

    Maps是一种关联式容器,包含“关键字/值”对. Multimaps和maps很相似,但是MultiMaps允许重复的元素. 简单介绍: 1.声明,首先包含头文件 “map” map <int, ...

  2. HTML5 新增绘图功能

    <!DOCTYPE html> <html> <head lang="en"> <title></title> < ...

  3. C#的一些基本问题

    静态类和静态变量静态类的定义:static class 类名 静态方法和变量必须使用类名来引用,而不能使用实例化后的对象,因为,静态变量不属于任何实例,而是共有的. 非静态类里面既可以定义静态方法也可 ...

  4. [HEOI2016/TJOI2016][bzoj4554] 游戏 [建图+最大流]

    题面 传送门 思路 看到棋盘摆放和棋子冲突,再加上这么小的数据范围,你能想到什么? 网络流棋盘模型啊! 就是 把源点连到每一行,每一列连到汇点,再在中间...... 等等,这道题每行不一定全部冲突?? ...

  5. 转JSON提示No serializer found for class

    在调用Json串生成方法时,提示: No serializer found for class com.jeremxy.domain.EpgDetail and no propertiesdiscov ...

  6. 洛谷P2947 [USACO09MAR]仰望Look Up

    P2947 [USACO09MAR]仰望Look Up 74通过 122提交 题目提供者洛谷OnlineJudge 标签USACO2009云端 难度普及/提高- 时空限制1s / 128MB 提交   ...

  7. ZJOI2017D1

    假装我还活着. 去温州前沉迷各种奇怪的动画片..嗯补了不少高达.. 到温州以后继续看片..嗯ZG还是挺不错的..然后接着就FA♂现我什么都不会写..有点尴尬.. 因为宾馆离温州中学比较远就完全没去听课 ...

  8. linux之awk手册

    awk 手册   原文 Table of Contents 1. awk简介 2. awk命令格式和选项 2.1. awk的语法有两种形式 2.2. 命令选项 3. 模式和操作 3.1. 模式 3.2 ...

  9. 汇编中的 imul 指令

    1.这是整形乘法指令,无论是 unsigned int 还算是 signed int 实际上指令都是进行相同的运算,只不过最终的结果是由程序中的类型来做相应的解读 2.imul 指令实际上不会发生 o ...

  10. 教你怎么使用Windows7系统自带的备份与还原的方法

    原文发布时间为:2010-09-09 -- 来源于本人的百度文章 [由搬家工具导入] 继续单击“下一步”按钮,在其后界面中检查上述备份设置是否正确,如果不正确的话可以直接单击“取消”按钮,重新设置备份 ...