Java学习日记11:JSP自定义标签

声明:文章中的标签中的执行顺序图片都来自给我上课的老师,仅用于个人学习记录用。

在jsp中,标签就是jsp转化为Java代码时,会转换为固定的,对应的Java代码
在这里自定义标签,当页面转换为Java代码时,就会转会为我们自己想要的代码啦!

下面就来介绍一些接口:(如果有不熟悉的地方就去查JavaEE的API,这些接口都在javax.servlet.jsp.tagext包下)

Tag:

tag

index.jsp

有两个要注意的地方:一个是页面开头的
<%@taglib uri="http://www.xxx.com/uri" prefix="my" %>
一个是<my:now color="red"/>

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://www.xxx.com/uri" prefix="my" %><!-- 这里对应my.ltd文件 -->
<!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>Insert title here</title>
</head>
<body>


<%-- <jsp:include page="inc.html"></jsp:include> --%>
<!-- 上面这一行是jsp的注释 -->




<!-- 这个是自定义标签。在jsp中,标签就是jsp转化为Java代码时,会转换为固定的,对应的Java代码
在这里自定义标签,当页面转换为Java代码时,就会转会为我们自己想要的代码啦! -->

<!-- 这里的自定义标签就是写成显示现在的时间。 -->
<my:now color="red"/>
<!-- 然后就是写对应的Java代码,这里继承实现Tag类 -->

</body>
</html>

这里的<my:now color="red"/>就是自定义标签。

对应的Java类:

package com.tags;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

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

public class TimeTag implements Tag //这里实现的是Tag接口
{
   private  Tag parent;
   private PageContext pc;


   private String color;

    public TimeTag()//构造方法1
    {
        System.out.println("实例化TimeTag.....");
    }

    @Override
    public int doEndTag() //结束读标签4
            throws JspException
    {
        System.out.println("doEndTag................");

        Date date=new Date();
        SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String re=df.format(date);

        try {
            //这里用PageContext的对象的getOut()方法(这样就能在页面中输出了)。
            pc.getOut().println("<h1 style='color:"+this.color+";'>"+re+"</h1>");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return Tag.EVAL_PAGE;
    }

    @Override
    public int doStartTag() //开始读标签3
            throws JspException 
    {
        System.out.println("doStartTag............");
        return Tag.SKIP_BODY;
        /*这里的常量有4个值
         *  static int  EVAL_BODY_INCLUDE   评估标签中的东西到输出流(但是获取不了)
          Evaluate body into existing out stream.

static int  EVAL_PAGE    执行页面中的剩下的内容
          Continue evaluating the page.

static int  SKIP_BODY     不执行页面中的剩下的内容
          Skip body evaluation.

static int  SKIP_PAGE     不评估标签中的东西
          Skip the rest of the page
         * 
         * 
         * */
    }

    @Override
    public Tag getParent()//得到父标签2
    {
        // TODO Auto-generated method stub
        return this.parent;
    }

    @Override
    public void release()//释放的时候执行此方法5
    {
        System.out.println("release..........");

    }

    @Override
    public void setPageContext(PageContext arg0)//设置pageContext2
    {
        System.out.println("setPageContext........");
        this.pc=arg0;

    }

    @Override
    public void setParent(Tag arg0)//设置父标签2
    {
        System.out.println("setparent........");
        this.parent=arg0;

    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) //设置颜色2
    {
        System.out.println("setColor.....");
        this.color = color;
    }



}

用一个ltd文件吧我们的jsp和Java联系起来:

<taglib 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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>http://www.xxx.com/uri</uri><!-- 对应jsp的<%@taglib uri="http://www.xxx.com/uri" prefix="my" %> -->
    <tag>
        <description>Outputs Hello, World</description>
        <name>now</name><!-- 这个名字对应index中的自定义标签中的now -->
        <tag-class>com.tags.TimeTag</tag-class><!-- 这里对应写的Java类 -->
        <body-content>empty</body-content><!-- 如果要用标签中的body的内容这里就不能是empty -->
         <attribute>
            <name>color</name><!-- 有了这个index中的color属性就能传进TimeTig中对应的方法了 -->
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
    </tag>

这个ltd文件的名字是根据自定义标签的标签名命名的。(这里叫my.ltd)

Tag(标签中有Body):

Index.jsp

<my:now color="red">
   第一个标签
</my:now>

My.ltd文件:

