JPS自定义标签初体验。

说下开发的环境
1,eclipse for java EE;
2, tomcat 7.0.42
3, windows 7


首先,新建一个动态web工程。
然后在javaResource目录下,新建一个类,这个类就是用来完成你的标签的功能的。
通常情况下,这个类需要实现Tag接口。

(Tag接口的内容如下:)

public interface Tag extends JspTag {

 
    public final static int SKIP_BODY = 0;

 
    public final static int EVAL_BODY_INCLUDE = 1;


    public final static int SKIP_PAGE = 5;


    public final static int EVAL_PAGE = 6;



    void setPageContext(PageContext pc);



    void setParent(Tag t);



    Tag getParent();



 
    int doStartTag() throws JspException;
 

    

    int doEndTag() throws JspException;

   

    void release();

}

上面这些方法各自完成自己的功能。sun公司已经为了我们定义了一个实现该接口的类,通常我们只需要继承这个已经实现
Tag接口的TagSupport类就可以。
但对于开始学些标签,最好还是自己实现Tag接口较好,这样能够让自己更加清楚程序的运行原理。
我们先去找到TagSupport的源代码:

package javax.servlet.jsp.tagext;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
public class TagSupport implements IterationTag, Serializable {
   
    public static final Tag findAncestorWithClass(Tag from, Class klass) {
	boolean isInterface = false;

	if (from == null ||
	    klass == null ||
	    (!Tag.class.isAssignableFrom(klass) &&
	     !(isInterface = klass.isInterface()))) {
	    return null;
	}

	for (;;) {
	    Tag tag = from.getParent();

	    if (tag == null) {
		return null;
	    }

	    if ((isInterface && klass.isInstance(tag)) ||
	        klass.isAssignableFrom(tag.getClass()))
		return tag;
	    else
		from = tag;
	}
    }

  

    public TagSupport() { }

 
    public int doStartTag() throws JspException {
        return SKIP_BODY;
    }

 

    public int doEndTag() throws JspException {
	return EVAL_PAGE;
    }


   
    
    public int doAfterBody() throws JspException {
	return SKIP_BODY;
    }

    public void release() {
	parent = null;
	id = null;
	if( values != null ) {
	    values.clear();
	}
	values = null;
    }


    public void setParent(Tag t) {
	parent = t;
    }


    public Tag getParent() {
	return parent;
    }

 

    public void setId(String id) {
	this.id = id;
    }

    
    public String getId() {
	return id;
    }


    public void setPageContext(PageContext pageContext) {
	this.pageContext = pageContext;
    }

 

    public void setValue(String k, Object o) {
	if (values == null) {
	    values = new Hashtable<String, Object>();
	}
	values.put(k, o);
    }


    public Object getValue(String k) {
	if (values == null) {
	    return null;
	} else {
	    return values.get(k);
	}
    }

 
    public void removeValue(String k) {
	if (values != null) {
	    values.remove(k);
	}
    }

   
    public Enumeration<String> getValues() {
	if (values == null) {
	    return null;
	}
	return values.keys();
    }

    // private fields

    private   Tag         parent;
    private   Hashtable<String, Object> values;
 
    protected String	  id;

    protected PageContext pageContext;
}

这里面方法还是很多的,不过对于开始只实现一个简单功能来说,先不要管这些,我们只需找到那些在Tag接口里存在的方法。
看看这个类是如何实现那些方法的。并对这些方法进行简单的分析。

 public int doStartTag() throws JspException {
        return SKIP_BODY;
    }
这个方法是非常重要的,它的意思就是标签开始执行,会做一些什么。比如我们一会要实现的功能,就是全部在这个方法
里完成。
对于该类来说,这个方法里就一条语句,return SKIP_BODY;究竟什么意思,我也不懂,但是这个SKIP_BODY被设置为了0.(见TAG标签的定义)
但是很明显,这里没有任何的输出。
/*
public final static int SKIP_BODY = 0;

 
    public final static int EVAL_BODY_INCLUDE = 1;


    public final static int SKIP_PAGE = 5;


    public final static int EVAL_PAGE = 6;
*/

    public int doEndTag() throws JspException {
    return EVAL_PAGE;
    }
    这个方法是执行到结束标签该做一些什么。return 6?也不大明白。但是在制作第一个标签的时候,我们不需要明白
    这个返回是什么意思,甚至都不要理会这个方法。一会只需要照着抄就行了,而且我们可以试着返回下其他值。
    或者在这里做一些输出操作,看看会发生什么事情。


 public void setPageContext(PageContext pageContext) {
    this.pageContext = pageContext;
    }
    这个方法,应该属于一个关键一点的方法了。因为这里涉及到一个变量pageContext,所以,我们需要在自己定义的
    类中申明这个变量。这个返回值就是当前使用该标签的pageContext,通过这个pageContext,我们可以获取很多
    JPS页面的信息,pageContext可以获取其他所有的page域,以及....

 
   public void setParent(Tag t) {
    parent = t;
    }
   这个先不要理会,没有什么作用。通常会在 if else这种标签的外面,套上一个父标签。

    public Tag getParent() {
    return parent;
    }
    同上。

     public void release() {
    parent = null;
    id = null;
    if( values != null ) {
        values.clear();
    }
    values = null;
    }
    这个就是释放资源,看这里,就是将里面的变量设置为空,而这里有一个value,我们开始应该并不需要什么value,
    所以就别管了。
    好了。明白了这些信息。
    
   我们就可以自己制作自己的标签了,我们实现的功能就是调用一个标签的时候,就会打印出来访者的Ip地址。
   <mytag:ShowIp/>
   在JSP页面就会显示IP地址。

  package cn.dzr.web.tag;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;

