Jsp中自定义标签

来源:互联网 发布:网络祭祖 编辑:程序博客网 时间:2024/05/23 01:12

Jsp中自定义标签


      • Jsp中自定义标签
        • 概述
        • 需求
        • 自定义标签实战
        • 自定义标签的执行过程
        • 自定义标签的作用


概述


很明显,内置标签和JSTL标签不能完全满足我们的开发需求,在实际的应用中我们经常会使用大量的自定义标签,本文将给出一个自定义标签的实例来说明整个过程。

需求


在Jsp中使用自定义标签实现:显示连接服务器的客户端的IP地址。当然我们可以在Jsp中使用脚本完成该任务,脚本如下:

<%  String ip = request.getRemoteHost();  out.write(ip);%>

在一个新建的Jsp页面中写入上面的Java代码,便可以很轻松的实现需求,但是有两点不好的地方:

  • 在Jsp中我们应该尽量少些Java代码
  • 需求中要求使用标签实现该功能,但是上述方法使用的是Jsp的脚本,不符合要求

搜索了JSTL的标签库我们发现:不存在这样的标签使得这个需求能够很完美的实。那么是不是意味着没有办法实现了呢?不是,我们使用自定义标签,下面将使用该实例,实现一个自定义标签。

自定义标签实战


需要明确的是:每一个标签的背后实际上都是Java代码,所以我们自定义的标签理所当然应该有Java类的支持。下面将从头讲述实现自定义标签的方法。

  • 书写一个Java类,将标签背后的实际处理逻辑写到该类中
