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 等标签,这些标签的作用可以提高
我们的开发效率,让程序可以变得更加灵活。达到高内聚,弱耦合的特性。