public class ShowIP implements Tag 
{
	
	Tag parent;
	PageContext pageContext;
	public void setPageContext(PageContext pc)
	{
		//将pageContext传递给这个类,这是我们实现下面操作的前提。
		//在接下来,我们肯定需要使用pageContext的功能的。
		this.pageContext = pc;

	}

	public void setParent(Tag t)
	{
		this.parent = t;

	}

	public Tag getParent()
	{
		return this.parent;
	}

	@Override
	public int doStartTag() throws JspException
	{
		//显示IP
		HttpServletRequest request = (HttpServletRequest)this.pageContext.getRequest();
		JspWriter out = this.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 void release()
	{
		//释放资源
		this.parent = null;
		this.pageContext = null;
	}

}

类已经写完。
那么接下来,我们就需要设定一条通道,让这个类的功能,能够到JSP页面里实现。
我们一共需要以下几步来完成。
1,将这个类配置成一条路径,并且使用一个简单的标签名来标志这个类。这个我们通常在一个xml文件里完成。
   在WEB-INF目录下新建一个文件,SimpleTag.tld(当然,名字随便你取)

   其内容如下:

 <!DOCTYPE taglib
        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
        "http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>

  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>simple</short-name>
  <uri>http://www.dzrtag.com</uri>
  
  <tag>
  	
  	<name>ShowIp</name>
  	<tag-class>cn.dzr.web.tag.ShowIP</tag-class>
  	<body-content>empty</body-content>
  	<description>显示IP地址</description>
  </tag>
  
</taglib>

这个XML文件里主要注意的是以下两个区域:
1,
 <tag>
      
      <name>ShowIp</name>
      <tag-class>cn.dzr.web.tag.ShowIP</tag-class>
      <body-content>empty</body-content>
      <description>显示IP地址</description>
  </tag>
    将标签的类,用ShowIP这个名字代表。注意类名必须是完成的类名,也就是包括其所在的包名。
    名字的话,从语法上来说,你可以随便取,但是最好取一个和其功能相对应的名字。
    接着下面的
    <body-content>empty</body-content>
    表示是否需要使用开始标签和结束标签之间的内容。我们这里当然不需要,所以设置为了空。
    下面的<description>显示IP地址</description>为描述信息。
     你可以写,或者不写。
    这里注意一点,name ->tag-class body-context description 可以不写,但是如果写,就必须按照这个顺序。
    相信学过XML的都知道,有一个shcema或者DTD规定了严格的顺序。

2,
         <tlib-version>1.0</tlib-version>
        <jsp-version>1.2</jsp-version>
        <short-name>simple</short-name>
        <uri>http://www.dzrtag.com</uri>

        这四行,第一行,第二行,是版本号。我也不大清楚不同版本有何不同。但是就是复制过来即可。
     重要的是uri,这个uri就是通道的核心。他起到连接JSP和tag类的作用。
     你这里设定一个值。具体的形式不清楚,但是我这里就是采用这种网站全名的格式。不纠结这个问题。

设定之后,我们就可以在JSP页面里使用这个标签了。

JSP页面内容如下


   <%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://www.dzrtag.com" 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>自定义标签的使用</title>
</head>
<body>	
	<mytag:ShowIp/>
</body>
</html>

需要注意的有两个地方。
1,
<%@taglib uri="http://www.dzrtag.com" prefix="mytag" %>   
这一句,看到这个uri没,机会是刚刚我上面写的uri,正是它,让JSP和TAG类关联了起来。
而这个后面的prefix 则是一个名称,语法你可以随便取名(除了一些sun公司不让你取的)

2,
<mytag:ShowIp/>
这里,就是使用刚刚你自己定义的标签了。

,你打开这个JSP,就会显示IP地址了。当你使用localhost:8080.。。。。访问的时候,他会显示一串000.
你用127.0.0.1访问的时候,则会显示127.0.0.1




系统可能出现一条错误信息:
resolved in either web.xml or the jar files deployed with this application。

我在网上找了半天的原因,最后通过重启tomcat解决了问题。或许是因为那个tld文件在配置之后,需要重启Tomcat才能
生效吧。
如果遇到一些无法解决的错误,重启也是一个不错的解决办法的。


最后,我对doEndTag方法进行了修改。

public int doEndTag() throws JspException
	{
	
		JspWriter out = this.pageContext.getOut();
		
		String str = "如果这是一个错误,那么该如何处理。";
		try
		{
			out.write(str);
		} 
		catch (IOException e)
		{
			throw new RuntimeException(e);
		}
		
		return 0;
	}

发现在页面上的IP地址后面,会显示 如果这是一个错误,那么该如何处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值