JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

JSTL

JSTL简单介绍:

JSTL的全称:JSP Standard Tag Library,JSP标准标签库

JSTL的作用:

提供给Java Web开发者一个标准通用的标签函数库

和EL来代替传统直接在页面上嵌入Java程序(Scripting)的做法,以提高程序可读性、维护性和方便性

JSTL的版本号:

JSTL的主要版本号是1.0、1.1和1.2(差别不大)

1.0版本号EL表达式还没有纳入官方规范

1.1和1.2版本号EL表达式已经纳入了官方规范

JSTL1.1 下载对应的jar包

JSTL的下载

JSTL主要由Apache组织的Jakarta Project实现

http://tomcat.apache.org/taglibs/standard/

容器必须支持Servlet2.4且JSP2.0以上的版本号

JavaEE1.4

JSTL导入jar包

解压缩后将lib中的jstl.jar、standard.jar 拷贝到WEB应用程序的WEB-INF\lib下

JSTL标签库

  • 核心标签库(core)—c(重点)
  • XML(x:操作xml的标签库)
  • SQL(sql标签库)
  • FMT(fmt:国际化标签库)
  • JSTL函数(EL函数)el

JSTL高速入门

导入jar包(jstl.jar和standard.jar)

当中jstl.jar是编译后的Java类文件,standard.jar定义的是标准接口

新建JSP的页面

在页面中引入核心标签库

JSTL标签库关于导入版本号的问题

http://java.sun.com/jsp/core 1.1或者1.2版本号(使用该版本号)

http://java.sun.com/jstl/core 1.0版本号(不支持EL表达式)

输出常量或者域范围中的变量(value属性,使用EL表达式)

输出默认值(default属性)

默认HTML标签不转义(escapeXml)
属性名是否支持EL 属性类型属性描写叙述value true Object 指定要输出的内容escapeXml true Boolean 指定是否将>、default true Object 指定假设value属性的值为null时所输出的默认值

Hello c out

${m }

${fn:escapeXml("link") }

${empty city?"北京":city }

在WebRoot下新建jstl目录,在目录下新建out.jsp

实例代码例如以下:

Insert title here

传统方式

JSTL的方式

JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

  • 向4个域中存入值。(var value scope属性)
  • 设置Web域中的java.util.Map 类型的属性对象或JavaBean类型的属性对象的属性(target property value属性)

属性名 是否支持EL 属性类型 属性描写叙述 value true Object 用于指定属性 var false String 用于指定要设置的Web域属性的名称 scope false String 用于指定属性所在的Web域 target true Object 用于指定要设置属性的对象。这个对象必须是
JavaBean对象或java.util.Map对象 property true String 用于指定当前要为对象设置的属性名称

在WebRoot/jstl下新建set.jsp

代码例如以下:

Insert title here

传统方式

${ user.username }

JSTL方式

${ i }

${ user.username }

JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

其语法格式例如以下:

假设不设置,默认是pageContext域范围内查找删除值。

使用方法演示样例:

在WebRoot/jstl文件夹下新建remove.jsp

实例代码例如以下:

Insert title here

传统方式

${ name }

${name }

JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

*
* var属性用于标识

关键代码:

在WebRoot/jstl下新建catch.jsp

实例代码例如以下:

Insert title here

传统方式

JSTL的方式

${ e.message }

JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

属性名 是否支持EL 属性类型 属性描写叙述 test true boolean 决定是否处理标签体中的内容的条件表达式 var false String 用于指定将test属性的运行结果保存到某个Web域中的某个属性的名称 scope false String 指定将test属性的运行结果保存到哪个Web域中 注意:没有

在WebRoot/jstl下新建if.jsp







Insert title here



传统方式

= 10){ out.print("a >= 10"); }else{ out.print("a < 10"); } %>

JSTL方式

i >= 10 i < 10 ${ x }

