前言
上篇博客讲述了三个简单的自定义标签(set、out、if),这次讲述两个比较复杂的标签(forEach、select)。
自定义标签的开发步骤:
1.先定义一个助手类
2.配置tld
3.导入taglib标签
**自定义标签的生命周期图**
一、 jsp标签
1.1 UI标签 select
注:用 jspWriter writer=pageContext.getOut()实现;
1.2 控制标签 forEach
注:作用域 4个
page(pageContext)
requeset(…)
session
application
作用域的作用:保存数据和数据交互
二、代码与结果
先演示forEach标签
必须要继承BodyTagSupport
package com.zhumengyuan.zhu.tag;
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 List<Object> items;
private String var;//保存集合中的元素的key
private String varStatus;//保存index,count属性的对象的key
public static class Status{
public int index=0;
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getCount() {//相当于s.count
return this.index+1;
}
//自动增长的方法
void increment() {
this.index++;
}
}
public ForEachTag() {
super();
// TODO Auto-generated constructor stub
}
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
public String getVarStatus() {
return varStatus;
}
public void setVarStatus(String varStatus) {
this.varStatus = varStatus;
}
@Override
public int doAfterBody() throws JspException {
Iterator<Object> it =(Iterator<Object>) pageContext.getAttribute("it");
while(it.hasNext()) {
if(null!=varStatus&&!"".equals(varStatus)) {
Status status =(Status) pageContext.getAttribute(varStatus);
status.increment();
pageContext.setAttribute(varStatus, status);
}
Object next=it.next();
pageContext.setAttribute(var, next);
return EVAL_BODY_AGAIN;
}
return super.doAfterBody();
}
@Override
public int doStartTag() throws JspException {
if(null!=varStatus&&!"".equals(varStatus)) {
pageContext.setAttribute(varStatus, new Status());
}
if(null!=items&&0!=items.size()) {
Iterator<Object> it = items.iterator();
Object next = it.next();
pageContext.setAttribute(var, next);
pageContext.setAttribute("it", it);
return EVAL_BODY_INCLUDE;
}
return super.doStartTag();
}
}
配置标签文件
<tag>
<name>forEach</name>
<tag-class>com.zhumengyuan.zhu.tag.ForEachTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>varStatus</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
</tag>
显示代码及结果
代码:
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="z" uri="/zking"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>jsp标签2</title>
</head>
<body>
<%
List<String> list=new ArrayList<String>();
list.add("zs");
list.add("ls");
list.add("ww");
String name="zs";
pageContext.setAttribute("name", name);
request.setAttribute("names", list);
%>
<h2>自定义forEach标签</h2>
<ul>
<z:forEach items="${names }" var="n" varStatus="s">
<li>${n},${s.index},${s.count}</li>
</z:forEach>
</ul>
</body>
</html>
结果:
select标签
先写个实体类
package com.zhumengyuan.zhu.entity;
import java.io.Serializable;
public class Dept implements Serializable{
private static final long serialVersionUID = 1L;
private Integer DeptId;
private String DeptName;
public Dept() {
super();
// TODO Auto-generated constructor stub
}
public Dept(Integer deptId, String deptName) {
super();
DeptId = deptId;
DeptName = deptName;
}
public Integer getDeptId() {
return DeptId;
}
public void setDeptId(Integer deptId) {
DeptId = deptId;
}
public String getDeptName() {
return DeptName;
}
public void setDeptName(String deptName) {
DeptName = deptName;
}
@Override
public String toString() {
return "Dept [DeptId=" + DeptId + ", DeptName=" + DeptName + "]";
}
}
再写个dao方法
package com.zhumengyuan.zhu.dao;
import java.util.ArrayList;
import java.util.List;
import com.zking.zhu.entity.Dept;
public class DeptDao {
public List<Dept> list(){
//访问数据库
List<Dept> list=new ArrayList<Dept>();
list.add(new Dept(1, "体育"));
list.add(new Dept(2, "美术"));
list.add(new Dept(3, "舞蹈"));
list.add(new Dept(4, "IT"));
return list;
}
}
select类 (必须继承BodyTagSupport)
package com.zhumengyuan.zhu.tag;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import org.apache.commons.beanutils.PropertyUtils;
public class SelectTag extends BodyTagSupport {
private List<Object> items;
private String name;
private String valueKey;//保存到option中的value的key
private String textKey;//保存option中的text文本的key
private String cssStyle;
private String headKey;
private String headValue;
private String selectedOptionValue;//默认选中
public SelectTag() {
super();
// TODO Auto-generated constructor stub
}
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValueKey() {
return valueKey;
}
public void setValueKey(String valueKey) {
this.valueKey = valueKey;
}
public String getTextKey() {
return textKey;
}
public void setTextKey(String textKey) {
this.textKey = textKey;
}
public String getCssStyle() {
return cssStyle;
}
public void setCssStyle(String cssStyle) {
this.cssStyle = cssStyle;
}
public String getHeadKey() {
return headKey;
}
public void setHeadKey(String headKey) {
this.headKey = headKey;
}
public String getHeadValue() {
return headValue;
}
public void setHeadValue(String headValue) {
this.headValue = headValue;
}
public String getSelectedOptionValue() {
return selectedOptionValue;
}
public void setSelectedOptionValue(String selectedOptionValue) {
this.selectedOptionValue = selectedOptionValue;
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
String html = toHtml();
out.println(html);
} catch (Exception e) {
throw new RuntimeException(e);
}
return super.doStartTag();
}
private String toHtml() throws Exception{
StringBuffer sb=new StringBuffer();
//<select name="" style="">
sb.append("<select name='"+name+"' ");
sb.append("style='"+cssStyle+"' ");
sb.append(">");
//<option value=""></option>
if(null!=items&&0!=items.size()) {
if(null!=headKey&&!"".equals(headKey.trim())) {
sb.append("<option value='"+headKey+"'>"+headValue+"</option>");
}
Object value=null;
Object text=null;
for (Object object : items) {
//反射
value=PropertyUtils.getProperty(object, valueKey);
text=PropertyUtils.getProperty(object, textKey);
if(value.toString().equals(selectedOptionValue.trim())) {
sb.append("<option selected value='"+value+"'>"+text+"</option>");
}else {
sb.append("<option value='"+value+"'>"+text+"</option>");
}
}
}
sb.append("</select>");
return sb.toString();
}
}
配置标签文件
<tag>
<name>select</name>
<tag-class>com.zhumengyuan.zhu.tag.SelectTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>valueKey</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>textKey</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>cssStyle</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>headKey</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>headValue</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
<attribute>
<name>selectedOptionValue</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
<type>boolean</type>
</attribute>
</tag>
结果:
注意:在拼接的时候要注意引号,容易出错