1.自定义ForEach标签
<% List <Dept> list=new ArrayList(); list.add(new Dept(1,"研发部")); list.add(new Dept(2,"销售部")); list.add(new Dept(3,"品牌部")); request.setAttribute("list",list); %> <body> <p>自定义foreach标签</p> <c:forEach items="${list }" var="l"> ${l.id }:${l.name} </c:forEach>
1.1编写助手类
由上可以看出,foreach属性有两个属性--items和var,所以就可以编写助手类了
package com.sy; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyTagSupport; /*** * foreach循环助手类 * @author 86177 * */ public class ForEachTag extends BodyTagSupport{ // 数据源,用来遍历的 private List<Object> items=new ArrayList<Object>(); //对象的指针:指向的数据源中的哪一个对象 private String var; 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; } @Override public int doAfterBody() throws JspException { Iterator<Object> it = (Iterator<Object>) pageContext.getAttribute("it"); if (it.hasNext()) { // 取得数据源中的第2.3条数据... pageContext.setAttribute(var, it.next()); pageContext.setAttribute("it", it); return EVAL_BODY_AGAIN; } return SKIP_BODY; // return super.doAfterBody(); } @Override public int doStartTag() throws JspException { if (items ==null|| items.size() == 0) return SKIP_BODY; Iterator<Object> it = items.iterator(); // 取得数据源中的第一条数据 pageContext.setAttribute(var, it.next()); pageContext.setAttribute("it", it); return EVAL_BODY_INCLUDE; } }
1.2编写.tld文件
<tag> <!-- 标签库标签的名字 --> <name>foreach</name> <!-- 对应的助手类 --> <tag-class>com.sy.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> <!-- 是否支持EL表达式 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
接着导入标签;
1.3 最后输出结果:
2.数据标签
当一些数据多个页面或者多个地方多次使用时,就可以将它作为数据标签
2.1 编写助手类
就是保存集合,但在WEB项目中会减少很多代码量
package com.sy; import java.util.ArrayList; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyTagSupport; public class DeptTag extends BodyTagSupport{ private String var;//存放数据 public String getVar() { return var; } public void setVar(String var) { this.var = var; } public DeptTag(String var) { super(); this.var = var; } @Override public int doStartTag() throws JspException { // 模拟数据库访问的过程 List <Dept> list=new ArrayList(); list.add(new Dept(1,"研发部")); list.add(new Dept(2,"销售部")); list.add(new Dept(3,"品牌部")); //将数据放入var 中 pageContext.setAttribute(var, list); return SKIP_BODY; } public DeptTag() { } }
2.2编写.tld文件
<tag> <!-- 标签库标签的名字 --> <name>dept</name> <!-- 对应的助手类 --> <tag-class>com.sy.DeptTag</tag-class> <!-- 代表jsp标签 --> <body-content>JSP</body-content> <attribute> <!-- 属性名称 --> <name>var</name> <!-- 是否为必填项 --> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>true</rtexprvalue> </attribute> </tag>
2.3输出结果为:
3.select标签
自定义标签将从前的很多行代码减少到只需要一行代码就可实现
3.1编写助手类
package com.sy; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.BodyTagSupport; public class SelectTag extends BodyTagSupport{ // 下拉框的数据源 private List<Object> items = new ArrayList<Object>(); //下拉框option 的value值 private String optionVal;//id //下拉框option的标签体内容 private String optionText;//name private String selectVal; public String getSelectVal() { return selectVal; } public void setSelectVal(String selectVal) { this.selectVal = selectVal; } public List<Object> getItems() { return items; } public void setItems(List<Object> items) { this.items = items; } public String getOptionVal() { return optionVal; } public void setOptionVal(String optionVal) { this.optionVal = optionVal; } public String getOptionText() { return optionText; } public void setOptionText(String optionText) { this.optionText = optionText; } @Override public int doStartTag() throws JspException { // 因为s:select 标签没有标签体,页面又要输出下拉框内容 JspWriter out = pageContext.getOut(); try { out.print(toHTML()); } catch (Exception e) { e.printStackTrace(); } return super.doStartTag(); } private String toHTML() throws Exception { //StringBuffer sb=new StringBuffer(); //sb.append("hello"); //sb.append(" "); //sb.append("world"); StringBuffer sb=new StringBuffer("<select>"); for (Object object : items) { // object==new Dept(1,研发部) // 取出某一个对象的某个属性值 // sb.append("<option value='1'>美女</option>" String val=getObjAttrValue(object,optionVal); String text=getObjAttrValue(object,optionText); sb.append("<option "+(val.equals(selectVal)?"selected":"")+" value='"+val+"'>"+text+"</option>"); } sb.append("</select>"); return sb.toString(); } /** * 获取某个对象的某个属性值 * @param object * @param attr id/name * @return * @throws SecurityException * @throws NoSuchFieldException */ private String getObjAttrValue(Object object, String attr) throws Exception{ Class clz= object.getClass(); Field f = clz.getDeclaredField(attr); f.setAccessible(true); return (String) f.get(object).toString(); } }
3.2编写.tld文件
<tag> <!-- 标签库标签的名字 --> <name>select</name> <!-- 对应的助手类 --> <tag-class>com.sy.SelectTag</tag-class> <!-- 代表jsp标签 --> <body-content>JSP</body-content> <attribute> <!-- 属性名称 --> <name>items</name> <!-- 是否为必填项 --> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <!-- 属性名称 --> <name>optionVal</name> <!-- 是否为必填项 --> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <!-- 属性名称 --> <name>optionText</name> <!-- 是否为必填项 --> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>false</rtexprvalue> </attribute> <attribute> <name>selectVal</name> <required>true</required> <!-- 是否支持EL表达式 --> <rtexprvalue>false</rtexprvalue> </attribute> </tag>
3.3输出结果为:
自定义JSP标签需要严谨对照周期图