今天来学习自定义标签2的内容
环境搭建
导入4个架包文件 jtsl-1.2.jar和standard-1.1.2.jar是C标签文件使用必要的架包
commons-beantils-1.8.0.jar和commons-logging.jar是后面写反射需要用到的架包
导入在WEB-INF下面的lib里面如下图
当我们使用C标签时必须写入这行代码
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
按住Ctrl点击uri里面的内容时会进入c.tld文件 当我们再使用标签时 本质上时有一个助手类(tag-class)帮忙处理业务逻辑的
助手类组成的部分为
<description>JSTL 1.1 core library</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>x</short-name>
<uri>/xiaoxi</uri>
<tag>
<!-- 标签名 -->
<name>out</name>
<!-- 标签工具类 -->
<tag-class>com.zhuchenxi.daay3.OutTags</tag-class>
<!-- 标签的内容:empty表示空标签,jsp表示可以为任何合法标签 -->
<body-content>empty</body-content>
<attribute>
<!-- 自定义标签的属性名称 -->
<name>value</name>
<!-- 是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
自己新建一个xx.tld文件复制助手类组成部分 也可以复制c.tld文件里面的内容再删除多余部分
UI标签 out select
首先写自定义标签out标签
创建一个SetTag类继承 BodyTagSupport 写入属性value out是输出标签 只有一个value属性 再类里写入 在封装 写一个无参方法 加上doStartTag()开始方法
package com.zhuchenxi.daay3;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class OutTags extends BodyTagSupport {
private Object value;
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public OutTags() {
// TODO Auto-generated constructor stub
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.println(value==null?"":value.toString());
} catch (Exception e) {
// TODO: handle exception
throw new RuntimeException(e);
}
return super.doStartTag();
}
}
在自己写的xx.tld文件里面配置文件
<tag>
<!-- 标签名 -->
<name>out</name>
<!-- 标签工具类 -->
<tag-class>com.zhuchenxi.daay3.OutTags</tag-class>
<!-- 标签的内容:empty表示空标签,jsp表示可以为任何合法标签 -->
<body-content>empty</body-content>
<attribute>
<!-- 自定义标签的属性名称 -->
<name>value</name>
<!-- 是否必填 -->
<required>true</required>
<!-- 是否支持表达式 -->
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
在taglib里面写上C标签的套路
<%@taglib prefix="x" uri="/xiaoxixi"%>
写个List集合加入数据
再保存再Attribute里面
再转发到页面上
<h2>自定义标签之out标签</h2>
<!-- 在outtags里面dostartag里面判断如果有值输出若没有则为空 -->
<x:out value="${names }"/>
输出为
接下来是自定义select标签
先写个传统的select标签好作参照写自定义的
<select name="" style="">
<option value="-1">-----请选择------</option>
<option value="1">长沙</option>
<option selected value="2">岳阳</option>
<option value="3">邵阳</option>
<option value="4">娄底</option>
</select>
接下来也是新建一个SelectTag 我们看上面需要的属性有name valueKety 用来保存option种的value的key textKey用来保存text文本种的key CssStyle样式 headkey也是样式 headValue默认线 selectOptionValue默认选中 然后封装 加上 doStartTag()方法和toHtml()方法 为拼接做准备
package com.zhuchenxi.daay3;
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;
import com.zhuchenxi.dao.DeptDao;
import com.zhuchenxi.entity.Dept;
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.zhuchenxi.daay3.SelectTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>name</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>valueKey</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>textKey</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>cssStyle</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>headKey</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>headValue</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>selectedOptionValue</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
写自定义标签
<h2>自定义标签之select标签</h2>
<x:select items="${deptList }" valueKey="deptId" textKey="deptName"
cssStyle="width:150px" headKey="-1"
headValue="-----请选择------" selectedOptionValue="2"></x:select>
输出为
控制标签 if forEach
先写if标签 因为是判断所有定义一个Boolean属性的 text; 在封装 在doStarTag()中 判断如果是为true 输出标签主题
package com.zhuchenxi.daay3;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class IfTags extends BodyTagSupport {
private Boolean text;
public Boolean getText() {
return text;
}
public void setText(Boolean text) {
this.text = text;
}
public IfTags() {
// TODO Auto-generated constructor stub
}
@Override
public int doStartTag() throws JspException {
if(text) {
return EVAL_BODY_INCLUDE;
}
return SKIP_BODY;
}
}
配置
<tag>
<name>if</name>
<tag-class>com.zhuchenxi.daay3.IfTags</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>text</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
如果$里面name等于zs name输出我怎么说呢 如果不等于输出空
<h2>自定义标签之if标签</h2>
<!-- 如果$里面name等于zs name输出我怎么说呢 如果不等于输出空 -->
<x:if text="${name eq 'zs'}">
我说怎么呢
</x:if>
输出
再接下来是forEach标签了
传统的forEach标签就是遍历出集合类容
<h2>foreach标签</h2>
<ul>
<c:forEach items="${names }" var="n" varStatus="s">
<li>${n },${s.index },${s.count }</li>
</c:forEach>
</ul>
当然我们写的也一样显示类 一个是要用List集合装入的 items 还有个是var 保存集合中的元素key
package com.zhuchenxi.daay3;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
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() {
// 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 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();
}
@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();
}
}
配置
<tag>
<name>forEach</name>
<tag-class>com.zhuchenxi.daay3.ForEachTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>varStatus</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
在页面上
<h2>自定义标签之set标签</h2>
<x:set value="deptList"/>
<br/>
<x:out value="${deptList }"/>
输出:
数据标签 set 用于设置变量值和对象属性
先写一个实体类Dept 封装 无参方法 构造方法 和 toString方法
package com.zhuchenxi.entity;
import java.io.Serializable;
public class Dept implements Serializable {
private static final long serialVersionUID = -288611754382387953L;
private Integer deptId;
private String deptName;
public Integer getDeptId() {
return deptId;
}
public void setDeptId(Integer deptId) {
this.deptId = deptId;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
@Override
public String toString() {
return "Dept [deptId=" + deptId + ", deptName=" + deptName + "]";
}
public Dept() {
// TODO Auto-generated constructor stub
}
public Dept(Integer deptId, String deptName) {
super();
this.deptId = deptId;
this.deptName = deptName;
}
}
再写一个dao方法
package com.zhuchenxi.dao;
import java.util.ArrayList;
import java.util.List;
import com.zhuchenxi.entity.Dept;
public class DeptDao {
public List<Dept> list(){
//访问数据库
List<Dept> ls = new ArrayList<Dept>();
ls.add(new Dept(1,"好嘞"));
ls.add(new Dept(2,"不累"));
ls.add(new Dept(3,"干了"));
ls.add(new Dept(4,"老子"));
return ls;
}
}
还是老样子写一个SetTag
package com.zhuchenxi.daay3;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.zhuchenxi.dao.DeptDao;
import com.zhuchenxi.entity.Dept;
public class SetTag extends BodyTagSupport {
private String value;//保存数据的key
private DeptDao deptDao = new DeptDao();
public SetTag() {
// TODO Auto-generated constructor stub
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public DeptDao getDeptDao() {
return deptDao;
}
public void setDeptDao(DeptDao deptDao) {
this.deptDao = deptDao;
}
@Override
public int doStartTag() throws JspException {
List<Dept> list = deptDao.list();
pageContext.setAttribute(value, list);
return super.doStartTag();
}
}
配置
<tag>
<name>set</name>
<tag-class>com.zhuchenxi.daay3.SetTag</tag-class>
<body-content>empty</body-content>
<attribute>
<name>value</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
页面上
<h2>自定义标签之set标签</h2>
<x:set value="deptList"/>
<br/>
<x:out value="${deptList }"/>
输出