 <body-content>scriptless</body-content><!-- 这里不是empty了,因为对应标签的body中有东西 -->

这个的ltd文件我只把和刚才不同的地方写出来。

TimeTag这个Java类:

这个类中只是有些方法里面不一样。

    @Override
    public int doStartTag() throws JspException 
    {
        System.out.println("doStartTag............");
        return Tag.EVAL_BODY_INCLUDE;//将标签中的body 输出到输出流中,这个常量就会读出body。
    }

IterationTag:

这个借口是刚才的Tag接口的子接口。这个接口可以实现循环多次body。
IterationTag

Index.jsp

<my:table row="10">
    <tr><td>${sid}<!-- sid.getPageContext --></td><td>b</td><td>c</td></tr>
    </my:table>

My.ltd文件:

<taglib 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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>http://www.xxx.com/uri</uri>
    <tag>
        <description>Outputs Hello, World</description>
        <name>table</name>
        <tag-class>com.tags.TableTag</tag-class>
        <body-content>scriptless</body-content>
         <attribute>
            <name>row</name>
            <required>true</required>
            <rtexprvalue>true</rtexprvalue>
        </attribute>
</tag>

TableTag类:

package com.tags;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.IterationTag;
import javax.servlet.jsp.tagext.Tag;

public class TableTag implements IterationTag //这里就是实现的IterationTag接口
{

    private int row;
    private PageContext pc;
    private int index=1;


