深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库

一、开发标签库案例

1.1、开发防盗链标签

  1、编写标签处理器类:RefererTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.SkipPageException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * 防盗链标签RefererTag
 */
public class RefererTag extends SimpleTagSupport {

    /**
     * 网站域名
     */
    private String site;

    /**
     * 要跳转的页面
     */
    private String page;

    @Override
    public void doTag() throws JspException, IOException {
        //获取jsp页面的PageContext对象
        PageContext pageContext = (PageContext) this.getJspContext();
        //通过PageContext对象来获取HttpServletRequest对象
        HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
        //获取请求的来路(Referer)
        String referer = request.getHeader("referer");
        //如果来路是null或者来路不是来自我们自己的site,那么就将请求重定向到page页面
        if (referer == null || !referer.startsWith(site)) {
            //获取HttpServletResponse对象
            HttpServletResponse response = (HttpServletResponse)pageContext.getResponse();
            String webRoot = request.getContextPath();
            if (page.startsWith(webRoot)) {
                //重定向到page页面
                response.sendRedirect(page);
            } else {
                //重定向到page页面
                response.sendRedirect(webRoot+page);
            }
            //重定向后,控制保护的页面不要执行
            throw new SkipPageException();
        }
    }

    public void setSite(String site) {
        this.site = site;
    }

    public void setPage(String page) {
        this.page = page;
    }
}

2、在WEB-INF目录下tld文件中添加对该标签的描述,如下:



<taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee web-jsptaglibrary_2_0.xsd">

    <description>孤傲苍狼开发的简单标签库description>
    <tlib-version>1.0tlib-version>
    <short-name>TagLibshort-name>
    <uri>/gaclTagLiburi>

    <tag>
        
        <name>referername>
        
        <tag-class>me.gacl.web.simpletag.RefererTagtag-class>
        
        <body-content>emptybody-content>
        
        <attribute>
            <description>描述标签的site属性description>
            
            <name>sitename>
            <required>truerequired>
            
            <rtexprvalue>truertexprvalue>
        attribute>
        <attribute>
            <description>描述标签的page属性description>
            
            <name>pagename>
            <required>truerequired>
            
            <rtexprvalue>truertexprvalue>
        attribute>
    tag>

taglib>

3、测试:在jsp页面中导入标签库并使用防盗链标签

