jsp自定义标签(二)

文章目录

  • 一、前言
  • 二、自定义forEach标签实例
    • 2.1代码示例
    • 2.2 注意事项
  • 三、自定义select标签实例
    • 3.1代码示例
    • 3.2 注意事项
  • 四、今日总结

一、前言

上篇博客地址指路牌:自定义标签(一)
上一篇博客中我们已经讲述了自定义标签的开发步骤和简单实例,这篇博客我们讲述一下两个比较复杂的自定义标签。

二、自定义forEach标签实例

2.1代码示例

按照自定义标签开发步骤,首先写一个助手类:
items:需要遍历的集合;
name(一般来说用var来表示,我因为之前测试改成了name):保存集合中每个元素的key值;
varStatus:是保存index count 属性的对象的key;
代码详解跟随在代码中:

package com.zengjing.jsp.day0202;

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 static final long serialVersionUID = 1L;
	
	private List<Object> items;//需要遍历的集合
	
	private String name;//保存集合中每个元素的key值
	
	private String varStatus;//是保存index count 属性的对象的key
	
	//匿名内部类 将其视作对象,index 和count视作属性来操作
	public static class Status{
		//定义一个index用来读取下标
		public int index=0;

		public int getIndex() {
			return index;
		}

		public void setIndex(int index) {
			this.index = index;
		}
		/**
		 * 借助index来获取这是第几个值
		 * @return
		 */
		public int getCount() {
			return this.index+1;
		}
		/**
		 * index自增方法
		 */
		void incremetn(){
			this.index++;
		}
		
	}
	
	public String getVarStatus() {
		return varStatus;
	}



	public void setVarStatus(String varStatus) {
		this.varStatus = varStatus;
	}



	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;
	}



	/**
	 * 执行到doAfterBody方法时,有需要操作的代码
	 */
	@Override
	public int doAfterBody() throws JspException {
		//获取之前存储的迭代器
		Iterator<Object> it =(Iterator<Object>) pageContext.getAttribute("it");
		//如果他有下一个值
		while(it.hasNext()) {
			//如果varStatus有值
			if(null!=varStatus && !"".equals(varStatus)) {
				//获取到varStatus的值
				Status s =(Status) pageContext.getAttribute(varStatus);
				//执行自增的方法
				s.incremetn();
				//重新保存到varStatus
				pageContext.setAttribute(varStatus, s);
			}
			//再获取到迭代器的下一个值
			Object next = it.next();
			//再保存到name中
			pageContext.setAttribute(name, next);
			//再执行主体一次
			return EVAL_BODY_AGAIN;
		}
		//如果没有下一个值就会跳出主体结束循环
		return super.doAfterBody();
	}


	/**
	 * 进入助手类首先执行的doStartTag方法
	 */
	@Override
	public int doStartTag() throws JspException {
		//第一次进入doStartTag方法的时候,varStatus如果有值,我们需要new一个Status给它,用来读取下标和个数
		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();
			//将下一个值保存到name中
			pageContext.setAttribute(name, next);
			//将迭代器保存到当前页面
			pageContext.setAttribute("it", it);
			
			
		}
		return EVAL_BODY_INCLUDE;
	}
	
}

配置tld文件中的属性:
items:必填可为表达式;
name:必填不可为表达式;
varStatus:非必填不可为表达式;

 <tag>
	    <name>forEach</name>
	    <tag-class>com.zengjing.jsp.day0202.ForEachTag</tag-class>
	    <body-content>JSP</body-content>
	     <attribute>
	    	<name>items</name>
	    	<required>true</required>
	    	<rtexprvalue>true</rtexprvalue>
	    </attribute>
	    <attribute>
	    	<name>name</name>
	    	<required>true</required>
	    	<rtexprvalue>false</rtexprvalue>
	    </attribute>
	     <attribute>
	    	<name>varStatus</name>
	    	<required>false</required>
	    	<rtexprvalue>false</rtexprvalue>
	    </attribute>
	    
	 </tag>

头部导入taglib标签:
jsp自定义标签(二)_第1张图片
效果图:
依次是集合中的内容、下标、第几个
jsp自定义标签(二)_第2张图片

2.2 注意事项

写forEach标签助手类的时候,保存值的时候一定不能忘记!否则会报空指针异常:
jsp自定义标签(二)_第3张图片

三、自定义select标签实例

3.1代码示例

按照自定义标签开发步骤,首先写一个助手类:
items:需要用select展示的集合
name:select的名字
valueKey:保存option中的value的key
textKey:保存option中text文本的key
cssStyle:样式
headKey:默认展示的key值
headValue:默认展示的文本
selectedOptionValue:默认选中的key值
代码详解在代码中:

package com.zengjing.jsp.day0202;

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;//需要用select展示的集合
	
	private String name;//select的名字
	
	private String valueKey;//保存option中的value的key

	private String textKey;//保存option中text文本的key
	
	private String cssStyle;//样式
	
	private String headKey;//默认展示的key值
	
	private String headValue;//默认展示的文本
	

	private String selectedOptionValue;//默认选中的key值

	public String getSelectedOptionValue() {
		return selectedOptionValue;
	}

	public void setSelectedOptionValue(String selectedOptionValue) {
		this.selectedOptionValue = selectedOptionValue;
	}

	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 getCssStyle() {
		return cssStyle;
	}

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

	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;
	}

	/**
	 * 首先实例化助手类进入doStartTag方法
	 */
	@Override
	public int doStartTag() throws JspException {
		//获取到out
		JspWriter out = pageContext.getOut();
		try {
			//通过打印输出方法返回的字符串将内容展示在页面
			out.println(toHtml());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return super.doStartTag();
	}
	
	private String toHtml() throws Exception {
		//用StringBuffer拼接需要返回的字符串
		StringBuffer sb=new StringBuffer();
		//拼接开头
		sb.append("");
		
		return sb.toString();
	}
	
}

需要配置的tld文件:
items:必填可为表达式
name:非必填不可为表达式
valueKey:必填不可为表达式
textKey:必填不可为表达式
cssStyle:非必填不可为表达式
headKey:非必填不可为表达式
headValue:非必填不可为表达式
selectedOptionValue:非必填不可为表达式

 <tag>
	    <name>select</name>
	    <tag-class>com.zengjing.jsp.day0202.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>

头部导入taglib标签:
jsp自定义标签(二)_第4张图片
效果图:
jsp自定义标签(二)_第5张图片

3.2 注意事项

1.这里用value作比较时需要.toString(),不然因为它本来是object类型会比较不了:
jsp自定义标签(二)_第6张图片
2.拼接时也一定要小心不要拼错!单引号不要忘了!
3.还有反射需要这两个包:

四、今日总结

自定义标签到此结束!有问题欢迎留言评论指教哦!
jsp自定义标签(二)_第7张图片

你可能感兴趣的:(jsp自定义标签(二))