那些年javaweb自定义标签详解

一、简介

自定义标签的作用主要是用来替换JSP中的Java脚本。属于JSP技术。

二、自定义标签的开发步骤:

1.编写一个实现Tag接口的Java(标签处理器类)

2.编写标签库描述符(tld)文件,在tld文件中把标签处理器类进行描述在tld文件放入应用的web-inf文件中。如输入客户端ip地址的例子具体步骤示例如下:

1>定义一个类,实现javax.servlet.jsp.tagext.Tag接口(通过继承Tag接口的实现类也可)。

  public class ShowRemoteIpTag extends TagSupport {
  	public int doStartTag() throws JspException {
  		String remoteIp = pageContext.getRequest().getRemoteAddr();
  		try {
  			pageContext.getOut().print("您的IP是是:"+remoteIp);
  		} catch (IOException e) {
  			e.printStackTrace();
  		}
  		return super.doStartTag();
  	}
  }

2、在WEB-INF目录下建立一个扩展名为tldXML文件(XML的内容参考Tomcat中的示例)fk.tld文件内容如下:

  
  
      my taglib study.
      1.0
      fk
      http://www.test.com/jsp/fk
       
  		Show Remote Ip
          showRemoteIp
  		com.fk.tag.ShowRemoteIpTag
  		empty
      
   
  	forEach
  	com.fk.tag.example.ForEachSimpleTag
  	scriptless
  	 
  	    items
  	    true
  	    true
  	
  	
  	    var
  	    true
  	    false
  	
  
   
  某一List对象是否包含某一Object对象
  contains
  	com.fk.util.ListContainsLabel
  	java.lang.Boolean contains(java.util.List,java.lang.Object)
  
  

3、在web.xml中建立tld文件的存放位置和uri的对应关系。

注:此步骤是可选的,前提是tld文件放在了WEB-INF目录下(建议使用此方式)

  
  	
  		http://www.test.com/jsp/fk
  		/WEB-INF/fk.tld
  	
  

三、Tag接口详解(接口中的方法大部分都是容器调用的,继承了JspTag接口)

int doStartTag():容器调用。遇到开始标签时调用。

返回值可为:

Tag.SKIP_BODY:指示标签主体内容不执行

Tag.EVAL_BODY_INCLUDE:指示标签主体内容执行

int doEndTag():容器调用。遇到结束标签时调用。

返回值可为:

Tag.SKIP_PAGE:忽略结束标签之后的JSP内容

Tag.EVAL_PAGE:结束标签后的JSP内容还要继续执行

Tag getParent():用户调用。得到父标签。没有父标签返回null

void release():容器调用。释放标签类占用的资源。

void setPageContext(PageContext pc):容器调用。传入当前页面的上下文对象

void setParent(Tag t):容器调用。传入当前标签的父标签对象。如果有的话。

四、IterationTag接口:增加了重复执行主体内容的方法。(IterationTag接口继承了Tag接口,TagSupport类实现了IterationTag接口)

int doAfterBody():主体执行后,结束标签执行前,容器调用

返回值:

Tag.SKIP_BODY:指示标签主体内容不执行

IterationTag.EVAL_BODY_AGAIN:再次调用doAfterBody方法

注:成员变量的问题。

五、BodyTag:增加了获取主体内容的方法

void doInitBody() :容器调用

void setBodyContent(BodyContent b):容器调用,传递标签的主体内容

注意:以上2个方法都是由容器调用。要求doStartTag()方法必须返回BodyTag.EVAL_BODY_BUFFERED

六、传统标签返回值图、标签类继承及传统标签的执行流程

那些年javaweb自定义标签详解_第1张图片

那些年javaweb自定义标签详解_第2张图片

那些年javaweb自定义标签详解_第3张图片

七、简单标签

SimpleTag接口详解

void setJspContext(JspContext pc) :设置当前JSP的上下文件。容器调用

void setParent(JspTag parent) :设置父标签对象。如果有的话。容器调用

void setJspBody(JspFragment jspBody) :设置主体内容。容器调用

若实现此接口类,有相关的setter属性,容器会自动调用自定义的setter方法。 

void doTag():遇到标签就执行。容器调用。---------处理自定义标签功能的方法

用于完成所有的标签逻辑,包括输出、迭代、修改标签体内容等。doTag方法中可以 抛出javax.servlet.jsp.SkipPageException异常,用于通知WEB容器不再执行JSP页面中 位于结束标记后面的内容,这等效于在传统标签的doEndTag方法中返回 Tag.SKIP_PAGE常量的情况。 

JspTag getParent():自己调用。得到父标签。没有返回null

注意:每次调用都会重新实例化,简单标签不会驻留内存,而传统标签会驻留内存(Servlet一样,第一次访问时容器创建实例化后就驻留了)

那些年javaweb自定义标签详解_第4张图片

//url地址过滤,若不是本站过来的url将被传到toPage值的文件中去。
public void doTag() throws JspException, IOException {
		PageContext pc = (PageContext)getJspContext();
		HttpServletRequest request = (HttpServletRequest)pc.getRequest();
		String referer = request.getHeader("Referer");//Referer
		HttpServletResponse response = (HttpServletResponse)pc.getResponse();
		if(null == referer ||!referer.startsWith(siteUrl)){ //若不是指定的url开头地址则转过去,否则继续浏览呢,siteUrl为标签另一属性本站的基地址。
			if(toPage.startsWith("/")){
				response.sendRedirect(toPage);
			}else{
				String path = request.getRequestURL().toString();
				String prePath = path.substring(0, path.lastIndexOf("/"));
				response.sendRedirect(prePath+"/"+toPage);
			}
		}
	}

显示类如下,模拟foreach功能:

public class ForEachSimpleTag extends SimpleTagSupport {
	private Object items;
	private String var;
	private Collection collection ;
	public void setItems(Object items) {
		if(items instanceof List){
			collection = (List)items;
		}
		if(items instanceof Set){
			collection = (Set)items;
		}
		if(items instanceof Map){
			collection = ((Map)items).entrySet();
		}
		if(items.getClass().isArray()){
			int len = Array.getLength(items);//获取数组的长度
			for(int i=0;i

八、tld文件的主要元素

taglib:根元素

tlib-version:版本号

short-name:短名称

uri:名称空间

function:可定义函数

name:标签的名称如contains

function-class:标签的处理类如com.fk.util.ListContainsLabel

function-signature:标签的静态处理方法

如:java.lang.Boolean contains(java.util.List,java.lang.Object)

tag:定义一个标签

name:标签的名称

tag-class:标签的处理类。全名称

body-content:标签的主体内容类型。

可选值:

JSP:主体内容可以是任意内容。服务传统标签

scriptless:主体内容一般是非java脚本内容。服务简单标签

empty:没有主体内容

tagdepentend:指示主体内容当做普通字符串对待

attribute:定义标签的属性

name:属性名称

required:是否是必须属性

rtexprvalue:是否支持表达式(EL表达式或Java表达式)

runtime expression value



你可能感兴趣的:(jsp,string,object,setter,java,null,前台Web,javaweb)