JSP标签(2) -----自定义foreach ,select标签,全网最详细,最完整易懂

目录

自定义JSP标签需要严谨对照周期图

一.自定义Foreach 标签

 1.1编写助手类

1.2详解助手类

首先,在dostartTag方法里,做一个判断,要是后面没有值了,就返回skip_body,不再执行后面代码,否则继续执行

 其次,在doAdterTag方法里继续判断后面的数值,步骤:

 1.3编写.tld文件

1.4 页面输出

 二.数据标签 

        2.1 编写助手类

三.select标签

 3.1编写助手类

        3.2 详解助手类


自定义JSP标签需要严谨对照周期图

 

一.自定义Foreach 标签

 1.1编写助手类

上面可以分析,foreach属性有两个属性--items和var,所以就可以编写助手类了

package com.yinzi.jsp;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.BodyTagSupport;

/**
 * foreach循环助手类
 * @author 86131
 *
 */
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;
	}
	
	@Override
	public int doStartTag() throws JspException {
		//循环判断
		if(items.size()==0||items==null)
			return SKIP_BODY;
		//迭代器
		Iterator<Object> it=items.iterator();
		//保存
		pageContext.setAttribute(var, it.next());//保存第一个
		pageContext.setAttribute("it", it);//保存剩下的在集合中
		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);
			//如果有就再次循环
			return EVAL_BODY_AGAIN;
		}
		//如果没有就结束
		return SKIP_BODY;
	}
	
}

1.2详解助手类

 单独把两个方法拿出来,讲解步骤:

首先,在dostartTag方法里,做一个判断,要是后面没有值了,就返回skip_body,不再执行后面代码,否则继续执行

 其次,在doAdterTag方法里继续判断后面的数值,步骤:

  1. 获取上方集合
  2. 再次判断,一直循环,直到没有

 1.3编写.tld文件

 <tag>
    <!-- 标签库标签的名字 -->
    <name>foreach</name>
   <!--  对应的助手类 -->
    <tag-class>com.yinzi.jsp.ForeachTag</tag-class>
   <!--  代表JSP标签 -->
    <body-content>JSP</body-content>
    <!-- 属性 -->
      <attribute>
       <!--  属性名称 -->
       <name>var</name>
        <!-- 是否为必填项 -->
         <required>true</required> 
       <!--  是否支持EL表达式 -->
       <rtexprvalue>false</rtexprvalue> 
   </attribute>
    <attribute>
       <!--  属性名称 -->
       <name>items</name>
        <!-- 是否为必填项 -->
         <required>true</required> 
       <!--  是否支持EL表达式 -->
       <rtexprvalue>true</rtexprvalue> 
   </attribute>
   
  </tag>

1.4 页面输出

        记得导入标签库!!

 输出结果:

 二.数据标签

当一些数据多个页面或者多个地方多次使用时,就可以将它作为数据标签 

        2.1 编写助手类

                        就是保存集合,但在WEB项目中会减少很多代码量

package com.yinzi.jsp;

import java.util.ArrayList;
import java.util.List;

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

import com.yinzi.entity.Student;

/**
 * 数据标签助手类
 * @author 86131
 *
 */
public class StudentTag extends BodyTagSupport{
	private String var;
	
	
	public String getVar() {
		return var;
	}


	public void setVar(String var) {
		this.var = var;
	}


	@Override
	public int doStartTag() throws JspException {
	//模拟从数据库获取数据
		List<Student> list=new ArrayList();
		list.add(new Student(1,"哈哈"));
		list.add(new Student(2,"嘿嘿"));
		list.add(new Student(3,"呵呵"));
		list.add(new Student(4,"啦啦"));
		//将其保存
		pageContext.setAttribute(var, list);
		return SKIP_BODY;
	}
}

三.select标签

        自定义标签将从前的很多行代码减少到只需要一行代码就可实现

 3.1编写助手类

package com.yinzi.jsp;
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();//保存数据
	private String optionVal; //保存下拉框的value值  对应实体类的id
	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 {
		//select没有标签体,又要输出内容,所有要用流对象
		JspWriter out = pageContext.getOut();
		//拼接,写一个拼接的方法
		try {
			out.print(pinjie());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return super.doStartTag();
	}
	
	
	/**
	 * 拼接的方法
	 * @return
	 * @throws Exception 
	 */
	private String pinjie() throws Exception {
		//用StringbBuffer
	StringBuffer sb = new StringBuffer("<select>");
		//循环遍历数据
	for (Object object : items) {
		System.out.println(object);
		//在这里要获取值,所有写一个根据对象取值
		String val=getObjattrvalue(object,optionVal);//value值
		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  属性
	 * @return
	 * @throws Exception 
	 *
	 */

	private String getObjattrvalue(Object object, String attr) throws Exception {
		//要反射因为不知道有哪些属性和类
		//类类
		Class c = object.getClass();
		Field f = c.getDeclaredField(attr);
		//打开访问权限
		f.setAccessible(true);
		return f.get(object).toString();
	}
	
}

        3.2 详解助手类

        因为select没有标签体,但是要输出内容,所以需要用流对象进行拼接

         拼接的方法,获取值在进行拼接 

         一切反射从获取类类开始

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值