声明:文章中的标签中的执行顺序图片都来自给我上课的老师,仅用于个人学习记录用。
在jsp中,标签就是jsp转化为Java代码时,会转换为固定的,对应的Java代码
在这里自定义标签,当页面转换为Java代码时,就会转会为我们自己想要的代码啦!
下面就来介绍一些接口:(如果有不熟悉的地方就去查JavaEE的API,这些接口都在javax.servlet.jsp.tagext
包下)
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。
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部分。
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();
}
}
——————————————–分割线————————————–