jsp标签内部解析及自定义——2

上文为大家讲解了jsp标签的C标签里的解析,有兴趣的可以去看看:
jsp标签内部解析及自定义——1

现在以C标签为例,为大家讲解一下原理。
一般来讲,标签分为3大类标签:
1,UI标签,没有标签体,且用来打印数据到jsp页面的标签。
2,控制标签,有标签体,但是通过属性来控制是否显示输出的。
3,数据标签,一边用来对数据进行操作,不能显示到页面。

set:

set是数据标签,就和赋值一样,他有两个参数:
1,var 也就是对象,
2,value也就是值,
明白参数后就可以设置tld文件了:

   <tag>
    <description>
        赋值标签
    </description>
    <!-- 标签库的标签名 -->
    <name>set</name>
    <!-- 便签对应的助手类的全路径名 -->
    <tag-class>com.zking.jsp.day02.SetTag</tag-class>
    
    <body-content>JSP</body-content>
    <attribute>
        <description>
var属性   --对象
        </description>
        <!-- 属性名 -->
        <name>var</name>
        <!-- 属性值是否必填 -->
        <required>true</required>
        <!-- 是否支持表达式  也就是是否可以使用${}  false的话只能填字符串  -->
        <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
        <description>
value   --值
        </description>
        <!-- 属性名 -->
        <name>value</name>
        <!-- 属性值是否必填 -->
        <required>true</required>
        <!-- 是否支持表达式  也就是是否可以使用${}  false的话只能填字符串  -->
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

设置完tld就去设置标签助手类:

package com.jsp.day02;

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

public class SetTag extends BodyTagSupport {

	private static final long serialVersionUID = 4965191755704898746L;
	
	private String var;
	private Object value;
	
	@Override
	public int doStartTag() throws JspException {
		pageContext.setAttribute(var, value);
		return SKIP_BODY;
	}
	
	public String getVar() {
		return var;
	}
	public void setVar(String var) {
		this.var = var;
	}
	public Object getValue() {
		return value;
	}
	public void setValue(Object value) {
		this.value = value;
	}
	
	set也比较简单,就是把键和值都存入作用域里,就行了,可以用${}调用,也可以out输出。
	
}

out:

out是UI标签,语法比较简单,他的作用是输出:
首先的是设置tld:

<tag>
    <description>
        输出标签
    </description>
    <!-- 标签库的标签名 -->
    <name>out</name>
    <!-- 便签对应的助手类的全路径名 -->
    <tag-class>com.zking.jsp.day02.OutTag</tag-class>
    
    <body-content>JSP</body-content>
    
    <attribute>
        <description>
输出的值
        </description>
        <!-- 属性名 -->
        <name>value</name>
        <!-- 属性值是否必填 -->
        <required>true</required>
        <!-- 是否支持表达式  也就是是否可以使用${}  false的话只能填字符串  -->
        <rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>

在value属性里,可以输出作用域里的键值,也可以输出set赋的值。也可以输出字符串。

现在写标签助手类:

package com.jsp.day02;

import java.io.IOException;

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

public class OutTag extends BodyTagSupport {

	private static final long serialVersionUID = 6097318304486137249L;
	
	private Object value;

	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}
	
	@Override
	public int doStartTag() throws JspException {
		JspWriter out = pageContext.getOut();
		try {
			out.print(value.toString());
		} catch (IOException e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}
	
}	

可以看到,out作用只需要就行,获取out,然后运用out.print()输出。

if

if是控制标签,相对来说也比较简单,他底层运用三元运算符就能完成的。

package com.zking.jsp.day02;

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

public class IfTag extends BodyTagSupport {

	private static final long serialVersionUID = -8477321984637500253L;
	
	private boolean test;

	public boolean isTest() {
		return test;
	}

	public void setTest(boolean test) {
		this.test = test;
	}
	
	@Override
	public int doStartTag() throws JspException {
		// TODO Auto-generated method stub
		return test? EVAL_BODY_INCLUDE:SKIP_BODY;
	}
}

相对来说,是通过test的值来判断是否跳过主体还是计算主体。

Foreach

Foreach标签也是属于控制标签的,和迭代器一样是用来遍历集合的。

package com.jsp.day02;

import java.util.ArrayList;
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 = -2643407962233076616L;
	
	private String var;
	private List<Object> items = new ArrayList<>();
	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;
	}
	
	/**
	 * 执行完这个方法的时候,var所代表的指针一定要向下移一位
	 */
	@Override
	public int doStartTag() throws JspException {
		if(items.size()==0) {
			return SKIP_BODY;
		}else {
			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 EVAL_PAGE;
	}
	
}

Select

select 标签,也就是制作一个下拉列表的标签。是属于UI标签。

package com.jsp.day02;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
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;


/**
 * 1,值的传递 id,name
 * 2,数据源	items
 * 3,展示列 与数据存储列与实体类的对应关系  textKey   textVal
 * 4,数据回显   selectedVal
 * 5,可能下拉框有默认值 (头标签) headerTextKey	headerTextVal
 * @author Administrator
 *
 */
public class SelectTag extends BodyTagSupport {

	private static final long serialVersionUID = 5375902073989817712L;
	
	private String id;
	private String name;
	private List<Object> items = new ArrayList<Object>();
	private String textKey;
	private String textVal;
	private String selectedVal;
	private String headerTextKey;
	private String headerTextVal;
	
