四、编写有标签体的标签
需要返回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;
- }
- }
- }
- <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>
- <tag>
- <name>iterate</name>
- <tag-class>org.tagext.IterateTag</tag-class>
- <body-content>JSP</body-content>
- <tei-class><span style="white-space:pre"> </span>//注意
- 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>