package com.jpzhutech.tag;import java.io.IOException;import javax.servlet.ServletRequest;import javax.servlet.http.HttpServletRequest;import javax.servlet.jsp.JspContext;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;/** * 标签处理器类 */import javax.servlet.jsp.tagext.SimpleTagSupport;public class ShowIp extends SimpleTagSupport{    //覆盖其中的doTag()方法    @Override    public void doTag() throws JspException, IOException {        //向浏览器输出客户的IP地址        PageContext pageContext = (PageContext)this.getJspContext();        HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();        String ip = request.getRemoteHost();        JspWriter out = pageContext.getOut();        out.write("当前客户的IP地址是:"+ip);    }}
  • 在/WebRoot/WEB-INF/下写一个tld文件,该tld文件的写法可以参考JSTL核心标签库的语法,将自定义标签和上面的Java代码绑定在一起
<!--在WebRoot/WEB-INF中写一个tld文件,假设我命名为jpzhutech.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">   <!-- 标签库的版本 -->   <tlib-version>1.1</tlib-version>  <!-- 标签库的访问前缀 -->  <short-name>jpzhutech</short-name>  <!-- tld文件的唯一标记 -->  <uri>http://www.jpzhutech.com</uri>  <tag>    <!-- 标签名称 -->    <name>ShowIp</name>    <!-- 标签处理器的完成类名 包名+类名 -->    <tag-class>com.jpzhutech.tag.ShowIp</tag-class>    <!-- 输出标签体的内容格式 -->    <body-content>scriptless</body-content>  </tag></taglib>
  • 在Jsp中引入自定的标签
<%--index.jsp--%><%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib uri="http://www.jpzhutech.com"  prefix="jpzhutech"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>自定义标签</title>  </head>  <body>    <jpzhutech:ShowIp></jpzhutech:ShowIp>  </body></html>

自定义标签的执行过程


解释上述实例当访问http://localhost:8080/TagDefinition/index.jsp 究竟发生了什么呢?

  • 访问http://localhost:8080/TagDefinition/index.jsp
  • tomcat服务器把Jsp文件翻译成为Java源文件,在编译成class文件,后执行类中的方法
  • 接着检查Jsp文件的taglib指令,检查是否存在一个名字为http://www.jpzhutech.com 的tld文件
  • 当读到Jsp文件的标签时,发现属于上述tld文件中的标签,会到该tld文件中找到相应的tag标签,并且该标签必须是唯一的,于是找到相应的tag-class
  • 最后执行tag-class中的方法,输出想要的结果

自定义标签的作用


  • 控制标签体内容是否输出
package com.jpzhutech.tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;public class DemoTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException, IOException {        PageContext context =(PageContext) getJspContext();        //控制标签体的内容是否输出        JspFragment jspBody = this.getJspBody();  //得到标签体的内容        //执行invoke方法会将标签体内容输出到一个Writer对象中        JspWriter out = context.getOut();        jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出    }}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@taglib uri="http://www.jpzhutech.com"  prefix="jpzhutech"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <title>自定义标签</title>  </head>  <body>    <jpzhutech:ShowIp>你好</jpzhutech:ShowIp>    <jpzhutech:demotag>标签体的内容</jpzhutech:demotag>    标签余下的内容  </body></html>
<?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">   <!-- 标签库的版本 -->   <tlib-version>1.1</tlib-version>  <!-- 标签库的访问前缀 -->  <short-name>jpzhutech</short-name>  <!-- tld文件的唯一标记 -->  <uri>http://www.jpzhutech.com</uri>  <tag>    <!-- 标签名称 -->    <name>ShowIp</name>    <!-- 标签处理器的完成类名 包名+类名 -->    <tag-class>com.jpzhutech.tag.ShowIp</tag-class>    <!-- 输出标签体的内容格式 -->    <body-content>scriptless</body-content>  </tag>  <tag>    <!-- 标签名称 -->    <name>demotag</name>    <!-- 标签处理器的完成类名 包名+类名 -->    <tag-class>com.jpzhutech.tag.DemoTag</tag-class>    <!-- 输出标签体的内容格式 -->    <body-content>scriptless</body-content>  </tag></taglib>
  • 控制标签余下的内容是否输出
package com.jpzhutech.tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.SkipPageException;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;public class DemoTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException, IOException {        PageContext context =(PageContext) getJspContext();        //功能一:控制标签体的内容是否输出        JspFragment jspBody = this.getJspBody();  //得到标签体的内容        //执行invoke方法会将标签体内容输出到一个Writer对象中        JspWriter out = context.getOut();        jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出        //功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出        throw new SkipPageException();    }}
  • 控制重复输出标签体的内容
package com.jpzhutech.tag;import java.io.IOException;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.SkipPageException;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;public class DemoTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException, IOException {        PageContext context =(PageContext) getJspContext();        //功能一:控制标签体的内容是否输出        JspFragment jspBody = this.getJspBody();  //得到标签体的内容        //执行invoke方法会将标签体内容输出到一个Writer对象中        JspWriter out = context.getOut();        jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出        // 功能三:控制重复输出标签体的内容        for (int i = 1; i <= 5; i++) {            jspBody.invoke(out);        }        //功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出        throw new SkipPageException();    }}
  • 改变标签体的内容
package com.jpzhutech.tag;import java.io.IOException;import java.io.StringWriter;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.SkipPageException;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;public class DemoTag extends SimpleTagSupport {    @Override    public void doTag() throws JspException, IOException {        PageContext context =(PageContext) getJspContext();        //功能一:控制标签体的内容是否输出        JspFragment jspBody = this.getJspBody();  //得到标签体的内容        //执行invoke方法会将标签体内容输出到一个Writer对象中        JspWriter out = context.getOut();        jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出        // 功能三:控制重复输出标签体的内容        for (int i = 1; i <= 5; i++) {            jspBody.invoke(out);        }        //功能四:改变标签体的内容        StringWriter writer = new StringWriter();        jspBody.invoke(writer);        String string = writer.toString();   //将要输出的内容转换成字符串        //改变其内容        String lowerCase = string.toLowerCase();  //将字符串转换为小写        out.write(lowerCase);  //使用out对象手动输出,已经不能使用jspBody.invoke(out)方法来输出        //功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出        throw new SkipPageException();    }}
  • 带属性的标签

注意:输出带属性的标签必须在定义每一个属性时,同时加上get和set方法,像下面的例子

package com.jpzhutech.tag;import java.io.IOException;import java.io.StringWriter;import javax.servlet.jsp.JspException;import javax.servlet.jsp.JspWriter;import javax.servlet.jsp.PageContext;import javax.servlet.jsp.SkipPageException;import javax.servlet.jsp.tagext.JspFragment;import javax.servlet.jsp.tagext.SimpleTagSupport;public class DemoTag extends SimpleTagSupport {    private String name;    private String price;    private String store;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPrice() {        return price;    }    public void setPrice(String price) {        this.price = price;    }    public String getStore() {        return store;    }    public void setStore(String store) {        this.store = store;    }    @Override    public void doTag() throws JspException, IOException {        PageContext context =(PageContext) getJspContext();        //功能一:控制标签体的内容是否输出        JspFragment jspBody = this.getJspBody();  //得到标签体的内容        //执行invoke方法会将标签体内容输出到一个Writer对象中        JspWriter out = context.getOut();        jspBody.invoke(out);   //一旦调用该方法,就会将标签体的内容输出        // 功能三:控制重复输出标签体的内容        for (int i = 1; i <= 5; i++) {            jspBody.invoke(out);        }        //功能四:改变标签体的内容        StringWriter writer = new StringWriter();        jspBody.invoke(writer);        String string = writer.toString();   //将要输出的内容转换成字符串        //改变其内容        String lowerCase = string.toLowerCase();  //将字符串转换为小写        out.write(lowerCase);  //使用out对象手动输出,已经不能使用jspBody.invoke(out)方法来输出        //输出带属性的标签        out.write("书名:"+name);        out.write("价格:"+price);        out.write("书店:"+store);        //功能二:控制余下的内容是否输出,如果这里之后什么都不写,则默认输出,相反做点事情会使得后续不输出        throw new SkipPageException();    }}
0 0
原创粉丝点击