1.要实现自定义的jsp标签,要编写一个助手类,这个类需要实现BodyTagSupport类
而且需要载BodyTagSupport类几个方法:
doStartTag(), setBodyContent(), doInitBody(), doAfterBody(), doEndTag();
他们执行顺序如下:
doStartTag()→doInitBody()→setBodyContent()→doAfterBody()→doEndTag()
我们拿foeach来进行举例:
编写助手类:并继承BodyTagSupport类(而且必须提供对应属性的get和set方法)
package com.hmc;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ForeachTag extends BodyTagSupport{
	private String var;
	private  List<Object> items=new ArrayList<Object>();
	public String getVar() {
		return var;
	}
	public void setVar(String var) {
		this.var = var;
	}
	public List<Object> getItems() {
		return items;
	}
	public void setItems(List<Object> items) {
		this.items = items;
	}
 
 
重写方法(foreach使用 doStarTag和doAfterBody方法即可)
)
@Override
public int doStartTag() throws JspException {
    Iterator<Object> it=items.iterator();
  //作用域进行存值
    pageContext.setAttribute(var, it.next());
    pageContext.setAttribute("it", it);
//EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流
    return EVAL_BODY_INCLUDE;
	
	}
	
	@Override
	public int doAfterBody() throws JspException {
    //迭代得到上个作用域的值
    Iterator<Object> it= (Iterator<Object>) pageContext .getAttribute("it");
		if(it.hasNext()) {
			pageContext.setAttribute(var, it.next());
			pageContext.setAttribute("it", it);
                    //EVAL_BODY_AGAIN:让服务器继续处理正文内容
			return EVAL_BODY_AGAIN;
		}
		else {
                 // EVAL_PAGE:让服务器继续执行页面
			return EVAL_PAGE;
		}
		
	}
	
	@Override
	public void doInitBody() throws JspException {
		// TODO Auto-generated method stub
		super.doInitBody();
	}
	
	@Override
	public void setBodyContent(BodyContent b) {
		// TODO Auto-generated method stub
		super.setBodyContent(b);
	}
	@Override
	public int doEndTag() throws JspException {
		// TODO Auto-generated method stub
		return super.doEndTag();
	}
	
 
 
说明:
doStartTag()方法可返回EVAL_BODY_INCLUDE或SKIP_BODY,
如果返回EVAL_BODY_INCLUDE则继续执行;
如果返回SKIP_BODY则接下来的doInitBody(),
setBodyContent(), 
doAfterBody()三个方法不会被执行,
而直接执行doEndTag()方法。
setBodyContent()方法用于设置标签体内容,
如果在此之前要作一些初始化工作,则在doInitBody()方法中完成。
标签体内容执行完后,会调用doAfterBody()方法,
此方法可返回EVAL_BODY_TAG, SKIP_BODY, EVAL_PAGE或SKIP_PAGE。
如果返回EVAL_BODY_TAG则会再次设置标签体内容,直到返回SKIP_BODY;
如果返回EVAL_PAGE则标签体执行完后会继续执行JSP页面中接下来的部分;
如果返回SKIP_PAGE,则JSP页面的后续内容将不再执行。
返回值:
EVAL_BODY_INCLUDE:告诉服务器正文的内容,并把这些内容送入输出流
SKIP_BODY:告诉服务器不要处理正文内容
EVAL_PAGE:让服务器继续执行页面
SKIP_PAGE:让服务器不要处理剩余的页面
EVAL_BODY_AGAIN:让服务器继续处理正文内容,只有doAfterBody方法可以返回
EVAL_BODY_BUFFERED:BodyTag接口的字段,在doStartTag()返回
EVAL_BODY_INCLUDE、SKIP_BODY一般由doStartTag()返回,而EVAL_PAPGE、SKIP_PAGE由doEndTag()返回。
2.创建tld文件,注:tld的文件格式为xml格式,创建xml时更改后缀名为tld即可;
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
	<tlib-version>1.0</tlib-version>
     <jsp-version>1.2</jsp-version>
      <short-name>Simple Tags</short-name>
     <!-- 设置被引用的路径 -->
      <uri>/MyJSP</uri>
	<!--foreach标签  -->
  <tag>
  <!-- 定义属性的名称 -->
 <name>foreach</name>
 <!-- 输入助手类的全路径限定名 -->
 <tag-class>com.hmc.ForeachTag</tag-class>
 <!-- -指定为jsp元素 -->
 <body-content>JSP</body-content>
 <!--设置属性  -->
 <attribute>
 <!-- -定义属性名 -->
 <name>items</name>
 <!---是否必填  -->
 <required>true</required>
 <!-- 是否支持EL表达式 -->
 <rtexprvalue>true</rtexprvalue>
 </attribute>
 
 <attribute>
 <name>var</name>
 <required>true</required>
 <rtexprvalue>flase</rtexprvalue>
 </attribute>
</tag>
 
 
3.创建jsp文件对标签进行测试
创建后必须引用文件给的路径(即tld文件的uri)
<%@page import="com.hmc.Stuent"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
 <%@taglib prefix="z" uri="/MyJSP" %>
 
 
调用foeach测试
<%
List<String> mys=new ArrayList<>();
mys.add("编号1");
mys.add("编号2");
mys.add("编号3");
request.setAttribute("mys", mys);
%>
<z:foreach items="${mys }" var="i">
${i}<br>
</z:foreach>
 
 
结果:
编号1 编号2 编号3
forech标签就完成了,当然,这只是一个例子,还有其他的如Out,Set,If,Redirect,selec--->https://i.cnblogs.com/Files.aspx 等标签,这些标签的作用可以提高
我们的开发效率,让程序可以变得更加灵活。达到高内聚,弱耦合的特性。