![](//img-blog.csdn.net/20170203195742497?

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

在WebRoot/jstl文件夹下新建choose.jsp

代码例如以下:







Insert title here



获取參数

传统方式

= 10 ){ out.print("a >= 10"); }else if(a < 10){ out.print("a < 10"); }else{ out.print("其它"); } %>

JSTL方式

i >= 10 i < 10 其它

![](//img-blog.csdn.net/20170203201606347?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

###

属性名 是否支持EL 属性类型 属性描写叙述 var false String 指定将当前迭代到的元素保存到page这个域中的属性名称 varStatus false String 记住用于保存迭代信息的对象 items true 不论什么支持的类型 将要迭代的集合对象 begin true int 假设指定items属性,就从集合中的第begin个元素開始进行迭代
。begin的索引值从0開始编号。假设没有指定items属性,就从
begin指定的值開始迭代。直到end值时结束迭代 end true int 与begin属性类似 step true int 指定迭代的步长,即迭代因子的迭代增量

遍历数组或者集合:

var:代表遍历的每个元素

items:要迭代的集合对象

获取遍历的内容:${ xxx }

遍历Map集合:

var:代表key与value的关系entry

items:要迭代的map集合

获取遍历的内容:${ xxx.key } —-${ xxx.value }

遍历对象集合:

var:代表遍历的每个对象

items:要迭代的集合

获取遍历的内容: ${ xxx.对象的属性 }

从1遍历到10:

var:定义变量

begin:从哪開始

end:到哪结束

step:迭代步长(相当于x+=step)

计算从1加到10的和:

定义变量sum。值为0

通过forEach循环1到10,每循环一次加到还有一个变量中

在循环中间定义变量。每次计算到该变量中

${sum }

varStatus属性:

记录迭代相关的信息:

属性 类型 意义 index number 如今指到成员的索引 count number 总共指到成员的总数 first boolean 如今指到的成员是否是第一个成员 last boolean 如今指到的成员是否是最后一个成员 遍历10到100的偶数,每到第三个数,显示红色:

在WebRoot/jstl文件夹下新建forEach.jsp

实例代码例如以下:

Insert title here

遍历数组

    ${ s }

遍历集合
 list = new ArrayList();
    list.add("美美");
    list.add("小凤");
    list.add("芙蓉");
    list.add("小泽");
    request.setAttribute("list", list);
%>

    ${ s }

遍历Map集合
 map = new HashMap();
    map.put("aa", "美美");
    map.put("bb", "小凤");
    map.put("cc", "芙蓉");
    request.setAttribute("map", map);
%>

    ${ entry.key } -- ${ entry.value }

遍历对象的集合
 uList = new ArrayList();
    uList.add(new User("美美","123"));
    uList.add(new User("小风","234"));
    uList.add(new User("芙蓉","345"));
    request.setAttribute("uList", uList);
%>

    ${ user.username } -- ${ user.password }

迭代数据
迭代从1到10

    ${ i }

计算从1加到100的和

${ sum }

遍历10到100的偶数,每到第3个数,显示红色

            ${ i }

            ${ i }

            ${ i }

![](//img-blog.csdn.net/20170203210200667?

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

用来切分字符串

名称 说明 EL 类型 必须 默认值 var 用来存放如今指到的成员 N String 否 无 items 被迭代的字符串 Y String 是 无 delims 定义用来切割字符串的字符 N String 是 无 varStatus 用来存放如今指到的相关成员信息 N String 否 无 begin 開始的位置 Y int 否 0 end 结束的位置 Y int 否 最后一个成员

语法格式:

在WebRoot/jstl文件夹下新建forTokens.jsp

代码例如以下:

Insert title here

分隔字符串

    ${ x }

![](//img-blog.csdn.net/20170203212826888?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

###

* 在JSP页面进行URL的相关操作时。常常要在URL地址后面附加一些參数。
* %d6%d0%b9%fa “后再附加到URL地址后面,这也就是使用
* 演示样例:

###

名称 说明 EL 类型 必须 默认值 url 一文件被包括的地址 Y String 是 无 context 项目虚拟路径 Y String 否 无 var 储存被包括的文件的内容(以String类型存入) Y String 否 无 scope var变量的JSP范围 N String 否 page charEncoding 被包括文件的内容的编码方式 Y String 否 无 varReader 储存被包括的文件的内容(以Reader类型存入) N String 否 无

***

在WebRoot/jstl/下新建 import.jsp(包括choose.jsp 并在choose.jsp 中获取參数)

实例代码例如以下:

Insert title here

JSTL方式

${ i }

![](//img-blog.csdn.net/20170203215250156?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

###

属性名 是否支持EL 属性类型 属性描写叙述 value true String 指定要构造的URL var false String 指定将构造出的URL结果保存到Web域中的属性名称 scope false String 指定将构造出的URL结果保存在哪个域中

在WebRoot/jstl/下新建url.jsp

Insert title here

JSTL方式

choose
i= ${i }

url=  
myurl= ${myurl }

myurl2= ${myurl2 }

改动choose.jsp 例如以下:







Insert title here



获取參数

传统方式

= 10 ){ out.print("a >= 10"); }else if(a < 10){ out.print("a < 10"); }else{ out.print("其它"); } %>

JSTL方式

i >= 10 i < 10 其它

禁用浏览器的cookie后。执行例如以下:
![](//img-blog.csdn.net/20170203223243006?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
点击choose跳转到choose.jsp

###

属性名 是否支持EL 属性类型 属性描写叙述 url true String 指定要转发或重定向到的目标资源的URL地址 context true String 当要使用相对路径重定向到 **同一个server下**的其它WEB应用程序中的
资源时,context属性指定其它WEB应用程序的名称

注意:假设重定向第三方的站点时要使用绝对路径(不能再使用Context)

// 曾经重定向
// response.sendRedirect(“/day12/index.jsp”);
%>

在WebRoot/jstl下新建redirect.jsp

Insert title here

JSTL方式

## EL函数库

### JSTL中的经常使用EL函数

EL函数是用来操作字符串的
因为在JSP页面中显示数据时,常常须要对显示的字符串进行处理,SUN公司针对一些常见处理定义了一套EL函数库供开发人员使用。

这些EL函数在JSTL开发包中进行描写叙述。因此在JSP页面中使用SUN公司的EL函数库。须要导入JSTL开发包,并在页面中导入EL函数库。例如以下所看到的:

在页面中使用JSTL定义的EL函数:

(能够在fn.tld文件里查看)

### fn:toLowerCase

fn:toLowerCase函数将一个字符串中包括的全部字符转换为小写形式,并返回转换后的字符串。它接收一个字符串类型的參数,比如:

fn:toLowerCase(“Www.IT315.org”)的返回值为字符串”www.it315.org”

fn.toLowerCase(“”) 的返回值为空字符串

### fn:toUpperCase

fn:toUpperCase函数将一个字符串中包括的全部字符转换为大写形式,并返回转换后的字符串,它接收一个字符串类型的參数。比如:

fn:toUpperCase(“www.IT315.org”)的返回值为字符串”WWW.IT315.ORG”

fn:toUpperCase(“”)的返回值为空字符串

### fn:trim

fn:trim函数删除一个字符串的首尾的空格,并返回删除空格后的结果字符串,它接收一个字符串类型的參数。须要注意的是,fn:trim函数不能删除字符串中间位置的空格

比如:fn:trim(” www.it3 15.org “)的返回值字符串是”www.it 315.org”

### fn:length

fn:length函数返回一个集合或数组大小,或返回一个字符串中包括的字符的个数。返回值是int类型。fn:length函数接收一个參数。这个參数能够是

假设fn:length函数的參数为null或者是元素个数为0的集合或数组对象。则函数返回0。假设參数是空字符串,则函数返回0;

### fn:split

fn:split函数以指定字符串作为分隔符,将一个字符串切割成数组并返回这个字符串数组。

fn:split函数接收两个字符串类型的參数,第一个參数表示要切割的字符串。第二个參数表示作为分隔符的字符串。

比如:fn:split(“www.it315.org”,”.”)[1]的返回值为字符串”it315″

### fn:join

fn:join函数以一个字符串作为分隔符,将一个字符串数组中的全部元素合并为一个字符串并返回合并后的结果字符串。fn:join函数接收两个參数。第一个參数是要操作的字符串数组,第二个參数是作为分隔符的字符串。

假设fn:join函数的第二个參数是空字符串。则fn:join函数的返回值直接将元素连接起来。比如:

如果stringArray是保存在Web域中的一个属性,它表示一个值为{“www”,”it315″,”org”}的字符串数组。则fn:join(stringArray,”.”)返回字符串”www.it315.org”

fn:join(fn:split(“www,it315,org”,”,”),”.”) 的返回值为字符串”www.it315.org”

### fn:indexOf

fn:indexOf 函数返回指定字符串在一个字符串中第一次出现的索引值,返回值为int类型。

fn:indexOf函数接收两个字符串类型的參数。假设第一个參数字符串中包括第二个參数字符串,那么无论第二个參数字符串在第一个參数字符串中出现几次。fn:indexOf函数总是返回第一次出现的索引值;假设第一个參数中不包括第二个參数。则fn:indexOf函数返回-1。假设第二个參数为空字符串,则fn:indexOf函数总是返回0。

比如:fn:indexOf(“www.it315.org”,”t3″) 的返回值为5

### fn:contains

fn:contains函数检測一个字符串中是否包括指定的字符串,返回值为布尔类型。

fn:contains函数在比較两个字符串是否相等时是大写和小写敏感的。

fn:contains函数接收两个字符串类型的參数。假设第一个字符串中包括第二个參数字符串返回true,否则返回false。假设第二个參数的值为空字符串。则fn:contains函数总是返回true。实际上,fn:contains(string,substring)等价于fn:indexOf(string,sunstring)!= -1

忽略大写和小写的EL函数:fn:containsIgnoreCase

### fn:startsWith

fn:startsWith 函数用于检測一个字符串是否以指定的字符串開始的,返回值为布尔类型。
fn:startsWith 函数接收两个字符串类型的參数,假设第一个參数字符串以第二个參数字符串開始,则函数返回true,否则函数返回false。

假设第二个參数为空字符串。则fn:startsWith函数总是返回true。比如:

fn:startsWith(“www.it315.org”,”it315″)的返回值为false

与之相应的EL函数:fn:endsWith

### fn:replace

fn:replace函数将一个字符串中包括的指定字符串替换为其它的指定字符串,并返回替换后的结果字符串。fn:replace(“www it315 org”,” “,”.”)的返回值为字符串”www.it315.org”

### fn:substring

fn:substring 函数用于截取一个字符串的子字符串并返回截取到的子字符串。

fn:substring函数接收三个參数,第一个參数是用于指定要操作的源字符串。第二个參数是用于指定截取子字符串開始的索引值,第三个參数是用于指定截取子字符串结束的索引值,第二个參数和第三个參数都是int类型,其值都从0開始比如:

fn:substring(“www.it315.org”,4,9)的返回值为字符串”it315″

### fn:substringAfter

fn:substringAfter函数用于截取并返回一个字符串中的指定字符串第一次出现之后的子字符串。fn:substringAfter函数接收两个字符串类型的參数。第一个參数表示要操作的源字符串。第二个參数表示指定的子字符串。

fn:substringAfter(“www.it315.org”,”.”)的返回值为字符串”it315.org”

与之相应的EL函数为:fn:substringBefore

## 自己定义EL函数开发步骤

EL自己定义函数开发与应用包含下面三个步骤:

编写一个Java类。方法必须是静态方法。

在WEB-INF文件夹下新建一个tld的文件。

没有标签的提示,复制http://java.sun.com/xml/ns/j2ee , 合并名称

设置2.0,设置url和shortname

编写标签库描写叙述符(tld)文件。在tld文件配置自己定义函数

使用function标签配置自己定义函数。

使用name标签配置方法名(能够随意)

使用function-class标签配置类的全路径

使用function-signature 标签配置返回值类型(中间有空格)方法名称(參数类型)

在JSP页面中导入和自己定义函数

### 开发EL function注意事项

编写标签库描写叙述文件后。须要将它放置到TLD文件里的

实比例如以下:

在src下新建一个cn.itcast.el的包。在包内新建ElDemo1.java

代码例如以下:

package cn.itcast.el;

public class ElDemo1 {

    public static String sayHello(String name){
        return "hello "+name;
    }

}

在WebRoot/WEB-INF下新建myfn的tld文件 并进行配置:

配置后的代码例如以下:

1.0
 myfn
 http://www.itcast.cn/1110/myfn

    sayHi

    cn.itcast.el.ElDemo1

    java.lang.String sayHello(java.lang.String)

在WebRoot根文件夹下新建el文件夹,在里面新建demo.jsp

Insert title here

${ fn:length("abcdefg") }

${ fn:toUpperCase("abcdefg") }

${ myfn:sayHi("小风") }

![](//img-blog.csdn.net/20170205161402015?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMzA4NzUxMw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)

## 自己定义标签

### 自己定义标签简单介绍

自己定义标签主要用于移除JSP页面中的Java代码。提高代码的复用性

使用自己定义标签移除jsp页面在奇偶那个的Java代码。仅仅须要完毕下面步骤:

* 编写一个实现Tag接口的Java类(标签处理器)
* 编写标签库描写叙述符(tld)文件,在tld文件里对标签处理器类描写叙述成一个标签
* 參考Tomcat中example项目中的JSP部分

由于企业业务需求是多种多样的。所以常见开源框架仅仅能提供通用的Java代码功能。假设实现既定业务逻辑功能,须要自己定义标签。通过自己定义标签(简化复杂业务开发)

### 简单标签

因为传统标签使用三个标签接口来完毕不同的功能,显得过于繁琐,不利于标签技术的推广,SUN公司为减少标签技术的学习难度,在JSP2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。

实现SimpleTag接口的标签通常称为简单标签。

SimpleTag方法介绍

* **setJspContext**方法:用于把JSP页面的pageContext对象传递给标签处理器对象。
* **setParent**方法:用于把父标签处理器对象传递给当前标签处理器对象。
* **getParent**方法:用于获得当前标签的父标签处理对象。
* **setJspBody**方法:用于把代表标签体的JspFragment对象传递给标签处理器对象。即传入标签体缓存对象(封装了标签体内容)
* **doTag**方法:用于完后全部标签逻辑,包含输出、迭代、改动标签体内容等。 在doTag方法中能够抛出javax.servlet.jsp.SkipPageException异常。用于通知WEB容器不再运行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

简单标签库开发经常使用功能,实现SimpleTag接口标签类(SimpleTag JSP2.0 之后为了简化标签开发提供的)

编写简单的标签类,仅仅须要继承SimpleTagSupport类

setJspContext 传入pageContext对象

setParent 传入父标签对象

setJSPBody 传入标签体缓存对象(封装了标签体内容)

doTag (运行标签。在该方法中编写标签代码逻辑)

在setJSPBody方法中传入对象JSPFragment。该对象封装了标签体内容。控制标签体内容输出

最重要方法invoke(Writer out) 意义将标签体内容输出到指定字符输出流中。

注意:在简单标签库中

### SimpleTag接口方法的运行顺序:

当web容器開始运行标签时,会调用例如以下方法完毕标签的初始化:

* WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
* WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,仅仅有在标签存在父标签的情况下。WEB容器才会调用这种方法。
* 假设调用标签时设置了属性,容器将调用每一个属性相应的setter方法把属性值传递给标签处理器对象。 假设标签的属性值是EL表达式。则WEB容器首先计算表达式的值。然后把值传递给标签处理器对象。
* 假设简单标签有标签体。容器将调用setJSPBody方法把代表标签体的JspFragment对象传递进来。

运行标签时:

* 容器调用标签处理器的doTag() 方法,开发者在方法内通过操作JspFragment对象。就能够实现是否运行、迭代、改动标签体的目的。

### JSPFragment类

(1)javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定义的。它的实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段。这段JSP片段中不能包括JSP脚本元素。

(2)WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJSPBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中仅仅定义了两个方法,例如以下所看到的:

getJspContext方法:用于返回代表调用页面的JspContext对象——pageContext

public abstract void invoke(java.io.Writer out) 输出标签内容

用于运行JspFragment对象所代表的JSP代码片段

參数out用于指定将JspFragment对象的运行结果写入到哪个输出流对象中,假设传递给參数out的值为null。则 将运行结果写入到JspContext.getOut()方法返回的输出流对象中。(简而言之,能够理解为写给浏览器)

### invoke方法具体解释

JspFragment.invoke方法是JspFragment最重要的方法。利用这种方法能够控制是否运行和输出标签体的内容、是否迭代运行标签体的内容或对标签体的运行结果进行改动后再输出。

比如:

* 在标签处理器中假设没有调用JspFragment.invoke方法,其结果就相当于忽略标签体内容。
* 在标签体处理器中反复调用JspFragment.invoke方法。则标签体内容会被反复运行;
* 若想在标签处理器中改动标签体内容。仅仅需在调用invoke方法时指定一个可取出结果数据的输出流对象(比如:StringWriter)。让标签体的运行结果输出到该输出流对象中。然后从该输出流对象中取出数据进行改动后在输出到目标设备。就可以达到改动标签体的目的。

例:控制标签后的jsp页面是否运行

doTag

throw new SkipPageException

TLD配置

### 自己定义标签入门

需求:自己定义标签

步骤一:编写标签类

编写一个类,继承SimpleTagSupport

重写两个方法,doTag()和setJspContext(JspContext pc)

通过JspContext 对象能够获取out对象向外输出内容

步骤二:提供tld文件进行配置

通过标签配置自己定义标签

配置标签名称

配置标签的类

配置标签体的内容

步骤三:在JSP页面中引入该标签库

### 自己定义带有标签体的标签

需求:自己定义标签

步骤一:编写标签类

编写一个类,继承SimpleTagSupport

重写两个方法。doTag()和setJspContext(JspContext pc)

在doTag()中通过getJspBody()获取JspFragment标签体,调用invoke(null)

步骤二:提供tld文件进行配置

通过标签配置自己定义标签

配置标签名称

配置标签的类

配置标签体的内容

步骤三:在JSP的页面中引入该标签库

### Body-content的配置

* empty:不能有标签体内容
* JSP:标签体内容能够是不论什么东西:EL、JSTL、
* scriptless:标签体内容不能是Java代码段,但能够是EL、JSTL等。
* tagdependent:标签体内容不做运算。由标签处理类自行处理,不管标签体内容是EL、JSP、JSTL,都不会做运算。

### 自己定义带有属性的标签

需求:自己定义标签

步骤一:编写标签类
编写一个类,继承SimpleTagSupport类。

提供页面的属性,设置成boolean类型。

并提供set方法。页面的属性与类中的属性名称必须同样。

重写doTag()方法,推断属性是否为true。通过getJspBody()获取JspFragment标签体。调用invoke(null)

步骤二:提供tld文件进行配置

通过

配置标签名称

配置标签的类

配置标签体的内容
配置属性

步骤三:在JSP页面中引入标签库

attribute的配置

(1)配置属性名称

(2)属性是否是必须的

(3)配置是否支持EL表达式

(4)配置属性的类型

### 在TLD中描写叙述标签属性attribute

元素名是否必须指定描写叙述description 否用于指定属性的描写叙述信息name 是用于指定属性的名称。属性名称是大写和小写敏感的,而且不能以jsp、
_jsp、java和sun开头required 否用于指定在JSP页面中调用自己定义标签时是否必须设置这个属性。


取值包含true和false。默认值是false。true表示必须设置。否则能够
设置也能够不设置该属性。
rtexprvalue 否rtexprvalue是runtime expression value(执行时表达式)的英文简写,
用于指定属性值是一个静态值或动态值。其取值包含true和false,默认值
是false。false表示仅仅能为该属性指定静态文本值,比如”123″; true表示可
以为该属性指定一个JSP动态元素,动态元素的结果作为属性值。比如
JSP表达式type 否用于指定属性值的Java类型。

默认是String

实比例如以下:

在WEB项目的src文件夹下新建cn.itcast.tag包。在包内新建三个标签实现类

TagDemo1.java (没有标签体的自己定义标签)

package cn.itcast.tag;

import java.io.IOException;

import javax.servlet.jsp.JspContext;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * 对外输出Hello
 * @author Administrator
 *
 */
public class TagDemo1 extends SimpleTagSupport{

    private PageContext pc;

    public void doTag() throws JspException, IOException {
        pc.getOut().write("Hello");
    }

    /**
     * server默认先运行该方法
     */
    public void setJspContext(JspContext pc) {
        this.pc = (PageContext) pc;
    }

}

TagDemo2.java (有标签体 处理标签体内容)

package cn.itcast.tag;

import java.io.IOException;
import java.io.StringWriter;

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.SimpleTagSupport;

/**
 * 带有标签主体
 * @author Administrator
 *
 */
public class TagDemo2 extends SimpleTagSupport{

    private PageContext pc;

    public void doTag() throws JspException, IOException {
        JspFragment jf = getJspBody();
        StringWriter sw = new StringWriter();
        //通过invoke方法将标签体内容写入到參数Writer对象sw中
        jf.invoke(sw);
        // 获取标签体内容
        String content = sw.toString().toUpperCase();
        pc.getOut().print(content);
    }

    public void setJspContext(JspContext pc) {
        this.pc = (PageContext)pc;
    }
}

TagDemo3.java (有属性 有标签体的自己定义标签)

package cn.itcast.tag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * 相似标签,带有属性的
 * @author Administrator
 *
 */
public class TagDemo3 extends SimpleTagSupport{

    private boolean test;

    public void setTest(boolean test) {
        this.test = test;
    }

    public void doTag() throws JspException, IOException {
        if(test){
            getJspBody().invoke(null);
        }
    }

}

在WebRoot/WEB-INF 文件夹下新建myc.tld文件

配置内容例如以下:

1.0
 myc
 http://www.itcast.cn/1110/myc

    print

    cn.itcast.tag.TagDemo1

    empty

    out

    cn.itcast.tag.TagDemo2

    scriptless

    if

    cn.itcast.tag.TagDemo3

    scriptless

        test

        true

        true

        boolean

在WebRoot下新建tag目录。新建tag.jsp 測试自己定义标签内容

Insert title here

    liuxun1993

    美美

启动server。执行结果例如以下:

> Original: https://www.cnblogs.com/clnchanpin/p/7400516.html
> Author: clnchanpin
> Title: JAVAWEB开发之JSTL标签库的使用、 自己定义EL函数、自己定义标签(带属性的、带标签体的)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/537899/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • java高并发,如何解决,什么方式解决

    案例一: 订票系统案例,某航班只有一张机票,假定有1w个人打开你的网站来订票,问你如何解决并发问题(可扩展到任何高并发网站要考虑 的并发读写问题) 问题,1w个人来访问,票没出去前…

    Java 2023年5月29日
    058
  • Bean 字段复制利器 MapStruct

    本文聊一个工具类,MapStruct ,它是一个在 dto,po(do/entity),vo 等这些 pojo 中转换字段的一个工具,在应用中经常有这样的转换,在 spring 和…

    Java 2023年6月5日
    0119
  • 2018年最新JAVA面试题总结之JavaWeb(2)

    转自于:https://zhuanlan.zhihu.com/p/39522575 1、tomcat的优化方式?回答:Tomcat的优化我准备从三方面来说: 第一部分: 内存优化T…

    Java 2023年6月13日
    076
  • JAVA入门基础_从零开始的培训_JAVA中的正则表达式、处理文本的利器(五)

    正则表达式 基本语法 源码解析(基于上述代码) Matcher.find()方法 Matcher.group(int group)方法 二个常用类 Pattern(相当于一个正则表…

    Java 2023年6月9日
    081
  • SpringBoot2.3.12.RELEASE优雅的全局异常处理(模板一)

    参考:https://www.cnblogs.com/xuwujing/p/10933082.html 1、首先,需要引入maven依赖包,如下所示: 1 "1.0&qu…

    Java 2023年5月30日
    082
  • 七、注释、标识符、数据类型与类型转换

    书写注释是一个好习惯 public class Comment { public static void main(String[] args) { //&#x5355;&…

    Java 2023年6月5日
    073
  • 自己实现 aop 和 spring aop

    代理类肯定要为用户做一些事情,不可能像学设计模式的时候创建个代理类,然后简单的在前面打印一句话,后面打印一句话,这叫啥事啊,难怪当时听不懂。最好是这个方法的前后过程可以自户自己定义…

    Java 2023年6月5日
    082
  • 使用idea操作git(ssh协议)

    问题 我们发现,使用IDEA上的git功能,当使用ssh协议出现了可以commit但无法push和pull的问题,经过测试发现原因是Could not read from rems…

    Java 2023年6月15日
    092
  • Android照相机应用

    Android在设计架构的时候,采用了mashup(混搭)的设计理念,也就是说一切都是组建,自己写的是组件,别人提供的也是组件,使用的时候只要符合相关协议就可以把他们当作自己的组件…

    Java 2023年6月7日
    079
  • centos yum安装ffmpeg

    一、安装前都需要先安装epel扩展源 yum -y install epel-release 二、对于6,安装yum源之后直接安装即可: su -c ‘yum loca…

    Java 2023年6月8日
    089
  • 1_day01_操作系统安装

    操作系统安装 内容介绍 1.制作U盘启动器 2.备份驱动 3.安装操作系统 4.驱动更新 5.依赖库检测 6.系统漏洞修复 7.系统布局优化 一、制作U盘启动器 1.1 下载老毛桃…

    Java 2023年6月8日
    078
  • Java异常

    1.异常引入 package exception; @SuppressWarnings({"all"}) /** * @Author Blueshadow * …

    Java 2023年6月8日
    078
  • svg–动画-进度条

    html;gutter:true; Document</p> <pre><code>.container { border: 1px solid…

    Java 2023年5月29日
    056
  • Java浮点数float,bigdecimal和double精确计算的精度误差问题总结

    1、float整数计算误差 案例:会员积分字段采用float类型,导致计算会员积分时,7位整数的数据计算结果出现误差。 原因:超出float精度范围,无法精确计算。 float和d…

    Java 2023年5月29日
    084
  • Spring Cloud Gateway 内置的过滤器工厂

    内置的过滤器工厂 这里简单将Spring Cloud Gateway内置的所有过滤器工厂整理成了一张表格。如下: 每个过滤器工厂都对应一个实现类,并且这些类的名称必须以Gatewa…

    Java 2023年5月30日
    087
  • Java开发笔记(一百三十七)JavaFX的标签

    前面介绍了JavaFX的窗口框架,其中舞台、场景、窗格都能与AWT/Swing体系的相关概念一一对应,不仅如此,JavaFX的常见控件也能在Swing中找到相应的控件。比如Java…

    Java 2023年6月6日
    083
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球