• JSP自定义标签(2)



    四、编写有标签体的标签


    需要返回TagSupport.EVAL_BODY_INCLUDE,则可以进入标签体;

    AttributeTag.java

    package org.tagext;
    import javax.servlet.jsp.tagext.*;
    import javax.servlet.jsp.*;
    
    public class AttributeTag extends TagSupport{
    	private String name;
    	public String getName(){
    		return name;
    	}
    	public void setName(String name){
    		this.name = name;
    	}
    	public int doStartTag()throws JspException{
    		Object value = null;
    		value = super.pageContext.getAttribute(name,PageContext.PAGE_SCOPE);
    		if(value==null){
    			return TagSupport.SKIP_BODY;
    		}
    		else{
    			return TagSupport.EVAL_BODY_INCLUDE;
    		}
    	}
    }


    xiazdong.tld

        <tag>
    	<name>attribute</name>
    	<tag-class>org.tagext.AttributeTag</tag-class>
    	<body-content>JSP</body-content>
    	<attribute>
    		<name>name</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
      </tag>

    AttributeTag.jsp

    <%@ page contentType="text/html" pageEncoding="GBK"%>
    <%@ taglib prefix="xiazdong" uri="xiazdong"%>
    <html>
    	<head>
    		<title></title>
    	</head>
    	<body>
    	<%
    		pageContext.setAttribute("xiazdong","12345");
    	%>
    		<h1>
    			<xiazdong:attribute name="xiazdong">
    				<h3>${pageScope.xiazdong}</h3>
    			</xiazdong:attribute>
    		</h1>
    	</body>
    </html>

    五、迭代标签


    迭代标签的定义就是重复执行标签体,经常用在输出集合;在MVC中经常使用;

    代码实例:


    一些变化不大的文件我就不写了;

    IterateTag.java

    package org.tagext;
    import javax.servlet.jsp.tagext.*;
    import javax.servlet.jsp.*;
    import java.util.*;
    public class IterateTag extends TagSupport{
    	private String name;
    	private String id;
    	private Iterator<String> iter;
    	public String getName(){
    		return name;
    	}
    	public void setName(String name){
    		this.name = name;
    	}
    	public String getId(){
    		return id;
    	}
    	public void setId(String id){
    		this.id = id;
    	}
    	public int doStartTag()throws JspException{
    		Object value = null;
    		value = super.pageContext.getAttribute(name,PageContext.PAGE_SCOPE);
    		if(value==null||!(value instanceof List<?>)){
    			return TagSupport.SKIP_BODY;
    		}
    		else{
    			iter = ((List<String>)value).iterator();
    			if(iter.hasNext()){
    				super.pageContext.setAttribute(id,iter.next());
    				return TagSupport.EVAL_BODY_INCLUDE;
    			}
    			else{
    				return TagSupport.SKIP_BODY;
    			}
    		}
    	}
    	public int doAfterBody()throws JspException{
    		if(iter.hasNext()){
    			super.pageContext.setAttribute(id,iter.next());
    			return TagSupport.EVAL_BODY_AGAIN;
    		}
    		else{
    			return TagSupport.SKIP_BODY;
    		}
    	}
    }

    IterateTag.jsp

    <%@ page contentType="text/html" pageEncoding="GBK" import="java.util.*"%>
    <%@ taglib prefix="xiazdong" uri="xiazdong"%>
    <html>
    	<head>
    		<title></title>
    	</head>
    	<body>
    	<%
    		List<String> list = new ArrayList<String>();
    		list.add("A");
    		list.add("B");
    		list.add("C");
    
    		pageContext.setAttribute("xiazdong",list);
    	%>
    		<h1>
    			<xiazdong:iterate name="xiazdong" id="iter">
    				<h3>${iter}</h3>
    			</xiazdong:iterate>
    		</h1>
    	</body>
    </html>


    六、BodyTagSupport类


    BodyTagSupport的特点就是可以将输出内容存在BodyContent中, 一次全部输出;

    根据上面的迭代输出的代码,稍微变化即可,主要变化是在IterateTag.java中,需要extends BodyTagSupport;

    BodyTagSupport的常用方法:

    (1)BodyTagSupport.EVAL_BODY_BUFFERED;

    (2)getPreviousOut();      //获得输出到网页的输出流

    (3)bodyContent对象存储数据;

    package org.tagext;
    import javax.servlet.jsp.tagext.*;
    import javax.servlet.jsp.*;
    import java.util.*;
    public class IterateTag extends BodyTagSupport{
    	private String name;
    	private String id;
    	private Iterator<String> iter;
    	public String getName(){
    		return name;
    	}
    	public void setName(String name){
    		this.name = name;
    	}
    	public String getId(){
    		return id;
    	}
    	public void setId(String id){
    		this.id = id;
    	}
    	public int doStartTag()throws JspException{
    		Object value = null;
    		value = super.pageContext.getAttribute(name,PageContext.PAGE_SCOPE);
    		if(value==null||!(value instanceof List<?>)){
    			return TagSupport.SKIP_BODY;
    		}
    		else{
    			iter = ((List<String>)value).iterator();
    			if(iter.hasNext()){
    				super.pageContext.setAttribute(id,iter.next());
    				return TagSupport.EVAL_BODY_BUFFERED;    //存在BodyContent中
    			}
    			else{
    				return TagSupport.SKIP_BODY;
    			}
    		}
    	}
    	public int doAfterBody()throws JspException{
    		if(iter.hasNext()){
    			super.pageContext.setAttribute(id,iter.next());
    			return TagSupport.EVAL_BODY_AGAIN;
    		}
    		else{
    			return TagSupport.SKIP_BODY;
    		}
    	}
    	public int doEndTag()throws JspException{
    		if(super.bodyContent!=null){
    			try{
    				super.bodyContent.writeOut(super.getPreviousOut());    //输出到页面
    			}
    			catch(Exception e){}
    		}
    		return BodyTagSupport.EVAL_PAGE;
    	}
    }

    七、TagExtraInfo和VariableInfo的使用


    在<jsp:useBean id = "">中的id属性表示对象名称,并且可以通过这个名称调用方法;而如果要实现这种效果,必须继承TagExtraInfo类;

    我们需要另外创建一个文件,用以表明属性的对象能够在脚本中使用;

    MyExtraInfo.java

    package org.tag;
    import javax.servlet.jsp.tagext.*;
    public class MyTagExtraInfo extends TagExtraInfo{
    	public VariableInfo[] getVariableInfo(TagData data){
    		return new VariableInfo[]{new VariableInfo(data.getId(),"java.lang.String",true,VariableInfo.NESTED)};
    	}
    }

    写完后在xiazdong.tld中添加:

    	<tei-class>			//注意
    		org.tag.MyTagExtraInfo
    	</tei-class>
    最后xiazdong.tld中以:

    <tag>
    	<name>iterate</name>
    	<tag-class>org.tagext.IterateTag</tag-class>
    	<body-content>JSP</body-content>
    
    
    	<tei-class>			//注意
    		org.tag.MyTagExtraInfo
    	</tei-class>
    
    
    	<attribute>
    		<name>name</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
    	<attribute>
    		<name>id</name>
    		<required>true</required>
    		<rtexprvalue>true</rtexprvalue>
    	</attribute>
      </tag>


    这样在JSP中就能够在Scriptlet中使用;

    <%@ page contentType="text/html" pageEncoding="GBK" import="java.util.*"%>
    <%@ taglib prefix="xiazdong" uri="xiazdong"%>
    <html>
    	<head>
    		<title></title>
    	</head>
    	<body>
    	<%
    		List<String> list = new ArrayList<String>();
    		list.add("A");
    		list.add("B");
    		list.add("C");
    
    		pageContext.setAttribute("xiazdong",list);
    	%>
    		<h1>
    			<xiazdong:iterate name="xiazdong" id="iter">
    				<h3><%=iter%></h3>     //注意,原本是${iter}输出;
    			</xiazdong:iterate>
    		</h1>
    	</body>
    </html>






    作者:xiazdong
    出处:http://blog.xiazdong.info
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    Devrama Slider
    全栈开发必备的10款 Sublime Text 插件
    经典网页设计:使用颜色滤镜效果的20个网站
    Nibbler – 免费的网站测试和指标评分工具
    使用 HTML5 Canvas 绘制出惊艳的水滴效果
    Qt4 和 Qt5 模块的分类
    设计Qt风格的C++API
    Qt属性系统
    Qt实现艺术字效果
    Qt中容器类应该如何存储对象(最好使用对象指针类型,如:QList<TestObj*>,而不要使用 QList<TestObj> 这样的定义,建议采用 智能指针QSharedPointer)
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3058120.html
Copyright © 2020-2023  润新知