`
cxshun
  • 浏览: 724557 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

JSP自定义标签小结

 
阅读更多

已经好久没有写博客了,这段时间看过很多书,包括《浪潮之巅》(好书,推荐大家看看),《暗时间》(也很不错,刘末鹏讲时间管理的),还有断断续续研究了IOC和spring的实现代码,这部分收获不大,单纯的为了看代码而看代码,现在打算学习设计模式后再来深入。这段时间,在看martin的《企业应用模式》,这是本好书,但翻译看着感觉怪怪的,好多名词怪怪的。但买了就要学习一下,基本看下还是可以的。

今天来重新学习一下基本的东西。很久以前就学习过JSP自定义标签,JSTL更是经常使用,但说到写一个自定义标签,如果没有重新看一下,倒真不知道如何下手。相信很多朋友有同样的感觉,看过的东西,没用一段时间很快就忘记了,特别是技术方面的。究其原因,还是我们没能深入了解它的本质,没有深入理解。

我们一起来看一下。

首先我们必须知道一个标签可以包含什么东西:拿一个JSTL核心标签来看一下:

<c:forEach var="item" items="${items}">
    XXXX
</c:forEach>

    我们看到,一个标签可以包含属性,这个可以随便,自己定个数,也可以有标签体,当然这个标签体又可以是另外一个标签,如此类推。

那究竟怎么来实现呢?首先我们可以看看JAVA EE中的Tag相应的层级结构。

 

 

我们可以看到基本的接口是JspTag,当然我们没必要去实现这个接口,因为JAVA EE已经帮我们实现了一部分,如果

我们不需要标签体,我们可以简单地继续TagSupport,而如果我们需要标签体,我们可以直接继承BodyTagSupport。这

个在我们之后的例子可以看到。(我们只看有标签体的例子,没有标签体的大家可以自己试下,很简单)。

那么基本的信息,我们知道了,是时候开始代码了。建项目这些就不废话了。

自定义标签包括如下几个步骤:

1)自定义标签处理类(即我们刚才说的继承TagSupport或BodyTagSupport,或者在新的JSP2里面的SimpleTag)。

2)一个标签描述文件,tld,这个我们可以通过打JAR包或者直接放在META—INF文件夹下,容器会自动进行搜索。

3)在web.xml中进行配置jsp-config进行配置taglib-uri及taglig-location。

4)在JSP页面上用taglib命令引用,然后就可以使用了。

 

看起来很简单,对吧。实际上也就那么回事。开始我们的代码。

1)首先来自定义标签处理类:

我这里写了一个进行循环输出的,这里我暂时处理 的是String类型,其他类型的大致相同。

package com.shun.customtag;

import java.io.IOException;
import java.util.Collection;
import java.util.Iterator;

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

public class IteratorTag extends BodyTagSupport{

	private static final long serialVersionUID = 1L;

	private Iterator<String> it;
	private String name;//这里name作为循环的变量名称,相当于forEach中的var
	
	public void setName(String name) {
		this.name = name;
	}
	
	public void setItems(Collection<String> items){
		if(items.size() > 0) {
			it = items.iterator();
		}
	}
	
	public int doAfterBody() throws JspException {
		return iterateItems();
	}

	public int doEndTag() throws JspException {
		//这里必须把body里面的内容输出,否则标签内的内容会为空
		if (bodyContent != null) {
			try {
				bodyContent.writeOut(bodyContent.getEnclosingWriter());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return EVAL_PAGE;
	}

	public int doStartTag() throws JspException {
		if (it == null) {
			return SKIP_BODY;
		} else {
			return iterateItems();
		}
	}
	
	/**
	 * 这里进行遍历传入的items对象
	 * @return
	 */
	private int iterateItems(){
		//如果还存在值,则把它放入pageContext,即当前页面下,以便我们可以在body中进行取出
		if (it.hasNext()) {
			pageContext.setAttribute(name, it.next());
			return EVAL_BODY_AGAIN;
		} 
		return EVAL_PAGE;
	}

}

  看到这里,也许有些人有疑问,怎么来确定返回的是EVAL_啥呢?

这个基本上是下面的情况:

doStartTag(标签处理开始,即遇到开始标签时)一般返回EVAL_BODY_INCLUDE或者SKIP_BODY

doEndTag(标签处理结束,即遇到结束标签时)一般返回EVAL_PAGE或者SKIP_PAGE。

doAfterBody(标签体处理完成后)一般可以返回EVAL_BODY_AGAIN或者EVAL_BODY_BUFFER(这个是JSP2新的,JSTL1.1是没有的)或者EVAL_PAGE

应该很容易想明白,在开始标签处理完后,就要考虑标签体的处理,那么EVAL_BODY_INCLUDE或者SKIP_BODY就很自然了,在结束后就开始考虑剩余的页面处理,那么返回SKIP_PAGE或者EVAL_PAGE也很有道理,而doAfterBody就是在标签体处理完成后要干什么,可以继续处理页面EVAL_PAGE,或者重新处理标签体(这个以前用的是EVAL_BODY_TAG,但这个已经在JAVA EE6中被抛弃了)。

 

代码基本上没啥问题的。可能很多人会说,那个bodyContent是干啥用的。这个实际上可以把它看成一个内容的缓冲器,它把我们所有标签体中的内容进行缓冲,当我们调用writeOut时,才进行写出。

 

2)标签处理类有了,那么接着就来标签描述文件了。

<?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 web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    
    <short-name>myTag</short-name>
    <uri>http://com.shun/myTag</uri>
    <tag>
    	<name>iterator</name>
    	<tag-class>com.shun.customtag.IteratorTag</tag-class>
    	<body-content>JSP</body-content>
    	<attribute>
    		<name>items</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    	<attribute>
    		<name>name</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    </tag>
</taglib>

  这里也是简单得很,但有几个地方要注意:

(1)这里的URI和我们稍后配置的在web.xml中的taglib-uri需要一致,容器就是靠这个URI来查找标签库的。

(2)rtexprvalue为true表明了指定的属性可以用EL表达式或其他的JSTL标签等。

 

3)写完之后就来配置web.xml了:

简单的一段配置就OK了。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  
  <jsp-config>
  	<taglib>
  		<taglib-uri>http://com.shun/myTag</taglib-uri>
  		<taglib-location>/META-INF/myTag.tld</taglib-location>
  	</taglib>
  </jsp-config>
</web-app>

  这里taglib-uri在上面已经强调过,需要和引用的tld中的URI一致。

 

4)接下来我们就可以直接使用了:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<%@ taglib uri="http://com.shun/myTag" prefix="myTag" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		List<String> items = new ArrayList<String>();
		items.add("test1");
		items.add("test2");
		items.add("test3");
		request.setAttribute("items",items);
	%>
	<myTag:iterator items="${items }" name="item">
		${item }
	</myTag:iterator>
</body>
</html>

  这里我们构造了一个List,然后让它循环输出,很简单。

当我们进行访问时,可以看到:

  这样表明我们的标签运行正常,这样就搞定了我们的自定义标签开发了。当然,当我们项目需要用到时,肯定不会这么简单的,这里只是抛砖引玉,大家可以深入研究。

  • 大小: 3.2 KB
  • 大小: 3.5 KB
  • 大小: 33.1 KB
分享到:
评论

相关推荐

    jsp自定义简单标签

    ### 小结 通过上述步骤,我们成功地创建了一个简单的自定义标签 `helloTag` 并在 JSP 页面中使用了它。这种自定义标签的方式不仅提高了代码的复用性,还使得 JSP 页面更加简洁和易于理解。在实际项目开发中,合理...

    jsp自定义标签

    ### jsp自定义标签知识点详解 #### 一、自定义标签概述 在JavaServer Pages (JSP) 技术中,自定义标签是一种强大的功能,它允许开发者创建可重用的代码片段,并以类似HTML标签的方式在JSP页面中使用。这种机制极大...

    JSP taglib 精讲

    5. **仅有的三个数据导向的JSP操作**:在JSP中,只有`&lt;jsp:useBean&gt;`、`&lt;jsp:setProperty&gt;`和`&lt;jsp:getProperty&gt;`这三个动作标签与数据处理相关,自定义标签可以大大扩展这一范围,提供更多灵活的数据处理方式。...

    jsp弹出窗口--jsp小结

    通过增加窗口特征字符串,我们可以自定义弹出窗口的样式和行为。例如: ```html &lt;!-- window.open ('page.html', 'newwindow', 'height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, ...

    jsp实验报告4-servlet.zip

    6. JSP标签库:`&lt;c:forEach&gt;`和`&lt;c:out&gt;`的使用。 7. EL(Expression Language)的运用。 通过这个实验,学生可以深入理解Web应用程序的工作原理,以及JSP和Servlet如何协作处理用户请求和展示结果。这对于理解Web...

    JSP基本语法总结(1)---(12)

    - **`&lt;%@ taglib ... %&gt;`**:引入自定义标签库,指定URI和别名。 ### 4. JSP脚本元素 - **`&lt;%-- ... --%&gt;`**:JSP注释,服务器端不会执行。 - **`! ... %&gt;`**:声明区,用于声明变量和方法,相当于Java类的一部分...

    关于jsp知识的 汇总

    JSP 的主要特点之一是其能够在服务器端执行 Java 代码片段,并且能够通过 JSP 自定义标签库来简化 HTML 和 XML 的使用。此外,JSP 还提供了一套标准的 HTML 和 XML 标签用于简化页面开发过程。JSP 标签库提供了一...

    jsp开发程序教程2

    5. **本章小结**: 学习JSP的基础知识,包括理解JSP的运行环境,掌握JDK和Tomcat的安装配置,选择合适的开发工具,以及如何编写和运行第一个JSP程序,这些都是成为一名合格的JSP开发者的基础。 在实际开发中,了解...

    JSP页面简介

    - **Taglib指令**:用于引入自定义标签库。 #### 脚本元素 脚本元素允许在JSP页面中嵌入Java代码,包括: - **声明**:`! %&gt;`,用于声明变量或方法,这些变量和方法在整个JSP页面中都可见。 - **Java程序段**:`...

    深入浅出Struts2(附源码)

    1.4 小结 13 第2章初识Struts 14 2.1 Struts的优点 14 2.2 Struts的动作处理流程 15 2.3 拦截器 17 2.4 Struts配置文件 18 2.4.1 struts.xml文件 19 2.4.2 struts.properties文件 26 2.5 Struts应用程序示例...

    jsp速成课件

    ##### 2.4 JSP语法小结 通过这些基本语法,开发者可以灵活地控制页面内容的生成逻辑,同时保持良好的可维护性和可读性。 #### 三、JSP内置对象 JSP 提供了一系列内置对象,简化了开发过程中的常见任务: - **...

    struts资料\前半阶段小结

    5. **JSP标签库**:Struts提供了一系列自定义JSP标签,如`&lt;s:form&gt;`, `&lt;s:textfield&gt;`等,简化视图层的开发,提高可读性和可维护性。 6. **Struts ActionServlet**:这是Struts的核心控制器,负责解析请求、调用...

    关于JSP基本语法的下篇

    - **Taglib指令**:用于指定自定义标签库的位置。 本文主要关注的是`Include`指令,因为它涉及到页面的重用和模块化设计。 #### 掌握JSP的九个内置对象 JSP提供了九个内置对象,它们为开发者提供了丰富的功能支持...

    深入浅出Struts 2 .pdf(原书扫描版) part 1

    1.4 小结 13 第2章 初识Struts 14 2.1 Struts的优点 14 2.2 Struts的动作处理流程 15 2.3 拦截器 17 2.4 Struts配置文件 18 2.4.1 struts.xml文件 19 2.4.2 struts.properties文件 26 2.5 Struts应用程序示例 26 ...

    Struts2 in action中文版

    第一部分 Strut 2:一个全新的框架 第1章 Struts 2:现代Web框架 2 1.1 Web应用程序:快速学习 2 1.1.1 构建Web应用程序 2 1.1.2 基础技术简介 3 1.1.3 深入研究 6 1.2 Web应用程序框架 7 ...15.7 小结 332

    Grails 技术精解与Web开发实践【源码+样章】----下载不扣分,回帖加1分,欢迎下载,童叟无欺

    14.2.2 开发自定义标签 179 14.3 Grails对Ajax的支持 182 14.4 本章小结 184 第15章 实现Web Service 185 15.1 REST风格的Web Service 185 15.1.1 什么是REST 185 15.1.2 在Grails中实现REST 185 15.1.3 在Client端...

Global site tag (gtag.js) - Google Analytics