天天看点

JavaWeb学习心得之自定义简单标签(二)

一、JspFragment类简介

        JspFragment实例对象代表JSP页面中的一段符合JSP语法规范的JSP片段,它不能包含JSP脚本元素。web容器在处理简单标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。其有两个方法:

  • getJspContext方法:用于返回代表调用页面的JspContext对象
  • invoke(writer out)方法:用于执行JapFragment对象所代表的JSP代码片段。out指定输出流对象,若为null,需要写入JspContext.getOut()方法返回的流对象。

       invoke方法时非常重要的方法,其作用如下:

  • 如果没有调用invoke方法,其结果就相当于忽略标签体内容
  • 如果重复调用invoke方法,则标签体内容将会被重复执行
  • 若invoke带流对象参数(StringWriter),我们可以从该流中取出数据进行修改,然后输出到浏览器,达到修改标签体的目的。

二、自定义带属性的标签 步骤:

  1. 在标签处理器中编写每个属性对应的setter方法(符合JavaBean属性命名)
  2. 在TLD文件中描述标签的属性

范例1:通过属性控制标签体执行次数 SimpleTag类

import java.io.IOException;

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

public class JSPDemo01 extends SimpleTagSupport{
	/*
	 *  定义标签的属性
	 */
	private int count;
	/*
	 * count属性对应的set方法
	 */
	public void setCount(int count) {
		this.count = count;
	}


	/*
	 * 简单标签使用这个方法就可以完成所有的业务逻辑,重写doTag方法
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 */
	@Override
	public void doTag() throws JspException, IOException {
		JspFragment fragment = this.getJspBody();
		for(int i=0;i<count;i++){
			fragment.invoke(null);
		}
	}
}
           

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用来添加对taglib(标签库)的描述 -->
    <description>简单标签库</description>
     <!--taglib(标签库)的版本号 -->
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLib</short-name>
       <!-- 
		        为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写 ,
		        在Jsp页面中引用标签库时,需要通过uri找到标签库
		        在Jsp页面中就要这样引入标签库:<%@taglib uri="/mySimpleTagLib" prefix="m"%>
		    -->
    <uri>/mySimpleTagLib</uri>
     <!--一个taglib(标签库)中包含多个自定义标签,每一个自定义标签使用一个tag标记来描述  -->
     <!-- 一个tag标记对应一个自定义标签 -->
    <tag>
    	<description>JSPDemo01</description>
    	<name>JSPDemo01</name>
    	 <!-- 标签对应的处理器类-->
    	<tag-class>com.hanxin.JSPDemo01</tag-class>
    	  <!-- 
		        tld文件中有四种标签体类型 :empty  JSP  scriptless  tagdepentend  
			            在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常
			            在传统标签中标签体body-content的值只允许是empty和JSP
			            如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的,
			            例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的
			            <gacl:sql>SELECT * FROM USER</gacl:sql>
			            在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可
	        -->
    	<body-content>scriptless</body-content>
    	<!-- 标签的属性描述 -->
    	<attribute>
    		<description>标签属性描述</description>
    		<!-- 属性名称 -->
    		<name>count</name>
    		<required>true</required>
    		<!-- rtexprvalue用来指示标签的属性值是否可以是一个表达式,
       		     一般设置为true,true就表示允许标签的属性值可以是一个表达式-->
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    </tag>
</taglib>
           

JSP文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" %>
<%@taglib uri="/mySimpleTagLib" prefix="m"%>
<!DOCTYPE html>
<html >
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>test</title>
</head>
<body>
<!-- 循环打印标签体10次 -->
<m:JSPDemo01 count="10">hello world<br></m:JSPDemo01>
</body>
</html>
           

       如果标签属性是8中基本数据类型,那么JSP在传递字符串时,JSP会自动转换成相应类型,但如果是复合类型,将无法转换。

范例:标签属性是一个复合类型 SimpleTag类

import java.io.IOException;
import java.util.Date;

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

public class JSPDemo02 extends SimpleTagSupport{
	/*
	 *  定义标签的属性
	 */
	private Date date;
	/*
	 * date属性对应的set方法
	 */
	public void setDate(Date date) {
		this.date = date;
	}

	/*
	 * 简单标签使用这个方法就可以完成所有的业务逻辑,重写doTag方法
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 */
	@Override
	public void doTag() throws JspException, IOException {
		JspFragment fragment = this.getJspBody();
		this.getJspContext().getOut().write(date.toString());
	}
}
           

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用来添加对taglib(标签库)的描述 -->
    <description>简单标签库</description>
     <!--taglib(标签库)的版本号 -->
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLib</short-name>
       <!-- 
		        为自定义标签库设置一个uri,uri以/开头,/后面的内容随便写 ,
		        在Jsp页面中引用标签库时,需要通过uri找到标签库
		        在Jsp页面中就要这样引入标签库:<%@taglib uri="/mySimpleTagLib" prefix="m"%>
		    -->
    <uri>/mySimpleTagLib</uri>
     <!--一个taglib(标签库)中包含多个自定义标签,每一个自定义标签使用一个tag标记来描述  -->
     <!-- 一个tag标记对应一个自定义标签 -->
    <tag>
    	<description>JSPDemo02</description>
    	<name>JSPDemo02</name>
    	 <!-- 标签对应的处理器类-->
    	<tag-class>com.hanxin.JSPDemo02</tag-class>
    	  <!-- 
		        tld文件中有四种标签体类型 :empty  JSP  scriptless  tagdepentend  
			            在简单标签(SampleTag)中标签体body-content的值只允许是empty和scriptless,不允许设置成JSP,如果设置成JSP就会出现异常
			            在传统标签中标签体body-content的值只允许是empty和JSP
			            如果标签体body-content的值设置成tagdepentend,那么就表示标签体里面的内容是给标签处理器类使用的,
			            例如:开发一个查询用户的sql标签,此时标签体重的SQL语句就是给SQL标签的标签处理器来使用的
			            <gacl:sql>SELECT * FROM USER</gacl:sql>
			            在这种情况下,sql标签的<body-content>就要设置成tagdepentend,tagdepentend用得比较少,了解一下即可
	        -->
    	<body-content>empty</body-content>
    	<!-- 标签的属性描述 -->
    	<attribute>
    		<description>标签属性描述</description>
    		<!-- 属性名称 -->
    		<name>date</name>
    		<required>true</required>
    		<!-- rtexprvalue用来指示标签的属性值是否可以是一个表达式,
       		     一般设置为true,true就表示允许标签的属性值可以是一个表达式-->
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    </tag>
</taglib>
           

jsp文件

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" 
	import="java.util.Date"%>

<%@taglib uri="/mySimpleTagLib" prefix="m"%>
<!DOCTYPE html>
<html >
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
    <title>test</title>
</head>
<body>
	<%
		Date date = new Date();
		request.setAttribute("date", date);
	%>
	<m:JSPDemo02 date="${date}"></m:JSPDemo02>
	<br>
	<m:JSPDemo02 date="<%=new Date() %>"></m:JSPDemo02>s
</body>
</html>
           

三、TLD文件中<attribute>元素说明 子元素说明

JavaWeb学习心得之自定义简单标签(二)

继续阅读