自定义标签主要用于移除Jsp页面中的java代码。

使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤:

  • 编写一个实现Tag接口的Java类(标签处理器类)。
  • 编写标签库描述符(tld)文件,在tld文件中对标签处理器类进行描述。

快速入门:使用标签输出客户机IP。
1、编写一个实现tag接口的标签处理器类

public class ViewIPTag implements Tag {private PageContext pageContext;public int doStartTag() throws JspException {HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();JspWriter out = pageContext.getOut();String ip = request.getRemoteAddr();try {out.write(ip);} catch (IOException e) {throw new RuntimeException(e);}return 0;}public int doEndTag() throws JspException {return 0;}public Tag getParent() {return null;}public void release() {}public void setPageContext(PageContext arg0) {this.pageContext = arg0;}public void setParent(Tag arg0) {}
}

2、在web-inf/目录下新建tld文件,在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>A tag library exercising SimpleTag handlers.</description><tlib-version>1.0</tlib-version><short-name>SimpleTagLibrary</short-name><uri>/itcast</uri><tag><name>viewIP</name>  <!-- 为标签处理器类配一个标签名 --><tag-class>cn.itcast.web.tag.ViewIPTag</tag-class><body-content>empty</body-content></tag></taglib>

3、在jsp页面中导入并使用自定义标签

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/itcast" prefix="itcast" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><title>输出客户机的IP</title></head><body>您的IP是:<itcast:viewIP/></body>
</html>

传统标签

传统标签执行流程

JSP引擎将遇到自定义标签时,首先创建标签处理器类的实例对象,然后按照JSP规范定义的通信规则依次调用它的方法。

Tag接口的执行流程:

  1. public void setPageContext(PageContext pc), JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。
  2. public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。
  3. public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
  4. public int doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。
  5. public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。

自定义标签功能扩展:

  • 开发人员在编写Jsp页面时,经常还需要在页面中引入一些逻辑,例如:

    • 控制jsp页面某一部分内容是否执行。
    • 控制整个jsp页面是否执行。
    • 控制jsp页面内容重复执行。
    • 修改j页面内容输出。
  • 自定义标签除了可以移除jsp页面java代码外,它也可以实现以上功能。

  • tld文件中的四种标签体类型
    EMPTY JSP scriptless tagdepentend

左边圈起来的部分是JSP2.0之前所用的,称为传统标签,现在一般使用的是右边圈起来的部分SimpleTag接口和实现类创建自定义标签。

简单标签

  • 由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法:

setJspContext方法:用于把JSP页面的pageContext对象传递给标签处理器对象
setParent方法:用于把父标签处理器对象传递给当前标签处理器对象
getParent方法:用于获得当前标签的父标签处理器对象
setJspBody方法:用于把代表标签体的JspFragment对象传递给标签处理器对象
doTag方法:用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回Tag.SKIP_PAGE常量的情况。

SimpleTag接口方法的执行顺序

  1. 当web容器开始执行标签时,会调用如下方法完成标签的初始化

    • WEB容器调用标签处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给标签处理器对象。
    • WEB容器调用标签处理器对象的setParent方法,将父标签处理器对象传递给这个标签处理器对象。注意,只有在标签存在父标签的情况下,WEB容器才会调用这个方法。
    • 如果调用标签时设置了属性,容器将调用每个属性对应的setter方法把属性值传递给标签处理器对象。如果标签的属性值是EL表达式或脚本表达式,则WEB容器首先计算表达式的值,然后把值传递给标签处理器对象。
    • 如果简单标签有标签体,容器将调用setJspBody方法把代表标签体的JspFragment对象传递进来。
  2. 执行标签时:
    • 容器调用标签处理器的doTag()方法,开发人员在方法体内通过操作JspFragment对象,就可以实现是否执行、迭代、修改标签体的目的。

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

WEB容器在处理简单标签的标签体时,会把标签体内容用一个JspFragment对象表示,并调用标签处理器对象的setJspBody方法把JspFragment对象传递给标签处理器对象。JspFragment类中只定义了两个方法,如下所示:

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

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),让标签体的执行结果输出到该输出流对象中,然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改标签体的目的。

开发带属性的标签

  • 要想让一个自定义标签具有属性,通常需要完成两个任务:

    1. 在标签处理器中编写每个属性对应的setter方法
    2. 在TLD文件中描术标签的属性
  • 为自定义标签定义属性时,每个属性都必须按照JavaBean的属性命名方式,在标签处理器中定义属性名对应的setter方法,用来接收JSP页面调用自定义标签时传递进来的属性值。 例如属性url,在标签处理器类中就要定义相应的setUrl(String url)方法。

  • 在标签处理器中定义相应的set方法后,JSP引擎在解析执行开始标签前,也就是调用doStartTag方法前,会调用set属性方法,为标签设置属性。