    @Override
    public int doEndTag() throws JspException 
    {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public int doStartTag() throws JspException 
    {
        pc.setAttribute("sid",index);//这里是设置第一个sid,index是1的时候,下面body里面在设置后续的,因为这里只运行一次

        // TODO Auto-generated method stub
        return Tag.EVAL_BODY_INCLUDE;
    }

    @Override
    public Tag getParent() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void release() {
        // TODO Auto-generated method stub

    }

    @Override
    public void setPageContext(PageContext arg0)//设置PageContext
    {
    this.pc=arg0;

    }

    @Override
    public void setParent(Tag arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public int doAfterBody() throws JspException 
    {
        if(--row>0)//因为row一开始已经运行了一次,所以这里是--row
        {
            index++;
            pc.setAttribute("sid",index);//这里是设置除了第一个的sid,因为这里能循环
          return IterationTag.EVAL_BODY_AGAIN;//设置这个就是再执行一遍标签中的body的内容
        }
        else
            return Tag.SKIP_BODY;
    }

    public int getRow() {
        return row;
    }

    public void setRow(int row) //设置行数
    {
        this.row = row;
    }

}

BodyTag:

先看API。这个接口是IterationTag的子接口。可以读写标签中的body部分。
BodyTag

Index.jsp

<my:block>
   我的邮件是:773669388@qq.com<!-- 这里要做到的是将前面的数字换成8888,并且显示到一个框里 -->
</my:block>

My.ltd文件:

<uri>http://www.xxx.com/uri</uri>
    <tag>
        <description>Outputs Hello, World</description>
        <name>block</name>
        <tag-class>com.tags.BlockTag</tag-class>
        <body-content>scriptless</body-content>

</tag>

BlockTag类:

package com.tags;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.Tag;
// 新增了一个用作返回值的常量和一个新方法,实现该接口的标签处理器可以在其内部对标签体执行后的内容进行处理。

public class BlockTag implements BodyTag //这里是实现了BodyTag类,这个类能读写body的内容
//从父类往下:Tag->IterationTag->BodyTag
{

    private BodyContent bodyContent;
    private PageContext pc;



    @Override
    public int doAfterBody() throws JspException {
        // TODO Auto-generated method stub
        return Tag.SKIP_BODY;
    }

    @Override
    public int doEndTag() throws JspException 
    {
        StringBuilder sb=new StringBuilder();
        //Return the value of the BodyContent as a String.把Body中的诗句返回到这里,以字符串的形式
        String msg=bodyContent.getString();
        String newmsg=msg.replace("773669388","8888");
        sb.append("<div style='width:200px;height:200px;border:1px #ccc solid; line-height:200px;text-align:center;'>");
        sb.append(newmsg);

        sb.append("</div>");


        try {
            //bodyContent.getEnclosingWriter().println(sb.toString());
            pc.getOut().println(sb.toString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        return Tag.EVAL_PAGE;
    }

    @Override
    public int doStartTag() throws JspException {
        // TODO Auto-generated method stub
        return BodyTag.EVAL_BODY_BUFFERED;//然后执行doInitBody()然后是Body然后是doAfterBody()
    }

    @Override
    public Tag getParent() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void release() {
        // TODO Auto-generated method stub

    }

    @Override
    public void setPageContext(PageContext arg0) //设置PageContext,参数是通过哪里传进来的
    {
        // TODO Auto-generated method stub
         this.pc=arg0;
    }

    @Override
    public void setParent(Tag arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void doInitBody() throws JspException {
        // TODO Auto-generated method stub

    }

    @Override
    public void setBodyContent(BodyContent arg0) {
        // TODO Auto-generated method stub
       this.bodyContent=arg0;
    }

}

BodyTagSupport:

这个类是一个实现类,实现了BodyTag, IterationTag, JspTag, Tag这些接口,并且有一个常量:bodyContent,是BodyContent类实例化的对象,已经实例化好的,可以直接用。

Index.jsp

<my:block>
   我的邮件是:773669388@qq.com
</my:block>

My.ltd文件:

 <uri>http://www.xxx.com/uri</uri>
    <tag>
        <description>Outputs Hello, World</description>
        <name>block</name>
        <tag-class>com.tags.BlockTag</tag-class>
        <body-content>scriptless</body-content>

</tag>

BlockTag类:

package com.tags;

import java.io.IOException;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTag;
import javax.servlet.jsp.tagext.BodyTagSupport;
import javax.servlet.jsp.tagext.Tag;

public class BlockTag extends BodyTagSupport//implements BodyTag 
{
    //这个类好像直接可以用bodycontent。具体多看看API


    @Override
    public int doEndTag() throws JspException 
    {
        StringBuilder sb=new StringBuilder();

        String msg=bodyContent.getString();
        String newmsg=msg.replace("773669388","8888");
        sb.append("<div style='width:200px;height:200px;border:1px #ccc solid; line-height:200px;text-align:center;'>");
        sb.append(newmsg);

        sb.append("</div>");


        try {
            //bodyContent.getEnclosingWriter().println(sb.toString());
            pageContext.getOut().println(sb.toString());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


        return Tag.EVAL_PAGE;
    }

    @Override
    public int doStartTag() throws JspException {
        // TODO Auto-generated method stub
        return BodyTag.EVAL_BODY_BUFFERED;
    }
}

TagSupport:

这个也是一个实现类,和BodyTagSupport比较类似。里面封装的常量不同。

这次的例子是用的ajax中使用的例子,实现选择省市的那个。不过这是用自定义标签实现。

Index.jsp

Index.jsp
<select id="pro">
   <my:allpro/>
   </select>

My.ltd文件:

<taglib 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 http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
    version="2.0">
    <description>A tag library exercising SimpleTag handlers.</description>
    <tlib-version>1.0</tlib-version>
    <short-name>SimpleTagLibrary</short-name>
    <uri>/newajax</uri>
    <tag>
        <description>Outputs Hello, World</description>
        <name>allpro</name>
        <tag-class>com.tags.AllProTag</tag-class>
        <body-content>empty</body-content>

</tag>

AllProTag类:

AllProTag类:
package com.tags;

import java.sql.SQLException;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.Tag;
import javax.servlet.jsp.tagext.TagSupport;
import javax.sql.DataSource;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.alibaba.fastjson.JSONObject;
import com.pojo.Area;

public class AllProTag extends TagSupport


/*这个类
 *  Field Summary
    id
          The value of the id attribute of this tag; or null.
    pageContext
          The PageContext.
 * 
 * */
{

    @Override
    public int doStartTag() throws JspException {
        // TODO Auto-generated method stub
        return Tag.SKIP_BODY;
    }

    @Override
    public int doEndTag() throws JspException 
    {
        DataSource ds=(DataSource)pageContext.getServletContext().getAttribute("ds");
        StringBuilder sb=new StringBuilder();
        QueryRunner run=new QueryRunner(ds);
        String sql="select * from area where parentid=? and style=?";
        List<Area> first=null;
        try {
            first=run.query(sql, new BeanListHandler<Area>(Area.class),0,0);

            for(Area a:first)
            {
                sb.append("<option value='"+a.getId()+"'>"+a.getName()+"</option>");
            }

            pageContext.getOut().println(sb.toString());

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }       
        return super.doEndTag();
    }

}

——————————————–分割线————————————–

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值