从几个简单的需求来讲解一下如何自定义 JSTL 标签:
需求:
- 使用一个单标签
<qjl:hello />
在控制台输出hello world
- 通过一个单标签
<qjl:path />
在页面输出当前 web 应用的上下文路径 - 使用一个单标签
<qjl:set var="" value="" scope="" />
向四大域中设置属性值
一、在控制台打印hello:
自定义一个单标签 <qjl:hello />
,调用该标签的时候在控制台打印一句 hello。
-
新建一个 web 项目
-
引入 jstl1.2 的 ja r包(注意这里是 1.2 )
-
创建一个类实现 SimpleTag 接口
-
因为这个接口已经有实现类 SimpleTagSupport ,所以我们只需要继承这个 SimpleTagSupport 即可
-
重写 doTag 方法
package com.lyu.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; /** * 类描述:用来输出Hello的tag标签处理类 * 类名称:com.lyu.tag.HelloTag * @author 曲健磊 * 2018年5月14日.下午11:25:45 * @version V1.0 */ public class HelloTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { System.out.println("hello"); } }
-
在 WEB-INF 里面创建一个
hello.tld
文件(名称随意)
-
tld 文件的格式可以参考 jstl 的 jar 包中的 tld 文件格式。
<?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <!-- 描述 --> <description>QJL 1.2 core library</description> <!-- 显示名称 --> <display-name>QJL core</display-name> <!-- 版本信息 --> <tlib-version>1.2</tlib-version> <!-- 建议使用的标签的前缀 --> <short-name>qjl</short-name> <!-- 标签的uri --> <uri>http://java.sun.com/qjl/core</uri> <tag> <!-- 标签名称 --> <name>hello</name> <!-- 标签处理类的全限定性类名 --> <tag-class>com.lyu.tag.HelloTag</tag-class> <!-- 标签的内容:为空就表示是一个单标签,标签里面没有内容 --> <body-content>empty</body-content> </tag> </taglib>
注:这个 tld 文件中有几个重要的标签(short-name, uri, tag)
-
short-name 用来定义当前定义的一系列标签的前缀,在页面上引入的时候可以这样写:
<%@ taglib uri="http://java.sun.com/qjl/core" prefix="qjl" %>
-
uri 其实是个虚的路径映射,并不是访问互联网上的某个网址(lz 一开始就以为引入 jstl 就要访问网页…),在 tld 文件中的 uri 标签上写什么,在页面上引入的时候就在 uri 属性上写什么,容器就会自动去 tld 文件中找该 uri 对应的标签了。
-
tag 标签就是用来配置我们上面写好的标签处理类 HelloTag ,name 是用来配置标签的名称,就拿上面的例子来说,页面上就可以这样定义该标签
<qjl:hello />
,tag-class 对应的标签处理类的全限定性类名,body-content 表示的是这个标签体的一些信息,emtpy 表示这是一个单标签(就是不成对出现,只单个出现,像 input 标签一样)。
-
-
在 jsp 页面中引入 刚才定义的标签:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!-- 引入刚才配置好的自定义标签 --> <%@ taglib uri="http://java.sun.com/qjl/core" prefix="qjl" %> <!doctype html> <html> <head> <meta http-equiv='Content-Type' content='text/html;charset=utf-8' /> <title>JSTL测试</title> </head> <body> <%-- 自定义一个标签 <qjl:hello /> 在控制台打印一句话 --%> <qjl:hello /> </body> </html>
-
运行服务器,请求这个页面,控制台打印如下:
**Question:**为什么写个 <qjl:hello />
标签就能在控制台打印了 hello 呢?
**Answer:**看一看刚才访问过的 jsp 页面被 jsp 引擎解析后的 java 源文件:
...
private boolean _jspx_meth_qjl_005fhello_005f0(javax.servlet.jsp.PageContext _jspx_page_context)
throws java.lang.Throwable {
javax.servlet.jsp.PageContext pageContext = _jspx_page_context;
javax.servlet.jsp.JspWriter out = _jspx_page_context.getOut();
// qjl:hello
// 这里是关键,创建了一个 HelloTag 对象
com.lyu.tag.HelloTag _jspx_th_qjl_005fhello_005f0 = new com.lyu.tag.HelloTag();
_jsp_getInstanceManager().newInstance(_jspx_th_qjl_005fhello_005f0);
try {
_jspx_th_qjl_005fhello_005f0.setJspContext(_jspx_page_context);
// 调用 doTag 方法
_jspx_th_qjl_005fhello_005f0.doTag</