<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="gacl" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="gacl"%>
--%>
<%--在Jsp页面中使用防盗链标签 
当用户尝试直接通过URL地址(http://localhost:8080/JavaWeb_JspTag_study_20140816/simpletag/refererTagTest.jsp)访问这个页面时,
防盗链标签的标签处理器内部就会进行处理,将请求重定向到/index.jsp
--%>
<gacl:referer site="http://localhost:8080" page="/index.jsp"/>

<html>
  <head>
    <title>防盗链标签测试title>
  head>

  <body>
     网站内部资料
  body>
html>

 运行效果如下:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第1张图片
  

1.2、开发标签

  1、编写标签处理器类:IFTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * 开发if标签
 */
public class IFTag extends SimpleTagSupport {

    /**
     * if标签的test属性
     */
    private boolean test;

    @Override
    public void doTag() throws JspException, IOException {
        if (test) {
            this.getJspBody().invoke(null);
        }
    }

    public void setTest(boolean test) {
        this.test = test;
    }
}

  2、在WEB-INF目录下tld文件中添加对该标签的描述,如下:

<tag>
    <description>if标签description>
    <name>ifname>
    <tag-class>me.gacl.web.simpletag.IFTagtag-class>
    <body-content>scriptlessbody-content>
    <attribute>
        <description>if标签的test属性description>
        <name>testname>
        <rtexprvalue>truertexprvalue>
        <required>truerequired>
    attribute>
tag>

  3、测试:在jsp页面中导入标签库并使用if标签

<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="c" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="c"%>
--%>

<html>
  <head>
    <title>if链标签测试title>
  head>

  <body>
  <%--if标签的test属性值为true ,标签体的内容会输出--%>
      <c:if test="true">
         <h3>网站内部资料h3>
    c:if>
    <%--if标签的test属性值为false ,标签体的内容不会输出--%>
    <c:if test="false">
        这里的内部不输出
    c:if>
  body>
html>

  运行效果如下:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第2张图片

1.3、开发标签

  这个标签的开发稍微有一点难度,因为这里面涉及到两个标签处理器类共享同一个变量的问题,如下:

 <c:when test="${user != null}">
     用户不为空
 c:when>
 <c:otherwise>
     用户为空
 c:otherwise>

  标签和标签对应着两个不同的标签处理器类,我们希望做到的效果是,如果标签执行了,那么就标签就不要再执行,那么这里面就涉及到一个问题:标签执行的时候该如何通知标签不要执行了呢?这个问题就涉及到了两个标签处理器类如何做到相互通讯的问题,如果标签执行了,就要通过某种方式告诉标签不要执行,那么该如何做到这样的效果呢?让标签处理器类和标签处理器类共享同一个变量就可以做到了,那么又该怎么做才能够让两个标签处理器类共享同一个变量呢,标准的做法是这样的:让两个标签拥有同一个父标签。

 1、开发父标签:ChooseTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * when标签和otherwise标签的父标签
 */
public class ChooseTag extends SimpleTagSupport {

    /**
     * 定义一个boolean类型的属性,该属性用于标识该标签下的某一个子标签是否已经执行过了,
     * 如果该标签下的某一个子标签已经执行过了,就将该属性设置为true
     */
    private boolean isExecute;

    @Override
    public void doTag() throws JspException, IOException {
        //输出标签体中的内容
        this.getJspBody().invoke(null);
    }

    public boolean isExecute() {
        return isExecute;
    }

    public void setExecute(boolean isExecute) {
        this.isExecute = isExecute;
    }
}

  2、开发when标签和otherwise标签

  WhenTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * when标签
 */
public class WhenTag extends SimpleTagSupport {

    /**
     * test属性,该属性值为true时,输出标签体中的内容
     */
    private boolean test;

    @Override
    public void doTag() throws JspException, IOException {
        //获取标签的父标签
        ChooseTag parentTag = (ChooseTag) this.getParent();
        if (test == true && parentTag.isExecute() == false) {
            //输出标签体中的内容
            this.getJspBody().invoke(null);
            //将父标签的isExecute属性设置为true,告诉父标签,我(when标签)已经执行过了
            parentTag.setExecute(true);
        }
    }

    public void setTest(boolean test) {
        this.test = test;
    }
}

  OtherWiseTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * otherwise标签
 */
public class OtherWiseTag extends SimpleTagSupport {

    @Override
    public void doTag() throws JspException, IOException {
        //获取标签的父标签
        ChooseTag parentTag = (ChooseTag) this.getParent();
        //如果父标签下的when标签没有执行过
        if (parentTag.isExecute() == false) {
            //输出标签体中的内容
            this.getJspBody().invoke(null);
            //设置父标签的isExecute属性为true,告诉父标签,我(otherwise标签)已经执行过了
            parentTag.setExecute(true);
        }
    }
}

  3、在WEB-INF目录下tld文件中添加对ChooseTag、WhenTag、OtherWiseTag这三对标签的描述,如下:

<tag>
        <description>choose标签description>
        <name>choosename>
        <tag-class>me.gacl.web.simpletag.ChooseTagtag-class>
        <body-content>scriptlessbody-content>
    tag>
    <tag>
        <description>when标签description>
        <name>whenname>
        <tag-class>me.gacl.web.simpletag.WhenTagtag-class>
        <body-content>scriptlessbody-content>
        <attribute>
            <description>when标签的test属性description>
            <name>testname>
            <rtexprvalue>truertexprvalue>
            <required>truerequired>
        attribute>
    tag>
    <tag>
        <description>otherwise标签description>
        <name>otherwisename>
        <tag-class>me.gacl.web.simpletag.OtherWiseTagtag-class>
        <body-content>scriptlessbody-content>
    tag>

  4、测试:在jsp页面中导入标签库并测试when和otherwise标签

<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="c" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="c"%>
--%>

<html>
  <head>
    <title>when和otherwise标签测试title>
  head>

  <body>
      <c:choose>
          <c:when test="${user==null}">
          when标签标签体输出的内容:
              <h3>用户为空h3>
          c:when>
          <c:otherwise>
              用户不为空
          c:otherwise>
      c:choose>
          <hr/>
      <c:choose>
          <c:when test="${user!=null}">
              用户不为空
          c:when>
          <c:otherwise>
          otherwise标签标签体输出的内容:
              <h3>用户为空h3>
          c:otherwise>
      c:choose>
  body>
html>

  运行效果如下:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第3张图片

1.4、开发foreach迭代标签

  1、编写标签处理器类:ForEachTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * ForEach迭代标签
 */
public class ForEachTag extends SimpleTagSupport {

    /**
     * 存储集合
     */
    private List items;

    /**
     * 迭代集合时使用的变量
     */
    private String var;

    public void setItems(List items) {
        this.items = items;
    }

    public void setVar(String var) {
        this.var = var;
    }

    @Override
    public void doTag() throws JspException, IOException {
        PageContext pageContext = (PageContext) this.getJspContext();
        Iterator it = items.iterator();
        while (it.hasNext()) {
            //得到一个迭代出来的对象
            Object object = (Object) it.next();
            //将迭代出来的对象存放到pageContext对象中
            pageContext.setAttribute(var, object);
            //输出标签体中的内容
            this.getJspBody().invoke(null);
        }
    }
}

  2、在WEB-INF目录下tld文件中添加对该标签的描述,如下:

<tag>
        <description>foreach标签description>
        <name>foreachname>
        <tag-class>me.gacl.web.simpletag.ForEachTagtag-class>
        <body-content>scriptlessbody-content>
        <attribute>
            <description>foreach标签的items属性description>
            <name>itemsname>
            <rtexprvalue>truertexprvalue>
            <required>truerequired>
        attribute>
        <attribute>
            <description>foreach标签的var属性description>
            <name>varname>
            <rtexprvalue>falsertexprvalue>
            <required>truerequired>
        attribute>
    tag>

  3、测试:在jsp页面中导入标签库并使用foreach标签

<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="c" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="c"%>
--%>

<html>
  <head>
    <title>foreach标签测试title>
  head>

<%
    List<String> data = new ArrayList<String>();
    data.add("孤傲苍狼");
    data.add("xdp");
    //将集合存储到pageContext对象中
    pageContext.setAttribute("data", data);
%>

  <body>
          <%--迭代存储在pageContext对象中的data集合 --%>
         <c:foreach items="${data}" var="str">
             ${str}<br/>
         c:foreach>
  body>
html>

  运行效果如下:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第4张图片

  目前这个foreach标签的功能较弱,只能遍历list集合,下面我们改造一下,使我们的foreach标签可以遍历所有集合类型,修改后foreach标签的代码如下:

package me.gacl.web.simpletag;

import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * ForEach迭代标签
 */
public class ForEachTag extends SimpleTagSupport {

    /**
     * 存储数据
     */
    private Object items;

    /**
     * 迭代集合时使用的变量
     */
    private String var;

    /**
     * 集合,用于存储items中的数据
     */
    private Collection collection;

    @Override
    public void doTag() throws JspException, IOException {
        PageContext pageContext = (PageContext) this.getJspContext();
        //迭代collection集合
        Iterator it = collection.iterator();
        while (it.hasNext()) {
            //得到一个迭代出来的对象
            Object object = (Object) it.next();
            //将迭代出来的对象存放到pageContext对象中
            pageContext.setAttribute(var, object);
            //输出标签体中的内容
            this.getJspBody().invoke(null);
        }
    }

    public void setVar(String var) {
        this.var = var;
    }

    public void setItems(Object items) {
        if (items instanceof Collection) {
            collection = (Collection) items;//list
        }else if (items instanceof Map) {
            Map map = (Map) items;
            collection = map.entrySet();//map
        }else if (items.getClass().isArray()) {
            collection = new ArrayList();
            //获取数组的长度
            int len = Array.getLength(items);
            for (int i = 0; i < len; i++) {
                //获取数组元素
                Object object = Array.get(items, i);
                collection.add(object);
            }
        }
        this.items = items;
    }
}

  测试功能增强后的foreach标签,如下:

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.HashSet"%>
<%@page import="java.util.Set"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="c" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="c"%>
--%>

<html>
  <head>
    <title>foreach标签测试title>
  head>

<%
    //list集合
    List<String> listData = new ArrayList<String>();
    listData.add("孤傲苍狼");
    listData.add("xdp");

    //对象数组
    Integer intObjArr[] = new Integer[]{1,2,3};

    //基本数据类型数组
    int intArr[] = new int[]{4,5,6};

    //map集合
    Map<String,String> mapData = new HashMap<String,String>();
    mapData.put("a", "aaaaaa");
    mapData.put("b", "bbbbbb");

    //将集合存储到pageContext对象中
    pageContext.setAttribute("listData", listData);
    pageContext.setAttribute("intObjArr", intObjArr);
    pageContext.setAttribute("intArr", intArr);
    pageContext.setAttribute("mapData", mapData);
%>

  <body>
          <%--迭代存储在pageContext对象中的list集合 --%>
         <c:foreach items="${listData}" var="str">
             ${str}<br/>
         c:foreach>
         <hr/>
         <%--迭代存储在pageContext对象中的数组 --%>
         <c:foreach items="${intObjArr}" var="num">
             ${num}<br/>
         c:foreach>
         <hr/>
         <%--迭代存储在pageContext对象中的数组 --%>
         <c:foreach items="${intArr}" var="num">
             ${num}<br/>
         c:foreach>
         <hr/>
             <%--迭代存储在pageContext对象中的map集合 --%>
         <c:foreach items="${mapData}" var="me">
             ${me}<br/>
         c:foreach>
  body>
html>

  测试结果:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第5张图片

1.5、开发html转义标签

  1、编写标签处理器类:HtmlEscapeTag.java

package me.gacl.web.simpletag;

import java.io.IOException;
import java.io.StringWriter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * html转义标签
 */
public class HtmlEscapeTag extends SimpleTagSupport {

    /**
     * @param message
     * @return 转义html标签
     */
    private String filter(String message) {

        if (message == null){
            return (null);
        }
        char content[] = new char[message.length()];
        message.getChars(0, message.length(), content, 0);
        StringBuilder result = new StringBuilder(content.length + 50);
        for (int i = 0; i < content.length; i++) {
            switch (content[i]) {
            case '<':
                result.append("<");
                break;
            case '>':
                result.append(">");
                break;
            case '&':
                result.append("&");
                break;
            case '"':
                result.append(""");
                break;
            default:
                result.append(content[i]);
            }
        }
        return (result.toString());
    }

    @Override
    public void doTag() throws JspException, IOException {
        StringWriter sw = new StringWriter();
        //将标签体中的内容先输出到StringWriter流
        this.getJspBody().invoke(sw);
        //得到标签体中的内容
        String content = sw.getBuffer().toString();
        //转义标签体中的html代码
        content = filter(content);
        //输出转义后的content
        this.getJspContext().getOut().write(content);
    }
}

  2、在WEB-INF目录下tld文件中添加对该标签的描述,如下:

 <tag>
     <description>HtmlEscape标签description>
     <name>htmlEscapename>
     <tag-class>me.gacl.web.simpletag.HtmlEscapeTagtag-class>
     <body-content>scriptlessbody-content>
 tag>

  3、测试:在jsp页面中导入标签库并使用htmlEscape标签

<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="c" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="c"%>
--%>

<html>
  <head>
    <title>html转义标签测试title>
  head>

  <body>
          <c:htmlEscape>
              <a href="http://www.cnblogs.com">访问博客园a>
          c:htmlEscape>
  body>
html>

  运行结果:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第6张图片

1.6、开发out输出标签

  1、编写标签处理器类:OutTag.java

package me.gacl.web.simpletag;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.SimpleTagSupport;

/**
 * @author gacl
 * 开发输出标签
 */
public class OutTag extends SimpleTagSupport {

    /**
     * 要输出的内容
     */
    private String content;

    /**
     * 是否将内容中的html进行转义后输出
     */
    private boolean escapeHtml;

    public void setContent(String content) {
        this.content = content;
    }

    public void setEscapeHtml(boolean escapeHtml) {
        this.escapeHtml = escapeHtml;
    }

    @Override
    public void doTag() throws JspException, IOException {
        if (escapeHtml == true) {
            //转义内容中的html代码
            content = filter(content);
            //输出转义后的content
            this.getJspContext().getOut().write(content);
        }else {
            this.getJspContext().getOut().write(content);
        }
    }

    /**
     * @param message
     * @return 转义html标签
     */
    private String filter(String message) {

        if (message == null){
            return (null);
        }
        char content[] = new char[message.length()];
        message.getChars(0, message.length(), content, 0);
        StringBuilder result = new StringBuilder(content.length + 50);
        for (int i = 0; i < content.length; i++) {
            switch (content[i]) {
            case '<':
                result.append("<");
                break;
            case '>':
                result.append(">");
                break;
            case '&':
                result.append("&");
                break;
            case '"':
                result.append(""");
                break;
            default:
                result.append(content[i]);
            }
        }
        return (result.toString());
    }
}

  2、在WEB-INF目录下tld文件中添加对该标签的描述,如下:

<tag>
        <description>out标签description>
        <name>outname>
        <tag-class>me.gacl.web.simpletag.OutTagtag-class>
        <body-content>emptybody-content>
        <attribute>
            <description>out标签的content属性,表示要输出的内容description>
            <name>contentname>
            <rtexprvalue>truertexprvalue>
            <required>truerequired>
        attribute>
        <attribute>
            <description>out标签的escapeHtml属性,表示是否将内容中的html进行转义后输出description>
            <name>escapeHtmlname>
            <rtexprvalue>truertexprvalue>
            <required>falserequired>
        attribute>
    tag>

  3、测试:在jsp页面中导入标签库并使用out标签

<%@ page language="java" pageEncoding="UTF-8"%>
<%--在jsp页面中导入自定义标签库 --%>
<%@taglib uri="/gaclTagLib" prefix="c" %>
<%--在jsp页面中也可以使用这种方式导入标签库,直接把uri设置成标签库的tld文件所在目录
<%@taglib uri="/WEB-INF/TagLib.tld" prefix="c"%>
--%>

<html>
  <head>
    <title>out标签测试title>
  head>

  <body>
          <%--使用out标签输出content属性的内容 --%>
          <c:out content="访问博客园"/>
          <hr/>
          <%--使用out标签输出 content属性的内容,内容中的html代码会进行转义处理--%>
          <c:out content="访问博客园" escapeHtml="true"/>
  body>
html>

  运行效果如下:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第7张图片

二、打包开发好的标签库

  我们的标签库开发好之后,为了方便别人使用,可以将开发好的标签库打包成一个jar包,具体的打包步骤如下:

  1、新建一个普通的java工程,例如:taglib

  这里写图片描述

  2、将在JavaWeb_JspTag_study_20140816这个web工程中开发好标签库的java代码拷贝到普通java工程taglib项目中,如下:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第8张图片深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第9张图片

  此时,我们可以看到,拷贝到taglib项目的标签代码都有错误,这是因为taglib项目中缺少了javaEE的jar包,而标签类是是基于javaEE API进行开发的,所以还需要将javaEE的jar包添加到taglib项目中。

  在taglib项目中创建一个【lib】文件夹,用于存放标签类依赖的javaEE的jar包。找到tomcat服务器目录下的lib文件夹,如下图所示:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第10张图片

  将【jsp-api.jar】【servlet-api.jar】这两个jar包拷贝到tagib项目中的lib文件夹中,然后添加【jsp-api.jar】【servlet-api.jar】这两个jar包的引用,如下所示:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第11张图片

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第12张图片

  在taglib项目中引用了【jsp-api.jar】和【servlet-api.jar】这两个jar包后,标签类中的代码就不再报错了

  3、在taglib项目中添加一个【META-INF】文件夹,如下所示:

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第13张图片

  将位于WEB-INF目录下的标签库对应的tld文件拷贝到taglib项目的【META-INF】文件夹中

  深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第14张图片深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第15张图片

  4、将taglib项目打包成jar包

  
深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第16张图片
  
深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第17张图片
  
深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第18张图片
  
深入分析JavaWeb Item25 -- 自定义标签开发案例和打包自定义标签库_第19张图片

  此时就可以看到我们打包好的jar包了,如下所示:

这里写图片描述

你可能感兴趣的:(JavaWeb,深入分析javaweb)