	@Override
	public int doStartTag() throws JspException {
		JspWriter out = pageContext.getOut();
		
		try {
			out.print(toHTML());
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
				
		return super.doStartTag();
	}
	
	
	private String toHTML() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		StringBuffer sb = new StringBuffer();
		sb.append("<select id='"+id+"' name='"+name+"'>");
		if(!(headerTextKey==null ||"".equals(headerTextKey)||headerTextVal==null||"".equals(headerTextVal))) {
			sb.append("<option selected value='"+headerTextKey+"'>"+headerTextVal+"</option>");
		}
		String value;
		String html;
		for (Object obj : items) {
			Field f = obj.getClass().getDeclaredField(textKey);
			f.setAccessible(true);
			value = (String) f.get(obj);
			html = (String) PropertyUtils.getProperty(obj, textVal);
			if(value.equals(selectedVal)) {
				//为什么加了selected就默认显示李四了
				sb.append("<option selected value='"+value+"'>"+html+"</option>");
			}else {
				
				sb.append("<option value='"+value+"'>"+html+"</option>");
			}
			
		}
		sb.append("</select>");
		return sb.toString();
	}


	public String getId() {
		return id;
	}


	public void setId(String id) {
		this.id = id;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public List<Object> getItems() {
		return items;
	}


	public void setItems(List<Object> items) {
		this.items = items;
	}


	public String getTextKey() {
		return textKey;
	}


	public void setTextKey(String textKey) {
		this.textKey = textKey;
	}


	public String getTextVal() {
		return textVal;
	}


	public void setTextVal(String textVal) {
		this.textVal = textVal;
	}


	public String getSelectedVal() {
		return selectedVal;
	}


	public void setSelectedVal(String selectedVal) {
		this.selectedVal = selectedVal;
	}


	public String getHeaderTextKey() {
		return headerTextKey;
	}


	public void setHeaderTextKey(String headerTextKey) {
		this.headerTextKey = headerTextKey;
	}


	public String getHeaderTextVal() {
		return headerTextVal;
	}


	public void setHeaderTextVal(String headerTextVal) {
		this.headerTextVal = headerTextVal;
	}
}	

checkbox

checkbox,创建一个复选框,且可以回显选中的,也是属于UI类型

标签助手类:

package com.zking.jsp.day02;

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;

import org.apache.commons.beanutils.PropertyUtils;


public class CheckboxTag extends BodyTagSupport {

	private static final long serialVersionUID = -5301514341025414346L;
	private String textKey;//传入值
	private String textVal;//显示值
	private List<Object> checkedVal=new ArrayList<>();//回显数据集合
	private List<Object> item=new ArrayList<>();//数据集合
	
	public List<Object> getItem() {
		return item;
	}
	public void setItem(List<Object> item) {
		this.item = item;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	
	public String getTextKey() {
		return textKey;
	}
	public List<Object> getCheckedVal() {
		return checkedVal;
	}
	public void setCheckedVal(List<Object> checkedVal) {
		this.checkedVal = checkedVal;
	}
	public void setTextKey(String textKey) {
		this.textKey = textKey;
	}
	public String getTextVal() {
		return textVal;
	}
	public void setTextVal(String textVal) {
		this.textVal = textVal;
	}
	
	public CheckboxTag() {
		super();
	}
	
	public CheckboxTag(String textKey, String textVal, List<Object> checkedVal, List<Object> item) {
	super();
	this.textKey = textKey;
	this.textVal = textVal;
	this.checkedVal = checkedVal;
	this.item = item;
}
	@Override
	public int doStartTag() throws JspException {
		JspWriter out = pageContext.getOut();
		try {
			out.print(toHTML());
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return super.doStartTag();
	}
	private String toHTML() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		StringBuffer sb=new StringBuffer();
		String value;
		String html;
		for (Object obj : item) {
			Field textKeyfield = obj.getClass().getDeclaredField(textKey);
			textKeyfield.setAccessible(true);
			value=(String)textKeyfield.get(obj);
			Field textValfield = obj.getClass().getDeclaredField(textVal);
			textValfield.setAccessible(true);
			html=(String)textValfield.get(obj);
			if(checkedVal.contains(value)) {
				sb.append("<input checked type='checkbox' value='"+value+"' />"+html+"");
			}
			else {
				sb.append("<input type='checkbox' value='"+value+"' />"+html+"");
			}
		}
		return sb.toString();
	}
}

属性设置:

    <tag>
    <name>checkbox</name>
    <tag-class>com.zking.jsp.day02.CheckboxTag</tag-class>
    
    <body-content>JSP</body-content>
    
    <attribute>
        <name>textKey</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
     </attribute>
     <attribute>
        <name>textVal</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
     </attribute>
      <attribute>
        <name>item</name>
        <required>true</required>
        <rtexprvalue>true</rtexprvalue>
     </attribute>
     <attribute>
        <name>checkedVal</name>
        <required>false</required>
        <rtexprvalue>true</rtexprvalue>
     </attribute>
  </tag>

来试验一下:

<%
	List ls=new ArrayList();
	ls.add(new student("1","唱"));
	ls.add(new student("2","跳"));
	ls.add(new student("3","rap"));
	List lb = new ArrayList();
	session.setAttribute("lb", lb);
	lb.add("1");
	lb.add("3");
	request.setAttribute("ls", ls);
	request.setAttribute("lb", lb);
	
%>
<z:checkbox textVal="name" checkedVal="${lb}" item="${ls}" textKey="id"></z:checkbox>

运行结果为:

在这里插入图片描述
这样就完成了~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值