下面到了关键部分乐。 对tag进行处理。其实很多情况下我们是使用已经提供的taglib. 别人/公司已经做好了tag和处理部分,打好了包 我们需要做的只是在我们的jsp中去应用.
但是当我们自己做个taglib时, 就需要编写这部分tag handler了.
这里只针对上面文件里提到的insert tag,其他的为了避免重复,就不一一说明了
==================== InsertTag.java==============================
/*
* $Id: InsertTag.java,v 1.13 2000/03/04 02:54:57 brydon Exp $
* Copyright 1999 Sun Microsystems, Inc. All rights reserved.
* Copyright 1999 Sun Microsystems, Inc. Tous droits réservés.
*/
package com.sun.estore.taglib;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;
import com.sun.estore.util.Debug;
/**
* This class is an easy interface to the JSP template or other
* text that needs to be inserted.
* @author Greg Murray
*/
public class InsertTag extends TagSupport {
private boolean directInclude = false;
private String parameter = null;
private String templateName = null;
private Template template = null;
private TemplateParameter templateParam = null;
/**
* default constructor
*/
public InsertTag() {
super();
}
public void setTemplate(String templateName){
this.templateName = templateName;
}
public void setParameter(String parameter){
this.parameter = parameter;
}
public int doStartTag() {
try{
if (templateName != null){
template = (Template)pageContext.getRequest().getAttribute("template");
}
} catch (NullPointerException e){
Debug.println("Error extracting template from session: " + e);
}
if (parameter != null && template != null) templateParam = (TemplateParameter)template.getParam(parameter);
if (templateParam != null) directInclude = templateParam.isDirect();
return SKIP_BODY;
}
public int doEndTag() throws JspTagException {
try{
pageContext.getOut().flush();
} catch (Exception e){
// do nothing
}
try {
if (directInclude && templateParam != null) {
pageContext.getOut().println(templateParam.getValue());
} else if (templateParam != null) {
if (templateParam.getValue() != null) pageContext.getRequest().getRequestDispatcher(templateParam.getValue()).include(pageContext.getRequest(), pageContext.getResponse());
}
} catch (Throwable ex) {
ex.printStackTrace();
}
return EVAL_PAGE;
}
}
可以看到。InsertTag.java继承了javax.servlet.jsp.tagext.TagSupport类. 因为在TagSupport中定义了一些接口. 我们在处理自定义的tag时, 对父类的doStartTag() 和doEndTag() 要进行重载,如果在tld文件中定义了tag的属性, 就需要在tag handler里对每个属性定义相应的setxxx/getxxx方法. 在doStartTag()中是从Template类所定义的Hashtable中取得TemplateParameter对象.
在doEndTag()中
pageContext.getRequest().getRequestDispatcher(templateParam.getValue()).include(pageContext.getRequest(), pageContext.getResponse());
这是在页面里包含通过jsp页的上下文返回通过tag的属性值指定的资源对象(RequestDispatcher)所产生的内容..
doStartTag()和doEndTag()返回值是在Tag Interface里定义的静态int
SKIP_BODY隐含0
Skip body evaluation. Valid return value for doStartTag and doAfterBody. 跳过对body的处理。
就是跳过了开始和结束标签之间的代码。
EVAL_BODY_INCLUDE 隐含1
Evaluate body into existing out stream. Valid return value for doStartTag.
This is an illegal return value for doStartTag when the class implements BodyTag,
since BodyTag implies the creation of a new BodyContent.
将body的内容输出到存在的输出流中。包括是jsp代码,也可以被输出
SKIP_PAGE 隐含5
Skip the rest of the page. Valid return value for doEndTag.
忽略剩下的页面。
EVAL_PAGE 隐含6
Continue evaluating the page. Valid return value for doEndTag().
继续执行下面的页
在这个类里还有对其他类的引用,我就不列出来了. 各位可以自己去研究. 自定义标签(Custom tags)实现了 javax.servlet.jsp.tagext.Tag or javax.servlet.jsp.tagext.BodyTag interface. 应用javax.servlet.jsp.JspWriter 来输出.
TagSupport class 提供了对interface Tag的隐含实现. 序列化编发数据.
public class TagSupport extends java.lang.Object implements Tag, java.io.Serializable
BodyTagSupport class提供了对interface BodyTag的隐含实现.继承TagSupport
public class BodyTagSupport extendsTagSupport implements BodyTag
我们在编写tag handler时需要继承TagSupport类或BodyTagSupport类,然后重载doStartTag()和doEndTag().
还可以再进一步分离.将具体实现放到bean里
这些自定义标签的类所应放的位置应该在WEB-INF/classes或WEB-INF/lib
最后将custom tag libraries 打包成.war文件.关于.war文件,如下图所示给出了资源结构图。
通过部署描述符来控制映射。 部署描述符是个XML文件。详细的请详见有关文档资料。这里只说明 部署TagLib的部分。
JSP custom tag libraries (optional)
Specifies URL for locating Tag Library Descriptor
…
uri
path
…
/**************自定义TagLib例子: JSP page *******************
………
*******************************************************/
文件位置如下:
这个例子很简单, 只是作为练习使用.你也可以自己进行扩展,多练习几种处理方法.比方说标签带有属性,
标签带有内容, 使用bean处理逻辑等等
关于将这些文件打包成.war文件.这里就不详细说明了.请根据你使用的application server情况自己完成吧. |