在TLD中描述标签属性:

简单标签调用流程图

方立勋_30天掌握JavaWeb_自定义标签相关推荐

  1. 方立勋_30天掌握JavaWeb_自己编写jdbc框架、dbutils框架(未完)

    元数据:数据库.表.列的定义信息. Connection.getDatabaseMetaData() DataBaseMetaData对象 getURL():返回一个String类对象,代表数据库的U ...

  2. 方立勋_30天掌握JavaWeb_数据库表设计

    定义外键约束 丈夫.妻子表: 妻子用一个husband_id来说明wife丈夫是哪个. 一对多对象表设计 部门.员工表: 一个部门可以有多个员工,员工表通过department_id说明属于哪个部门. ...

  3. 方立勋_30天掌握JavaWeb_使用httpUrlConnection模似ie

    在手机应用开发常常需要用到. 模拟ie浏览器访问. import java.io.InputStream; import java.io.OutputStream; import java.net.H ...

  4. 方立勋_30天掌握JavaWeb_国际化开发

    国际化开发概述 软件的国际化:软件开发时,要使它能同时应对世界不同地区和国家的访问,并针对不同地区和国家的访问,提供相应的.符合来访者阅读习惯的页面或数据. 国际化又称为 i18n:internati ...

  5. 方立勋_30天掌握JavaWeb_(Servlet+JSP+JavaBean实现)用户注册和登陆

    JSP+JavaBean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务数据,JSP即负责处理用户请求,又显示数据. Servlet+JSP+JavaBean(M ...

  6. 方立勋_30天掌握JavaWeb_(JSP+JavaBean实现)简单计算器

    JSP+JavaBean模式适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务数据,JSP即负责处理用户请求,又显示数据. Servlet+JSP+JavaBean(M ...

  7. 方立勋_30天掌握JavaWeb_JSP

    JSP运行原理 JSP全称是Java Server Pages,它和servle技术一样,都是SUN公司定义的一种用于开发动态web资源的技术. JSP这门技术的最大的特点在于,写jsp就像在写htm ...

  8. 方立勋_30天掌握JavaWeb_request

    request常用方法 import java.io.IOException; import javax.servlet.ServletException; import javax.servlet. ...

  9. 方立勋_30天掌握JavaWeb_Servlet Filter(过滤器)未完

    Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片 ...

最新文章

  1. centos中的mysql安装配置,Linux下安装配置MySQL
  2. 拉文大学计算机科学,拉文大学
  3. JavaOne 2012覆盖率
  4. nuxt.js 配置后端的请求地址
  5. 富士 FinePix F401
  6. Hive的数据加载与导出
  7. python安装api_Python API文档
  8. 【毕业答辩】你的论文答辩PPT准备好了吗?
  9. 【java学习之路】(java SE篇)002.java SE基础语法
  10. 不得不爱开源 Wijmo jQuery 插件集(13)-【Tooltip】(附页面展示和源码)
  11. Hangman Judge UVA - 489
  12. Swift 面向协议编程入门
  13. 高通modem启动过程_使用QXDM收集高通modem日志
  14. 智能门锁主要有哪些优势,具体是怎么分类的?
  15. php教师评价系统,正韵教学评价系统 v3.2
  16. Leetcode刷题之旅--剑指 Offer 17. 打印从1到最大的n位数
  17. 什么是软件测试吞吐量,在软件测试中吞吐量与TPS有什么区别与联系
  18. Ubuntu 20.04 物理机安装
  19. Snapde和Excel、PowerPivot、WPS打开超大CSV文件性能比较
  20. 双 JK 触发器 74LS112 逻辑功能。真值表_数字电路学习笔记(十一):时序逻辑...

热门文章

  1. orcale的rank(排名函数)实例
  2. WinForm窗体拖动代码
  3. safari的调试工具
  4. cocos2d-x 中文 乱码问题
  5. 解决ORACLE被锁定的资源两法
  6. Cannot resolve field [content], input field list:[contents].
  7. 决策树(CART算法)针对中文文本分类
  8. Opengl :公转与自转
  9. armadillo 配置
  10. python matplotlib:figure,add_subplot,subplot,subplots讲解实现