栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java Web之自定义JSP标签

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java Web之自定义JSP标签

Java Web之自定义JSP标签
write:2022-5-7

上文:Java Web之使用过滤器。
前面我们学习了JSP自带的标签:Java web之JSP技术详解,但自带标签数量有限,从JSP1.1开始出现了自定义JSP标签技术,允许用户创建客户化的标签,从而完成特定需求的功能。

文章目录
  • 1. 理解自定义JSP标签的作用
  • 2. 掌握创建并运用自定义JSP标签的步骤
  • 3. 了解JSP Tag API
    • 3.1 标签的处理类
    • 3.2 TagSupport类
    • 3.3 PageContext类
    • 3.4 doStartTag()方法的返回值
    • 3.5 doEndTag()方法的返回值
    • 3.6 用户自定义的标签属性
  • 4. Servlet容器处理自定义标签的流程
    • 4.1 范例1:创建hello标签
    • 4.2 范例2:创建message标签
  • 5. 练习题

1. 理解自定义JSP标签的作用

自定义JSP标签技术是在JSP 1.1版本中才出现的,它支持用户在JSP文件中自定义标签,这样可以使JSP代码更加简洁。
自定义标签是可重用的
自定义标签能处理复杂的逻辑运算和事务,或者定义JSP网页的输出内容和格式。

2. 掌握创建并运用自定义JSP标签的步骤

因为自定义的JSP标签可以被重复使用,因此创建自定义JSP标签和在JSP文件中使用自定义JSP标签是独立的;

  1. 创建自定义JSP标签
    (1)创建标签的处理类(决定标签完成的功能)
    (2)创建XML格式的标签库描述文件
  2. 在JSP文件中使用自定义JSP标签
    (1)在web.xml文件中声明所引用的自定义标签所在的标签库(标签库:组织和管理一组功能相关的标签)
    (2)在JSP文件中引入标签库,然后插入标签,例如:< mm:hello/>
3. 了解JSP Tag API 3.1 标签的处理类

Servlet容器执行JSP文件时,如果遇到自定义标签,就会调用这个标签的处理类。

标签处理类必须扩展以下两个类之一:
javax.servlet.jsp.TagSupport或者javax.servlet.jsp.BodyTagSupport
下面主要结束如何扩展TagSupport类

3.2 TagSupport类
  1. TagSupport类的主要方法
    doStartTag():Servlet容器遇到自定义标签的起始标志(即:<)时调用该方法
    doEndTag():Servlet容器遇到自定义标签的结束标志(即:/>)时调用该方法
    setValue(String k,Object o):在标签处理类中设置key/value
    getValue(String k): 在标签处理类中根据参数key返回匹配的value
    removeValue(String k):在标签处理类中删除key/value
  2. TagSupport类的两个重要属性
    (1)两个属性
    parent:引用嵌套了当前标签的上层标签(父标签)的处理类对象
    pageContext:引用当前JSP页面的javax.servlet.jsp.PageContext对象
    (2)与属性对应的方法
    setPageContext(PageContext pc):设置PageContext对象,该方法由Servlet容器在调用doStartTag或doEndTag方法前调用
    setParent(Tag t):设置嵌套了当前标签的上层标签的处理类,该方法由Servlet容器在调用doStartTag()方法前调用
    getParent():返回嵌套了当前标签的上层标签的处理类对象

Servlet容器在调用doStartTag() 方法前,会先调用setPageContext()和setParent()方法,设置pageContext和parent属性。

parent属性是private类型的,在doStartTag()或doEndTag()方法中可以通过getParent()方法获取上层父标签的处理类对象;
在TagSupport类中定义了protected类型的pageContext成员变量,因此在标签处理类中可以直接访问pageContext变量。

3.3 PageContext类

TagSupport类的两个重要属性之一:PageContext类
PageContext类本身由Servlet容器创建,它是Servlet容器为JSP页面提供的得力助手,在JSP页面的自定义标签也可以使用这个得力助手;

PageContext类提供了保存和访问Web应用的各个范围内的共享数据的方法:

