JSP标签编程 1

来源:互联网 发布:美国劳工统计局数据 编辑:程序博客网 时间:2024/05/19 16:20

JSP标签编程  1

    标签编程在实际开发之中,并不是很常见,就是说自己开发标签的情况基本上是不存在的,因为这个与开发的环境所限制,因为自己开发之后的标签基本上没有任何的通用性,所以在实际中基本上都是大量的使用已经开发好的标签,例如:之后讲解的JSTL或者是Struts 中都有标签

之所以在这类讲解标签的开发,注意目的是帮助大家建立一个完整的知识体系

本程序中的Scriptlet代码实在是太多了,肯定不方便修改及维护,但是很多时候一个jsp 页面又不能去避免的要使用的Scriptlet代码,因为JSP 需要输出,那么此时的之中矛盾就可以通过标签来完成。

定义一个简单的标签  ----- 空标签

要想实现一个标签,可以直接继承javax.servlet.jsp.tagext.TagSupport 类,如果要定义的标签内没有标签体,则直接覆写TagSupport类中的doStartTag() 方法即可


定义标签支持类: HelloTag.java

之前在开发Servlet的时候曾经配置过了一个Servlet 的开发包,但是现在的标签的支持类并不在servlet包之中。将tomcat lib目录下的jsp-api.jar拷贝进行配置

