java EE开发之Servlet第十二课:简单自定标签
来源:互联网 发布:网络release是什么意思 编辑:程序博客网 时间:2024/06/01 09:16
1 . 什么是自定义标签
尽管JSP本身,以及第三方提供了很多标签库,但因为业务需要,我们有时还是需要自定义标签。因为JSP页面中不可以存在Java代码,所以我们需要自定义标签!
2 .标签的真身
其实我们现在应该可以了解了,真的是万物皆对象。JSP可以是一个对象,当然标签也可以是一个对象。其实在页面中使用的标签就是对一个对象的方法调用!
标签:
- 标签处理类:都有自己的标签处理类!所有标签处理类都必须去实现Tag或SimpleTag接口;
- TLD(Tag Library Description):一个TLD文件中可以部署多个标签!JSP会通过TLD文件找到标签! (webapps\examples\WEB-INF\jsp2,这里有模板)
3,SimpleTag
1) SimpleTag是什么
标签处理类必须实现JspTag接口,而JspTag接口有两个子接口:Tag和SimpleTag。更加确切的说:标签处理类必须实现Tag或SimpleTag接口。
JSP2.0之后,SUN提供了SimpleTag接口,通过SimpleTag接口来实现标签处理类要比Tag这种传统方式方便很多,所以现在我们可以大声与Tag说再见了。
SimpleTag接口内容如下:
void doTag():标签执行方法;
JspTag getParent():获取父标签;
void setParent(JspTag parent):设置父标签
void setJspContext(JspContext context):设置PageContext
void setJspBody(JspFragment jspBody):设置标签体对象;
4 .自定义标签方式一:实现SimpleTag接口的自定义标签
案例:定义一个Hello SimpleTag的简单标签
标签类的定义:
public class HelloTag implements SimpleTag { private PageContext pageContext; public void doTag() throws JspException, IOException { pageContext.getOut().write("<p>Hello SimpleTag!</p>"); } public void setJspContext(JspContext pc) { this.pageContext = (PageContext) pc; } public void setParent(JspTag parent) {} public JspTag getParent() {return null;} public void setJspBody(JspFragment jspBody) {}}
TLD文件的定义
注意: [把tld文件放到classes\META-INF\hello.tld路径]
<?xml version="1.0" encoding="UTF-8"?><taglib version="2.0" xmlns="http://java.sun.com/xml/ns/j2ee"xmlns:xml="http://www.w3.org/XML/1998/namespace" 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 "><tlib-version>1.0</tlib-version><short-name>kzkate</short-name><uri>http://www.kzkate.cn/kzkate-tags</uri><tag> <name>hello</name> <tag-class>cn.kzkate.simpletags.HelloTag</tag-class> <body-content>empty</body-content></tag></taglib>
jsp中使用
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib prefix="kzkate" uri="http://www.kzkate.cn/kzkate-tags" %>...... <body> This is my JSP page. <br> <kzkate:hello/> </body>
5 .自定义标签方式二:继承SimpleTagSupport的自定义标签
public class HelloTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { this.getJspContext().getOut().write("<p>Hello SimpleTag!</p>"); }}
6 .有标签体的标签
标签类
public class HelloTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { PageContext pc = (PageContext) this.getJspContext(); HttpServletRequest req = (HttpServletRequest) pc.getRequest(); String s = req.getParameter("exec"); if(s != null && s.endsWith("true")) { //[获取当前标签的标签体对象]; JspFragment body = this.getJspBody() JspWriter out = pc.getOut(); //[执行标签体。如果使用null来调用invoke()方法,那么默认是使用当前页面的输出流!即使用null与当前的效果相同。] body.invoke(out); } }}
TLD文件
<tag> <name>hello</name> <tag-class>cn.kzkate.simpletags.HelloTag</tag-class> <body-content>scriptless</body-content></tag>
jsp中使用
<kzkate:hello> <h1>哈哈哈~</h1></kzkate:hello>
body-content元素的可选值有:
empty:不能有标签体内容。
JSP:标签体内容可以是任何东西:EL、JSTL、<%=%>、<%%>,以及html;但不建议使用Java代码段,SimpleTag已经不再支持使用JSP
scriptless:标签体内容不能是Java代码段,但可以是EL、JSTL等;
tagdependent:标签体内容不做运算,由标签处理类自行处理,无论标签体内容是EL、JSP、JSTL,都不会做运算。
public class HelloTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { PageContext pc = (PageContext) this.getJspContext(); HttpServletRequest req = (HttpServletRequest) pc.getRequest(); String s = req.getParameter("exec"); if(s != null && s.endsWith("true")) { //[获取当前标签的标签体对象]; JspFragment body = this.getJspBody(); JspWriter out = pc.getOut(); //[执行标签体。如果使用null来调用invoke()方法,那么默认是使用当前页面的输出流!即使用null与当前的效果相同。] body.invoke(out); } }}
<tag> <name>hello</name> <tag-class>cn.kzkate.simpletags.HelloTag</tag-class> <body-content>scriptless</body-content></tag>
<kzkate:hello> <h1>哈哈哈~</h1></kzkate:hello>
7,不执行标签下面的页面内容
我们知道,在使用Tag接口来编写标签时,可以跳过标签下面的JSP页面内容。在SimpleTag中也是可以的,这需要在doTag()方法中抛出SkipPageException。
SkipPageException是JspException的子类,当doTag()方法抛出该异常时,JSP真身不会打印异常信息,而是跳转页面内容!
public class SkipTag extends SimpleTagSupport { public void doTag() throws JspException, IOException { this.getJspContext().getOut().print("<h1>只能看到我!</h1>"); throw new SkipPageException(); }}
<tag> <name>skip</name> <tag-class>cn.kzkate.simpletags.SkipTag</tag-class> <body-content>empty</body-content></tag>
<kzkate:skip/> <h1>看不见我!</h1>
8,带有属性的标签
- 在处理类中添加属性,以及getter/setter方法;
- 在TLD中部属相关属性。
public class DemoTag extends SimpleTagSupport { private String name; public String getName() { return name; } //[Servlet在执行标签时会先调用setName()方法把值传递给处理类,然后再调用doTag()方法。] public void setName(String name) { this.name = name; } public void doTag() throws JspException, IOException { this.getJspContext().getOut().print("hello " + name); }}
<tag> <name>demo</name> <tag-class>cn.kzkate.simpletags.DemoTag</tag-class> <body-content>empty</body-content> <attribute> //[tag>中可以有0~n个<attribute>元素,每个<attribute>表示一个属性。] //[定属性名(必须给出<name>),当指定的属性为name时,那么标签处理类必须有setName()方法。getName()可以没 //有。因为Servlet会调用setName()传递值给标签处理类] <name>name</name> //[属性是否为必须的。默认值为false,表示属性不是必须的。] <required>true</required> //[属性是否可以是表达式。如EL表达式,以及<%=xxx%>。默认值为false,表示不能是表达式。] <rtexprvalue>false</rtexprvalue> </attribute></tag>
<%pageContext.setAttribute("name", "liSi");String name = "wangWu";%> <kzkate:demo name="zhangSan"/><br/> <kzkate:demo name="${name }"/><br/> <%--[因为<rtexprvalue>为false,所以属性值为能否是动态表达式,所以${name}和<%=name%>都是非法的。]--%> <kzkate:demo name="<%=name %>"/>
9,综合案例:自定义分页标签和时间格式化标签
分页标签类
public class PageTag extends SimpleTagSupport { private int curPage;//当前页 private int pageSize;//每页显示的条数; private int total;//总页数 private String url;//点击上一页或下一页跳转到哪个请求进行处理数据 private String className = "tres"; public void doTag() throws JspException, IOException { JspWriter out = this.getJspContext().getOut(); StringBuffer str = new StringBuffer(); str.append("<div align='center' class='"+className+"'>"); if(curPage==1){ str.append("首页 上一页"); }else{ str.append("<a href='"+url+"&curPage=1'>首页 </a>"); str.append("<a href='"+url+"&curPage="+(curPage-1)+"'>上一页</a>"); } str.append("当前第"+curPage+"页共"+total+"页"); if(curPage!=total){ str.append("<a href='"+url+"&curPage="+(curPage+1)+"'>下一页 </a>"); str.append("<a href='"+url+"&curPage="+total+"'>末页</a>"); }else{ str.append("下一页 末页"); } str.append("<form action='listAction.do?method=list' method='post'>"); str.append("<input size='3' name='curPage'>"); str.append("<input type='submit' value='Go'>"); str.append("</form>"); str.append("</div>"); /*str.append("<script>"); str.append("function validate(){"); str.append("}"); str.append("</script>");*/ out.println(str); } //省略get/set方法}
日期标签类
public class DateTag extends SimpleTagSupport { //设定日期的格式 private String parttern = "yyyy-MM-dd E"; //指定日期 private Date value ; @Override public void doTag() throws JspException, IOException { //获取输出流对象 JspWriter out = this.getJspContext().getOut(); SimpleDateFormat sf = new SimpleDateFormat(parttern); //Date d = new Date(); String str = sf.format(value); out.println(str); } //省略get/set方法}
分页标签和日期标签TLD
<?xml version="1.0" encoding="UTF-8" ?><taglib xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd" version="2.1"> <description>这是我们自定义的标签</description> <display-name>My core</display-name> <tlib-version>1.0</tlib-version> <short-name>my</short-name> <uri>/mytag</uri> <tag> <description> 这是一个日期标签 </description> <name>date</name> <tag-class>com.cshr.tag.DateTag</tag-class> <body-content>empty</body-content> <!-- 设置标签的属性 --> <attribute> <description>这个属性用来设置日期的格试</description> <name>parttern</name> <!-- 是否为必须属性 --> <required>false</required> <!-- 是否支持动态表达式 --> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <description>这个属性用来设置日期的值</description> <name>value</name> <!-- 是否为必须属性 --> <required>true</required> <!-- 是否支持动态表达式 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <description> 这是一个分页标签 </description> <name>page</name> <tag-class>com.cshr.tag.PageTag</tag-class> <body-content>empty</body-content> <!-- 设置标签的属性 --> <attribute> <description>这个属性用来设置当前页数</description> <name>curPage</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <description>这个属性用来设置每页显示多少条数据</description> <name>pageSize</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <description>这个属性用来设置总页数</description> <name>total</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <description>这个属性用来设置请求的地址</description> <name>url</name> <required>true</required> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <description>这个属性用来设置CSS</description> <name>className</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag></taglib>
jsp中测试
......<%@ taglib uri="/mytag" prefix="my" %><%@ taglib uri="/mytag" prefix="my" %><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %><% Date d = new Date(2012-1900,11,12); request.setAttribute("d",d);%>.......<!-- 自定义日期标签 --><my:date value="${d}" parttern="yyyy/MM/dd"/><fmt:formatDate value="${d}" pattern="yyyy/MM/dd" /><!-- 自定义分页标签 --><my:page pageSize="${pageSize}" url="listAction.action?method=list" total="${total}" curPage="${curPage}" className="badoo"/>
- java EE开发之Servlet第十二课:简单自定标签
- java EE开发之Servlet第十三课:复杂自定标签
- java EE开发之Servlet第一课
- java EE开发之Servlet第三课:过滤器(Filter)
- java EE开发之Servlet第四课:监听器(Listener)
- java EE开发之Servlet第五课:xml解析
- java EE开发之Servlet第六课:神奇的Ajax
- java EE开发之Servlet第七课:JNDI
- java EE开发之Servlet第十一课:反射基础三
- java EE开发之Servlet第十四课:自定义注解Annotation
- Java EE开发第十二章:1.Servlet之Response相应(重定向、操作相应体、文件下载、随机验证码)
- jsp自定标签tld文件
- 创建jsp自定标签步骤
- java ee 之 servlet
- java EE开发之Servlet第二课:Servlet的三个hashMap
- Java EE开发第十二章:2.Servlet之Request请求(请求行、头、体、转发,转发和重定向区别,中文乱码)
- Java EE之Servlet技术
- Java EE之Servlet技术
- 蓝桥杯训练——顺序存储的二叉树的最近的公共祖先问题
- Alert换行,根据特殊字符换行
- Hoj2739
- rcu的理解
- P4241【NOIP2016 DAY2】蚯蚓
- java EE开发之Servlet第十二课:简单自定标签
- Web安全之SQL注入
- Java中集合(二)Vector
- Dubbo+Zookeeper+Spring整合入门Demo
- Drozer的使用
- Nagios
- 判断字典是否包含特定Key值
- CCN(content centric networking)介绍
- maven部署war远程服务器