public void setAttribute(String name, Object value, int scope)//存放
public Object getAttribute(String name, int scope)//访问

其中,scope参数用来指定属性存在的范围,它的可选值包括:
PageContext.PAGE_SCOPE
PageContext.REQUEST_SCOPE
PageContext.SESSION_SCOPE
PageContext.APPLICATION_SCOPE
例如:

pageContext.setAttribute(“username”,”Tom”, PageContext.SESSION_SCOPE);//存放
String username=(String)pageContext.getAttribute(“username”, PageContext.SESSION_SCOPE);//访问
3.4 doStartTag()方法的返回值

TagSupport类的主要方法之一:doStartTag():Servlet容器遇到自定义标签的起始标志(即:<)时调用该方法

doStartTag()方法返回一个整数值,用来决定程序的后续流程。它有两个可选值:
Tag.SKIP_BODY表示标签之间的内容被忽略。
Tag.EVAL_BODY_INCLUDE表示标签之间的内容被正常执行。

例如对于以下代码:
< prefix: Mytag>
Hello
……
……
< /prefix:Mytag>

假若< Mytag>的doStartTag()方法返回Tag.SKIP_BODY,”Hello”字符串不会显示在网页上;若返回Tag.EVAL_BODY_INCLUDE,“Hello” 字符串将显示在网页上。

3.5 doEndTag()方法的返回值

TagSupport类的主要方法之一:doEndTag():Servlet容器遇到自定义标签的结束标志(即:/>)时调用该方法

doEndTag()方法也返回一个整数值,用来决定程序后续流程。它有两个可选值:
Tag.SKIP_PAGE:表示立刻停止执行JSP网页,网页上未处理的静态内容和JSP程序代码均被忽略,任何已有的输出内容立刻返回到客户的浏览器上。
Tag.EVAL_PAGE:表示按正常的流程继续执行JSP网页。

3.6 用户自定义的标签属性

在标签中还能包含自定义的属性,例如:
< prefix:mytag username=“Tom">
……
……
< /prefix:mytag>

在标签处理类中应该将这个属性作为成员变量,并且分别提供设置和读取属性的方法;
假定以上username为String类型,可以定义如下方法:
private String username;
public void setUsername(String value){
this.username=value;
}
public String getUsername(){
return username;
}

4. Servlet容器处理自定义标签的流程

4.1 范例1:创建hello标签

定义一个名为mytaglib的标签库,它包含一个简单的hello标签,这个标签能够将JSP页面中所有的< mm:hello/>解析为字符串“hello”。

hello标签的处理类HelloTag

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.tagext.TagSupport;

public class HelloTag extends TagSupport{
  
  public int doEndTag() throws JspException{
    try{
      //打印字符串“Hello”
      pageContext.getOut().print("Hello");
    }catch (Exception e) {
      throw new JspTagException(e.getMessage());
    }
    return EVAL_PAGE;
  }
}

创建hello标签的标签库的描述文件
创建Tag Library的描述文件mytaglib.tld文件,在这个文件中定义mytaglib标签库和hello标签。这个文件存放位置为/WEB-INF/mytaglib.tld。


  1.0//标签库版本
  1.1//jsp版本
  mytaglib//标签库默认的前缀名
  /mytaglib//标签库唯一的访问标识符

  //定义一个标签
    hello//标签名
    mypack.HelloTag//标签处理类
    empty//标签主体的类型
    Just Says Hello//标签的说明信息
  


如果某个web应用需要使用名为mytaglib的标签库中的标签,就需要在web应用中加入标签库的描述文件mytaglib.tld文件:把mytaglib.tld文件放在/WEB-INF下,目录/WEB-INF/mytaglib.tld;
在web.xml文件中加入< taglib>元素


     ……
    //声明web应用引用的标签库
       /mytaglib//为标签库映射唯一一个标识符,根据标识符引用标签库
       /WEB-INF/mytaglib.tld//标签库tld文件存放位置
    


在JSP文件中加入hello标签
(1)在hellowithtag1.jsp中加入引用mytaglib的taglib指令:<%@ taglib uri=“/mytaglib” prefix=“mm” %>
以上taglib指令中,prefix属性用来指定引用mytaglib标签库时的前缀(所有以mm开头的标签都来自mytaglib标签库)。

