自定义标签学习

来源:互联网 发布:中国频道 域名转出 编辑:程序博客网 时间:2024/06/05 23:26

自定义标签为了避免jsp中出现java代码,以至于view层混乱,所以自定义标签使View层更简洁。

1.写一个继承了TagSupport类的java类,如下

public class ViewIPTag extends TagSupport {@Overridepublic int doStartTag() throws JspException {HttpServletRequest request=(HttpServletRequest) this.pageContext.getRequest();JspWriter out=this.pageContext.getOut();try {out.println(request.getRemoteAddr());} catch (IOException e) {throw new RuntimeException(e);} return super.doStartTag();}}
2.在WEB-INF目录下写tld文件,记得写uri,使其绑定到某个链接上,当jsp关联这个链接,就相当于使用了tld同链接的tag,如下

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE taglib        PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"        "http://java.sun.com/j2ee/dtd/web-jsptaglibrary_1_2.dtd"><taglib>  <tlib-version>1.0</tlib-version>  <jsp-version>1.2</jsp-version>  <short-name>debug</short-name>  <uri>http://www.wanhao.com</uri>  <tag>    <name>viewIP</name>    <tag-class>com.wanhao.ViewIPTag</tag-class>    <body-content>TAGDEPENDENT</body-content>  </tag></taglib>
3.写jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%@ taglib uri="http://www.wanhao.com"  prefix="wan"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html>  <head>    <base href="<%=basePath%>">        <title>My JSP '2.jsp' starting page</title>    <meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0">    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><!--<link rel="stylesheet" type="text/css" href="styles.css">-->  </head>    <body>      您的ip是:<wan:viewIP/>  </body></html>


自定义标签还可以

1.控制是否显示标签内文本:

当实现TagSupport的类返回  EVAL_BODY_INCLUDE 时,显示标签内的文本内容。

当其返回 SKIP_BODY 时,不显示标签内文本内容。

2.控制这个jsp的剩余页面是否显示,只需要重写doEndTag()方法

@Overridepublic int doEndTag() throws JspException {// TODO Auto-generated method stubreturn SKIP_PAGE;}

3.重复标签内容

主要重写两个方法,若是doAfterBody()方法返回  EVAL_BODY_AGAIN ,则重新执行标签

static int i=5;@Overridepublic int doAfterBody() throws JspException {i--;if(i>0)return EVAL_BODY_AGAIN;elsereturn SKIP_BODY;}@Overridepublic int doStartTag() throws JspException {// TODO Auto-generated method stubreturn EVAL_BODY_INCLUDE;}

4.修改标签内容

需要继承BodyTagSupport类,实现doStartTag()返回EVAL_BODY_BUFFERED时,把BodyContent内容传给doEndTag()

public class Demo4 extends BodyTagSupport {@Overridepublic int doStartTag() throws JspException {// TODO Auto-generated method stubreturn EVAL_BODY_BUFFERED;}@Overridepublic int doEndTag() throws JspException {BodyContent bc= getBodyContent();String con=bc.getString();try {pageContext.getOut().println(con.toUpperCase());} catch (IOException e) {e.printStackTrace();}return EVAL_PAGE;}}

上面的内容在做项目中不太常见,因为还有更加简便的方法,之所以介绍上述方法,是为了便于以后读懂框架代码。

接下来就介绍更简便的方法。

写一个实现了 SimpleTagSupport 的类,其它的和上述相同,只需要这一个类便可以实现所有功能。

1.控制标签体内容的显示与隐藏

取消注释表示没有将 JspFragment 中的内容加入输出流对象的缓冲区,不会显示,反之显示

public class SimpleTag extends SimpleTagSupport {@Overridepublic void doTag() throws JspException, IOException {JspFragment jf=this.getJspBody();//jf.invoke(this.getJspContext().getOut());}}
2.控制标签内容重复展示

也可以写 jf.invoke(null); 这不是将 JspFragment 的对象内容注入空流对象 ,而是默认对 JspContext() 对应输出流对象注入信息。

public class SimpleTag extends SimpleTagSupport {@Overridepublic void doTag() throws JspException, IOException {JspFragment jf=this.getJspBody();for(int i=0;i<5;++i)jf.invoke(this.getJspContext().getOut());}}
3.跳过jsp页面的剩余部分

@Overridepublic void doTag() throws JspException, IOException {throw new SkipPageException();}
4.修改标签内容

先把输出信息传给StringWiter流对象(其父类Writer),获取字符串并改变后,将结果加到真正在页面显示的流对象的缓冲区。

public class SimpleTag extends SimpleTagSupport {@Overridepublic void doTag() throws JspException, IOException { JspFragment jf = this.getJspBody(); StringWriter sw=new StringWriter(); jf.invoke(sw); String content=sw.toString().toUpperCase();  this.getJspContext().getOut().write(content); }}


简单标签的高级用法:

给标签加上属性值

1.在对应的实现类加上一个属性,并声明其get set方法。

2.在调用此标签的实先tld文件的标签中,加入这一属性,并建议设置  

    <required>true</required>
    <rtexprvalue>true</rtexprvalue>   控制是否标签属性可以是表达式,如${} <%= %>等

例如:

public class SimpleTag extends SimpleTagSupport {private Date today;public Date getToday() {return today;}public void setToday(Date today) {this.today = today;}@Overridepublic void doTag() throws JspException, IOException { JspFragment jf = this.getJspBody(); StringWriter sw=new StringWriter(); sw.write(today.toLocaleString()); jf.invoke(sw); String content=sw.toString().toUpperCase();  this.getJspContext().getOut().write(content); }}
   <tag>    <name>SimpleDemo4</name>    <tag-class>com.wanhao.SimpleTag</tag-class>    <body-content>scriptless</body-content>    <attribute>    <name>today</name>    <required>true</required>    <rtexprvalue>true</rtexprvalue>    </attribute>  </tag>  








0 0