自定义jsp标签(out、if、foreach、select)

目录

标签与自定义标签

什么是标签?

标签基本结构:

空标签:

jsp标签库是什么?

标签的生命周期图: 

自定义标签的创作流程:

1.创建一个标签助手类(继承BodyTagSupport)

①out标签

②if标签

③select标签

④foreach标签

2.编写标签库描述文件(tld)

3.页面显示


标签与自定义标签:

什么是标签?

标记语言,是一种注释文本的语言,以便于计算机可以操作。很多与“ML”结尾的语言都是标记语言,比如:HTML,XML,XHTML,VML等等。
标记语言与其他语言一样,也需要运行它们的环境,比如HTML的运行环境时浏览器,XML也要自己的解析和运行的环境。

标签基本结构:

<开始标签>标签体<结束标签>

<name>out</name>

空标签:

<开始标签 属性名="属性值"/></结束标签>
<br/><br/>
<开始标签 属性名="属性值"/> 

<action path="/studentAction" type="org.lisen.mvc.action.StudentAction"></action>
<forward name="students" path="/students/studentList.jsp" redirect="false"/>

jsp标签库是什么?

是一个JSP标签集合,它封装了JSP应用的通用核心功能, 基于JSP标签我们可以理解为,是JSP应该通用功能的一种封装方式。 

标签的生命周期图: 

  SKIP_BODY:跳过主体( 不会打印“awa”)
  EVAL_BODY_INCLUDE:计算标签主体内容并[输出](会打印“awa”)
  EVAL_PAGE:计算页面的后续部分
  SKIP_PAGE:跳过页面的后续部分(不建议用,直接跳过后面全部类容包括body)
  EVAL_BODY_AGAIN:再计算主体一次

实例(完整的流程图):

                                              EVAL_BODY_INCLUDE         SKIP_BODY
实例化标签助手类->doStartTag()------------->doAfterBody---------------->doEndTag()...
                                                              EVAL_BODY_AGAIN

/**
	 * 在标签体之后在结束标签之前执行的动作
	 * 返回值两种:
	 * 1.跳过主题,执行doEndTag的方法SKIP_BOOY
	 * 2.再计算主题一次  EVAL_BODY_AGAIN
	 */
	@Override
	public int doAfterBody() throws JspException {
		//获取count值
		int count = (int)pageContext.getAttribute("count");
		if(count<3) {
			count++;
			pageContext.setAttribute("count", count);
			return EVAL_BODY_AGAIN;
		}else {
			return SKIP_BODY;
		}
	}

	@Override
	public int doEndTag() throws JspException {
		return super.doEndTag();
	}
	
	/**
	 * 默认为跳过标签体
	 */
	@Override
	public int doStartTag() throws JspException {
		pageContext.setAttribute("count", 1);
		String str="";
		for (Object string : item) {
			str+=string;
		}
		pageContext.setAttribute(var, str);
		return EVAL_BODY_INCLUDE;
	}

自定义标签的创作流程:

1.创建一个标签助手类(继承BodyTagSupport)

①out标签

像这个out标签就是一个简单的流程:

                                        SKIP_BODY
实例化标签助手类->doStartTag()------------->doEndTag() 

package com.ljq.mymvc.tag;

import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import com.mysql.jdbc.StringUtils;

/**
 * 自定义out标签
 * 
 * @author 一麟
 *
 */
public class OutTag extends BodyTagSupport {

	private String val;// 传入的值

	private String defaultVal;// 默认值

	/**
	 * @param val
	 */
	public void setVal(String val) {
		this.val = val;
	}

	public void setDefaultVal(String defaultVal) {
		this.defaultVal = defaultVal;
	}

	/**
	 * 处理标签的数值(执行开始标签)
	 */
	@Override
	public int doStartTag() {
		JspWriter out = this.pageContext.getOut();
		try {
			if (StringUtils.isNullOrEmpty(val)) {
				out.println(this.defaultVal);
			} else {
				out.println(this.val);
			}
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return SKIP_BODY;
	}

}

②if标签

package com.ljq.mymvc.tag;

import javax.servlet.jsp.tagext.BodyTagSupport;

/**
 * if自定义标签
 * 
 * @author 一麟
 *
 */
public class IfTag extends BodyTagSupport{
	
	private boolean test;

	public boolean isTest() {
		return test;
	}