(2)在hellowithtag1.jsp文件中插入hello标签:
< b>< mm:hello/> :
<%= request.getParameter(“username") %>

访问hellowithtag1.jsp:
http://localhost:8080/hellowithtag1.jsp?username=weiqin

4.2 范例2:创建message标签

创建一个能替换helloapp应用中JSP网页的静态文本的标签,这个标签名为message,它放在mytaglib标签库中。

在hellowithtag2.jsp文件中使用message标签的代码如下:
< b>< mm:message key=“hello.hello” /> :
<%= request.getAttribute(“username") %>< /b>
当客户访问hello.jsp网页时,message标签的处理类会根据属性key的值从一个文本文件中找到与key匹配的字符串。假定这个字符串为“Hello”,然后将这个字符串输出到网页上。
创建包含JSP网页静态文本的文件
首先将创建包含JSP网页静态文本的文件,这些文本以key=value的形式存放,这个文件名为messageresource.properties:

在Web应用启动时装载静态文本
尽管装载静态文本的任务可以直接由标签处理类来完成,但是把初始化的操作安排在Web应用启动时完成,这更符合Web编程的规范。
在本例中,由LoadServlet类的init方法负责从静态文本文件中读取静态文本,然后把它们装载到Properties对象中,最后再把这个Properties对象作为属性保存到ServletContext中。

LoadServlet类的init方法

public void init()throws ServletException {
    
    Properties ps=new Properties();
    try{
      ServletContext context=getServletContext();
      InputStream in=
         context.getResourceAsStream("/WEB-INF/messageresource.properties");
      ps.load(in);
      in.close();

      //在Web应用范围内存放包含静态文本的Properties对象
      context.setAttribute("ps",ps);  
    }catch(Exception e){
      e.printStackTrace();
    }
  }

为了保证在Web应用启动时就加载LoadServlet,应该在web.xml中配置这个Servlet时设置load-on-startup属性:


        load
        mypack.LoadServlet
        1
    

创建MessageTag标签处理类
MessageTag包含一个成员变量key,它与message标签的属性key对应。在MessageTag中定义了getKey和setKey方法:

private String key=null;
    public String getKey(){
      return this.key;
}
public void setKey(String key){
      this.key=key;
} 
public int doEndTag() throws JspException {

     try {
	   Properties    ps=
        (Properties)pageContext.getAttribute("ps",pageContext.APPLICATION_SCOPE);
         String message=(String)ps.get(key);
         pageContext.getOut().print(message);
      } catch (Exception e) {
            throw new JspTagException(e.getMessage());
      }
       
         return EVAL_PAGE;
    }
}

在mytaglib库中定义message标签

//定义一个标签
    message//标签名
    mypack.MessageTag//标签处理类
    empty//标签主体的类型
    produce message by key//标签的说明信息
 
    
        key//属性
        true//属性是否需要赋值
    
  
5. 练习题
  1. 问题:在标签处理类中,如何访问session范围内的共享数据?
    选项:
    (A)在TagSupport类中定义了session成员变量,直接调用它的getAttribute()方法即可。
    (B)在标签处理类TagSupport类中定义了pageContext成员变量,先通过它的getSession()方法获得当前的HttpSession对象,再调用HttpSession对象的getAttribute()方法。
    ©pageContext.getAttribute(“attributename”,PageContext.SESSION_SCOPE)
    答案: B,C
  2. 问题:在下面的选项中,哪些是TagSupport类的doStartTag()方法的有效返回值?
    选项:
    (A) Tag.SKIP_BODY
    (B) Tag.SKIY_PAGE
    © Tag.EVAL_BODY_INCLUDE
    (D) Tag.EVAL_PAGE
    答案: A,C
  3. 问题:标签处理类的doStartTag()方法以及doEndTag()方法由谁调用?
    选项:
    (A) HTTPServletRequest类
    (B) HTTPServletResponse类
    © ServletContext类
    (D) Servlet容器
    答案: D
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/871926.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号