package com.demo;import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;public class HelloTag extends TagSupport {@Overridepublic int doStartTag() throws JspException {JspWriter out = super.pageContext.getOut();try {out.println("<h1>HelloWorld!!</h1>");} catch (Exception e) {// TODO: handle exception}return TagSupport.SKIP_BODY;  //不在执行标签}}

但是,只靠一个标签的支持类本身是无法完成全部功能的

下面还需要定义一个标签的描述文件,标签的描述文件的后缀“*.tld” ,而且此操作依然富豪xml

<?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"></taglib>

<%@ taglib prefix="mytag" uri="/WEB-INF/hellotag.tld"%>  表示引入标签库

javax.servlet.ServletException: java.lang.NoClassDefFoundError: javax/el/ELResolver


这个项目还有另一种情况 我编译的时候是把 jsp-api.jar  C:\jdk6.0\jre\lib\ext  删除后重新启动tomcat 但是java 类在生成classes的时候需要这个类  这是我用editplus 运行后的情况

以下是自定义开发的标签

package com.demo;import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;public class HelloTag extends TagSupport {@Overridepublic int doStartTag() throws JspException {JspWriter out = super.pageContext.getOut();try {out.println("<h1>HelloWorld!!</h1>");} catch (Exception e) {// TODO: handle exception}return TagSupport.SKIP_BODY;  //不在执行标签}}<?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_1.xsd"       version="2.1">      <tlib-version>1.0</tlib-version>         <short-name>firsttag</short-name>        <tag>                  <name>hello</name>                  <tag-class>com.demo.HelloTag</tag-class>      <body-content>empty</body-content>          </tag> </taglib><%@ page contentType="text/html; charset=GBK" %><%@ taglib prefix="mytag" uri="/WEB-INF/hellotag.tld"%><html>    <head>        <title>欢迎光临</title>    </head>        <body>            <h1><mytag:hello/></h1>   <!-- 访问标签 -->        </body></html> 

        此时,已经完成了输出功能,但是这些功能是直接由标签的支持类所完成的,而只有通过tld文件才可以使用这个标签的支持类,当然,在标签的开发中也可以将所有的标签库的描述文件直接在web.xml 文件之中进行配置

<jsp-config>        <taglib>            <taglib-uri>myhello</taglib-uri>            <taglib-location>/WEB-INF/hellotag.tld</taglib-location>        </taglib>    </jsp-config>
是在web.xml 文件组之中为tld 的文件走了一个映射,映射的名称就是myhello 。以后在JSP 页面中,就可以直接通过myhello进行访问了
<%@ page contentType="text/html; charset=GBK" %><%@ taglib prefix="mytag" uri="myhello"%><html>    <head>        <title>欢迎光临</title>    </head>        <body>            <h1><mytag:hello/></h1>   <!-- 访问标签 -->        </body></html>

       标签操作之中文件配置的非常多,需要标签的支持类,标签的描述文件,如果需要还可以在web.xml 文件之中配置,还需要在jsp中进行引入

本身非常麻烦

因为之前一直强调过, 在一个JSP文件之中,基本功能:判断、输出

小结:

标签可以简化JSP中的Scriptlet,但是从实际开发来讲,自定义标签库使用并不多

标签需要*.tld文件的支持,之后使用<%@taglib%>

————————————————————————————————————————————————————

本章目标

JSP标签编程 

    定义有属性的标签

本章目标

理解标签中熟悉的设置方法

理解标签配置文件中的属性定义格式

        上面已经清楚的知道了,对于一个标签的开发需要标签的支持了,标签库的描述文件、web.xml文件中进行配置、之后在JSP中进行使用

         但是对于属性:<jsp:forward page=""/>,  现在自己的标签也可以定义属性操作

         下面定义一个可以完成日期格式化显示的操作,希望用户可以输入自己的日期的格式化的模板,根据此模板最终完成标签

<jsp-config>        <taglib>            <taglib-uri>myhello</taglib-uri>            <taglib-location>/WEB-INF/hellotag.tld</taglib-location>        </taglib>    </jsp-config>
是在web.xml 文件组之中为tld 的文件走了一个映射,映射的名称就是myhello 。以后在JSP 页面中,就可以直接通过myhello进行访问了
<%@ page contentType="text/html; charset=GBK" %><%@ taglib prefix="mytag" uri="myhello"%><html>    <head>        <title>欢迎光临</title>    </head>        <body>            <h1><mytag:hello/></h1>   <!-- 访问标签 -->        </body></html>

       标签操作之中文件配置的非常多,需要标签的支持类,标签的描述文件,如果需要还可以在web.xml 文件之中配置,还需要在jsp中进行引入

本身非常麻烦

因为之前一直强调过, 在一个JSP文件之中,基本功能:判断、输出

小结:

标签可以简化JSP中的Scriptlet,但是从实际开发来讲,自定义标签库使用并不多

标签需要*.tld文件的支持,之后使用<%@taglib%>

———————————————————————————————————————————————————


本章目标

JSP标签编程
    定义有属性的标签
理解标签中熟悉的设置方法
理解标签配置文件中的属性定义格式
        上面已经清楚的知道了,对于一个标签的开发需要标签的支持了,标签库的描述文件、web.xml
文件中进行配置、之后在JSP中进行使用
         但是对于属性:<jsp:forward page=""/>,  现在自己的标签也可以定义属性操作
         下面定义一个可以完成日期格式化显示的操作,希望用户可以输入自己的日期的格式化的模板
,根据此模板最终完成标签

package com.demo.tag;import java.text.*;import java.util.*;import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;//处理日常日期格式化标签public class DateTag extends TagSupport {private String format;//标签的格式化操作public int doStartTag() throws JspException {SimpleDateFormat sdf = new SimpleDateFormat(this.format);//表示日期显示操作try{super.pageContext.getOut().write(sdf.format(new Date()));}catch (Exception e){e.printStackTrace();}return TagSupport.SKIP_BODY;  }public void setFormat(String format) {this.format = format;}public String getFormat() {return this.format;}}//    此时完成了标签的处理类操作,之后就需要缩写*.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_1.xsd"       version="2.1">      <tlib-version>1.0</tlib-version>         <short-name>firsttag</short-name>        <tag>                  <name>date</name>                  <tag-class>com.demo.tag.DateTag</tag-class>      <body-content>empty</body-content>          <attribute>        <name>format</name>  <!-- 属性名通过反射机制 -->        <required>true</required>  <!-- 此属性必须设置 -->        <rtexprvale>true</rtexprvale>  <!-- 支持表达式输出 -->      </attribute>      </tag> </taglib>下面为了方便的使用,直接在web.xml 文件之中定义此标签库        taglib>            <taglib-uri>date</taglib-uri>            <taglib-location>/WEB-INF/datetag.tld</taglib-location>        </taglib>下面开始在一个JSP 文件之中使用此标签操作<?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_1.xsd"       version="2.1">      <tlib-version>1.0</tlib-version>         <short-name>firsttag</short-name>        <tag>                  <name>date</name>                  <tag-class>com.demo.tag.DateTag</tag-class>      <body-content>empty</body-content>          <attribute>        <name>format</name>          <required>true</required>          <rtexprvale>true</rtexprvale>        </attribute>      </tag> </taglib>
          此处的format 就是一个标签操作中所需要的属性,而此属性操作时,必须要有相应的setter、getter方法进行接收


小结

标签中设置的属性依然使用反射机制调用setter方法完成

所以设置的属性要通过TLD文件进行定义

第十二章   JSP 标签编程    ———TagSupport 类

本章目标

掌握TagSupport类的作用

掌握TagSupport类的主要属性及方法

可以定义有标签体的标签

TagSupport 类

基本的标签掌握后,可以发现标签的实现都需要继承TagSupport这个类,所以TagSupport类是整个标签编程的一个核心类,此类的定义如下:

public class TagSupport
extends Object
implements IterationTag, Serializable

doStartTag()

此方法在标签开始的时候执行,此方法有两种返回值,分别是:

SKIP_BODY:  表示忽略标签体的内容,而将执行权转交给doEndTag() 方法

EVAL_BODY_INCLUDE: 表示执行标签体的内容

doAfterBody()

此方法是IterationTag接口与Tag接口的差别所在,本方法用来重复执行标签体的内容,有两种返回值,分别是:

SKIP_BODY: 表示标签体内容会被忽略,并且执行权转交给doEndTag() 方法

EVAL_BODY_AGAIN: 表示重复执行标签体的内容,会重复调用doAfterBody() 方法,一直循环执行下去,直到doAfterBody() 方法返回SKIP_BODY为止

doEndTag()

在标签结束时执行,此方法有两种返回值

SKIP_PAGE: 表示JSP页面应该立刻停止执行,并将所有的输出立刻回传到浏览器上;

EVAL_PAGE: 表示JSP可以正常的运行完毕

release()

将标签处理类所产生或是活得的资源全部释放,并等待用户下次继续使用

       首先标签定义完成之后将执行的doStartTag() 方法,之后判断此方法的返回值,如果是EVAL_BODY_INCLUDE 则表示要执行标签体(doAfterTag()) 如果返回的SKIP_BODY, 表示标签准备结束了

本程序的主要功能是完成一个判断的操作,判断在某一个属性范围之中,是否存在指定的属性名称,如果存在则进行输出

这个过程肯定要使用标签体的。

package com.demo;import java.io.*;import javax.servlet.*;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.*;public class AttributeTag  extends TagSupport{private String name;//接收属性的名称private String scope;//接收属性的范围@Overridepublic int doStartTag() throws JspException {  //判断属性是否存在Object value = null;if("page".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.PAGE_SCOPE);}if("request".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.REQUEST_SCOPE);}if("session".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.SESSION_SCOPE);}if("application".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.APPLICATION_SCOPE);}if(value == null) {  //表示现在根本没有此属性return TagSupport.SKIP_BODY;//没有属性不执行标签体} else {return TagSupport.EVAL_BODY_INCLUDE;  // 执行标签体}}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}}

           编辑完成之后下面依然需要定义一个*.tld的文件,用于标签库的描述操作

          现在的由于所有的标签都是由用户自己定义的,为了避免麻烦,以后在讲解的所有标签的开发中,所有的标签的定义操作,都直接在gztag.tld文件中描述了

<?xml version="1.0" encoding="ISO-8859-1"?><web-app 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-app_2_5.xsd"   version="2.5">     <description>      Servlet and JSP Examples.    </description><jsp-config><taglib><taglib-uri>myhello</taglib-uri><taglib-location>/WEB-INF/hellotag.tld</taglib-location></taglib><taglib><taglib-uri>date</taglib-uri><taglib-location>/WEB-INF/datetag.tld</taglib-location></taglib></jsp-config></web-app>

那么下面开始进行标签的使用操作
package com.demo;import java.io.*;import javax.servlet.*;import javax.servlet.jsp.JspException;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.*;public class AttributeTag  extends TagSupport{private String name;//接收属性的名称private String scope;//接收属性的范围@Overridepublic int doStartTag() throws JspException {  //判断属性是否存在Object value = null;if("page".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.PAGE_SCOPE);}if("request".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.REQUEST_SCOPE);}if("session".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.SESSION_SCOPE);}if("application".equals(this.scope)) {value = super.pageContext.getAttribute(this.name,PageContext.APPLICATION_SCOPE);}if(value == null) {  //表示现在根本没有此属性return TagSupport.SKIP_BODY;//没有属性不执行标签体} else {return TagSupport.EVAL_BODY_INCLUDE;  // 执行标签体}}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}}<?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">      <tlib-version>1.0</tlib-version>   <!-- 标签库的版本 -->      <short-name>firsttag</short-name>  <!-- 标签库在tld中的描述 -->          <tag>                  <name>present</name>                      <tag-class>com.demo.AttributeTag</tag-class>      <body-content>JSP</body-content>      <attribute>          <name>name</name>          <required>true</required>          <rtexprvalue>true</rtexprvalue>      </attribute>              <attribute>          <name>scope</name>          <required>true</required>          <rtexprvalue>true</rtexprvalue>      </attribute>      </tag> </taglib>    <taglib>            <taglib-uri>gz</taglib-uri>            <taglib-location>/WEB-INF/gztag.tld</taglib-location>        </taglib><%@ page contentType="text/html; charset=GBK"%><%@ taglib prefix="mytag" uri="gz"%><html><head><title>欢迎光临</title></head><body><%    String scope = "session"; //假设现在判断的是session范围    session.setAttribute("username","我要做皇帝");%>    <mytag:present name="username" scope="<%=scope%>" >        <h2><%=scope%> 范围存在属性,内容是:"${sessionScope.username}"</h2>    </mytag:present>            <mytag:present name="usernames" scope="request" >        <h2>request 范围存在属性,内容是:"${requestScope.usernames}"</h2>    </mytag:present></body></html> 
         很多的地方都在使用标签完成操作

       这个时候完成了有标签的标签开发工作,这样JSP的功能之一,判断的功能就可以通过标签完成简化代码的开发了

这个标签操作就是根据返回值的数值,来决定我最终的操作是哪一种。


小结

TagSupport 类中有各种标签处理方法,根据其返回值进行相应方法的调用;

标签中可以存在标签体,但是必须通过EVAL_BODY_INCLUDE才可以执行标签体




原创粉丝点击