	public void setTest(boolean test) {
		this.test = test;
	}
	
	
	@Override
	public int doStartTag() { 
		
		if(this.isTest()) {
			return EVAL_BODY_INCLUDE;
		} 
		
		return SKIP_BODY;
		
	}
	

}

③select标签

package com.ljq.mymvc.tag;

import java.util.List;

import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.beanutils.BeanUtils;

import com.mysql.jdbc.StringUtils;

/**
 * 下拉框标签助手类
 * 
 * @author 一麟
 *
 */
@SuppressWarnings("all")
public class SelectTag extends BodyTagSupport {

	private String id;

	private String name;

	private List<?> items;

	private String cssClass;

	private String cssStyle;

	private String value;

	private String text;

	private String selectValue;

	public void setText(String text) {
		this.text = text;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public void setSelectValue(String selectValue) {
		this.selectValue = selectValue;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setItems(List<?> items) {
		this.items = items;
	}

	public void setCssClass(String cssClass) {
		this.cssClass = cssClass;
	}

	public void setCssStyle(String cssStyle) {
		this.cssStyle = cssStyle;
	}

	/**
	 * 初始化
	 */
	@Override
	public int doStartTag() {

		JspWriter out = this.pageContext.getOut();

		try {
			String html = getSelectHtml();
			out.print(html);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return SKIP_BODY;
	}

	// 构造select标签(通过传入的参数)
	private String getSelectHtml() throws Exception {
		StringBuilder sb = new StringBuilder();

		// 元素需求判断(需要的元素就构造)
		sb.append("<select id='" + id + "' name='" + name + "'");
		if (!StringUtils.isNullOrEmpty(this.cssClass)) {
			sb.append(" class='" + this.cssClass + "'");
		}
		if (!StringUtils.isNullOrEmpty(this.cssStyle)) {
			sb.append(" style='" + this.cssStyle + "'");
		}
		sb.append(">");

		// 循环生成options标签
		for (Object option : this.items) {
			String val = BeanUtils.getProperty(option, this.value);
			String txt = BeanUtils.getProperty(option, this.text);

			if (val.equals(this.selectValue)) {
				sb.append("<option value='" + val + "' selected>" + txt + "</option>");
			} else {
				sb.append("<option value='" + val + "' >" + txt + "</option>");
			}
		}

		sb.append("</select>");

		return sb.toString();
	}
}

④foreach标签

package com.ljq.mymvc.tag;

import java.util.List;

import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;

import org.apache.commons.beanutils.BeanUtils;

import com.mysql.jdbc.StringUtils;

/**
 * 下拉框标签助手类
 * 
 * @author 一麟
 *
 */
@SuppressWarnings("all")
public class SelectTag extends BodyTagSupport {

	private String id;

	private String name;

	private List<?> items;

	private String cssClass;

	private String cssStyle;

	private String value;

	private String text;

	private String selectValue;

	public void setText(String text) {
		this.text = text;
	}

	public void setValue(String value) {
		this.value = value;
	}

	public void setSelectValue(String selectValue) {
		this.selectValue = selectValue;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setItems(List<?> items) {
		this.items = items;
	}

	public void setCssClass(String cssClass) {
		this.cssClass = cssClass;
	}

	public void setCssStyle(String cssStyle) {
		this.cssStyle = cssStyle;
	}

	/**
	 * 初始化
	 */
	@Override
	public int doStartTag() {

		JspWriter out = this.pageContext.getOut();

		try {
			String html = getSelectHtml();
			out.print(html);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return SKIP_BODY;
	}

	// 构造select标签(通过传入的参数)
	private String getSelectHtml() throws Exception {
		StringBuilder sb = new StringBuilder();

		// 元素需求判断(需要的元素就构造)
		sb.append("<select id='" + id + "' name='" + name + "'");
		if (!StringUtils.isNullOrEmpty(this.cssClass)) {
			sb.append(" class='" + this.cssClass + "'");
		}
		if (!StringUtils.isNullOrEmpty(this.cssStyle)) {
			sb.append(" style='" + this.cssStyle + "'");
		}
		sb.append(">");

		// 循环生成options标签
		for (Object option : this.items) {
			String val = BeanUtils.getProperty(option, this.value);
			String txt = BeanUtils.getProperty(option, this.text);

			if (val.equals(this.selectValue)) {
				sb.append("<option value='" + val + "' selected>" + txt + "</option>");
			} else {
				sb.append("<option value='" + val + "' >" + txt + "</option>");
			}
		}

		sb.append("</select>");

		return sb.toString();
	}
}

2.编写标签库描述文件(tld)

tld文件就是标签库描述文件(Tag Library Descrptor File)

tag.tld

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<!-- 标签库描述符 -->
<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>/yilinyyds</uri>


	<tag>
		<name>out</name>
		<tag-class>com.ljq.mymvc.tag.OutTag</tag-class>
		<body-content>empty</body-content>
		<attribute>
			<name>val</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
			<description>out标签,val属性是传入的值</description>
		</attribute>
		<attribute>
			<name>defaultVal</name>
			<required>false</required>
			<rtexprvalue>false</rtexprvalue>
			<description>用户定义默认值</description>
		</attribute>
	</tag>

	<tag>
		<name>if</name>
		<tag-class>com.ljq.mymvc.tag.IfTag</tag-class>
		<body-content>jsp</body-content>
		<attribute>
			<name>test</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
			<description>if标签判断,若为true则执行标签中的代码</description>
		</attribute>
	</tag>

	<tag>
		<name>foreach</name>
		<tag-class>com.ljq.mymvc.tag.ForeachTag</tag-class>
		<body-content>jsp</body-content>
		<description>foreach标签</description>
		<attribute>
			<name>items</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>var</name>
			<required>true</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
	</tag>

	<tag>
		<name>select</name>
		<tag-class>com.ljq.mymvc.tag.SelectTag</tag-class>
		<body-content>empty</body-content>
		<attribute>
			<name>id</name>
			<required>true</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
		<attribute>
			<name>name</name>
			<required>true</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
		<attribute>
			<name>items</name>
			<required>true</required>
			<rtexprvalue>true</rtexprvalue>
		</attribute>
		<attribute>
			<name>cssClass</name>
			<required>false</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
		<attribute>
			<name>cssStyle</name>
			<required>false</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
		<attribute>
			<name>value</name>
			<required>true</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
		<attribute>
			<name>text</name>
			<required>true</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
		<attribute>
			<name>selectValue</name>
			<required>false</required>
			<rtexprvalue>false</rtexprvalue>
		</attribute>
	</tag>

</taglib>

注意:tld文件一定要放在WEB-INF目录下或者子目录。

  • <taglib>:描述信息
  • <description>与<display-name>:可选,用于在IDE中的XML工具显示,和真正的TLD内容没什么关系,可有多个,用于不同语言的显示
  • <tlib-version>:必选,taglib的版本
  • <jsp-version>:必选,jsp的版本
  • <short-name>:必选,给出推荐和缺省的tag前缀。
  • <uri>:可选,建议给出,若不提供则需要在web.xml中配置<jsp-config>描述tag 
    library,uri可以随意配置,不需要真实存在。
  • <tag>:用来装载单个标签的信息
  • <name>:必选,标签名称。
  • <tag-class>:标签处理类(指的是自定义标签类的权限类名)
  • <tei-class>:可选,javax.servlet.jsp.tagext.TagExtraInfo的继承类,用于校验tag的属性,确保使用的正确,<c:import><c:forEach>就有定义。
  • <body-content>:必选,有四个选项empty、scriptless、JSP、tagdependent,之后篇章介绍。
  • <variable>:可选,可定义多个,JSTL TLD中都没有使用,它是用来提供tag的结果的各种变量信息。什么是variable?我们通过pageContext.setAttribute/getAttribute设置或获取某个值,这就是变量。不通过variable,我们也可以通过EL来获取。如果提供了variable,我们除了EL外,还可以在java代码中使用这些变量。但现在都是采用MVC模式,JSP页面中java代码基本上也不会被使用。子参数依次包括:
  1. <description>:标签的描述,建议有,方便项目的维护
  2. <name> 变量的名字 。
  3. <required>:是否必填
  4. <rtexprvalue:可选,rtexprvalue是runtime expression value:true表示允许EL这类运行时计算值,false则不允许,缺省为false。
  5. <type>:可选,属性类型,缺省为Object

3.页面显示

接下来我们创建一个jsp文件显示页面查看结果。

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib uri="/yilinyyds" prefix="y"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>测试</title>
</head>
<body>

	<center>
		<%
		request.setAttribute("name", "");
		request.setAttribute("name02", "小明");
		%>
		<!-- out 标签 -->
		<y:out val="${name}" defaultVal="name为空" />
		<br>
		<y:out val="${name02}" defaultVal="name02为空" />
		<br>

		<y:if test="${100 == 100}">
		hello world!
	</y:if>

		<y:if test="${100 == 200}">
		no happy!
	</y:if>
	</center>

</body>
</html>

下面这行代码就是引入自定义标签 uri就是在tld描述文件中定义的,而prefix就是你自己定义的前缀,字母即可。 

<%@ taglib uri="/yilinyyds" prefix="y"%>

页面输出结果:

猜你喜欢

转载自blog.csdn.net/m0_67376124/article/details/125670782
今日推荐