select标签

思路:首先思考select标签所需要的属性,取数据的集合是必须的(item),还有显示的数据和上传的数据(TextVal和TextKey),还有设置默认选择的数据(SelectedVal),还有我们头标签的显示和上次数据(headerVal和headerKey),下面我们是以一个学生类的id和name来当作我们的传值数据和显示数据,所以我们就是以它的属性名id和name来取值的

SelectTag助手类

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

public class SelectTag extends BodyTagSupport{
	
	private String id;
	private String name;
	private List<Object> items=new ArrayList<>();
	private String textKey;  //id=textKey
	private String textVal;
	private String selectedVal;
	private String headerTextKey;
	private String headerTextVal;
	
	
	@Override
	public int doStartTag() throws JspException {
		JspWriter out = pageContext.getOut();
		try {
			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 (IOException e) {
			e.printStackTrace();
		}
		return SKIP_BODY;
	}
	private String toHTML() throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
		StringBuffer sb=new StringBuffer();
		sb.append("<select id='"+id+"' name='"+name+"'>");//初始select
		//判断头标签不能为空
		if(!(headerTextKey==null||"".equals(headerTextVal)||headerTextVal==null||"".equals(headerTextVal))) {
			sb.append("<option selected value='"+headerTextKey+"'>"+headerTextVal+"</option>");
		}
		String value;
		String html;
		for (Object obj : items) {
			//利用反射获取类对象的属性,也就是我们下拉框的显示值和数据值
			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(value.equals(selectedVal)) {
				sb.append("<option selected value='"+value+"'>"+html+"</option>");
			}
			else {
				sb.append("<option value='"+value+"'>"+html+"</option>");
			}
		}
		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;
	}
	public SelectTag() {
		super();
	}
}

最后再jsp页面输入验证代码就可以用了(是再引入了taglib的前提下)

<%
	List ls=new ArrayList();
	ls.add(new Student("001","aaaa"));
	ls.add(new Student("002","bbbb"));
	ls.add(new Student("003","cccc"));
	List ls1=new ArrayList();
	ls1.add("001");
	ls1.add("002");
	request.setAttribute("ls", ls);
	
%>
	
	
	<z:select headerTextKey="-1" headerTextVal="---请选择---" textVal="name" items="${ls}" textKey="id"></z:select> 

结果为成功显示数据
自定义jsp标签案例_jsp自定义标签

checkbox标签

一样,首先我们来分析它需要的属性,取数据的集合,显示值和传入值,它与select标签不同的是它的回显数据需要是一个集合,因为它可能选中的标签不只一个,所以是一个集合。

配置描述文件

    <tag>
    <name>checkbox</name>
    <tag-class>com.xy.taglib.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>

CheckeboxTag助手类

public class CheckboxTag extends BodyTagSupport {
	
	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)) {//判断回显集合里是否包含这个value,包含就设置选择
				sb.append("<input checked type='checkbox' value='"+value+"' />"+html+"");
			}
			else {
				sb.append("<input type='checkbox' value='"+value+"' />"+html+"");
			}
		}
		return sb.toString();
	}
}

代码验证复选框标签是否正确

<%
	List ls=new ArrayList();
	ls.add(new Student("001","aaaa"));
	ls.add(new Student("002","bbbb"));
	ls.add(new Student("003","cccc"));
	List ls1=new ArrayList();
	ls1.add("001");
	ls1.add("002");
	request.setAttribute("ls", ls);
	request.setAttribute("ls1", ls1);
	
%>
	
	<z:checkbox textVal="name" checkedVal="${ls1}" item="${ls}" textKey="id"></z:checkbox> 

结果可知,ls1集合中的数据全部选中了
自定义jsp标签案例_数据_02

数据字典应用

使用的下拉框,只要定义使用那个字典就会将这个字典可用的内容显示出来
显示字典时只要定义那个字典和属性值就可以显示出字典的显示值,和我们的out标签的效果是一样的

下面我们用下拉框的一个案例来说明,用3个助手类来好理解

OptionTag

public class OptionsTag extends BodyTagSupport {
	public int doStartTag() throws JspException {
		return EVAL_BODY_INCLUDE;
	}
	@Override
	public int doEndTag() throws JspException {
		try {
			StringBuffer results = new StringBuffer("");
			if ("SEX".equals(collection)) {//数据当然可以从数据遍历
				results.append("<option value=\"0\"  selected=\"selected\">请选择</option>");
				results.append("<option value=\"1\">男</option>");
				results.append("<option value=\"2\">女</option>");
			}
			pageContext.getOut().write(results.toString());
		} catch (IOException ex) {
			throw new JspTagException("错误");
		}
		return EVAL_PAGE;
	}
	// collection只是传递一个标识,具体下拉值内容是从数据库取还是从请求中得到为不同具体实现
	protected String collection;
	public String getCollection() {
		return collection;
	}
	public void setCollection(String collection) {
		this.collection = collection;
	}
}

SelectTag

	public int doStartTag() throws JspException {
		try {
			StringBuffer results = new StringBuffer("<select");
			if(name != null){
	            results.append(" name=\"");
	            results.append(name);
	            results.append("\"");
	        }
			if(style != null){
	            results.append(" style=\"");
	            results.append(style);
	            results.append("\"");
	        }
			results.append(">");
			pageContext.getOut().write(results.toString());
		} catch (IOException ex) {
			throw new JspTagException("错误");
		}
		return EVAL_BODY_INCLUDE;
	}
	@Override
	public int doEndTag() throws JspException {
		try {
			StringBuffer results = new StringBuffer("");
			// 因为下拉中包含下拉内容,所以只能在遇到结束标签时才能写select结束
			results.append("</select>");			
			pageContext.getOut().write(results.toString());
		} catch (IOException ex) {
			throw new JspTagException("错误");
		}
		return EVAL_PAGE;
	}
	// 样式
	protected String style;
	// 名字
	protected String name;
	public String getStyle() {
		return style;
	}
	public void setStyle(String style) {
		this.style = style;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

SelectDisplay

	public int doStartTag() throws JspException {
		try {
			StringBuffer results = new StringBuffer("");
			pageContext.getOut().write(results.toString());
		} catch (IOException ex) {
			throw new JspTagException("错误");
		}
		return EVAL_BODY_INCLUDE;
	}
	@Override
	public int doEndTag() throws JspException {
		try {
			StringBuffer results = new StringBuffer("");
			if ("SEX".equals(collection)) {
				results.append("<span>");
				results.append("<input type=\"");
				results.append("hidden\" name=\"");
				results.append(getName());
				results.append("\"");
				results.append(" value=\"");
				results.append(getValue());
				results.append("\">");				
				if ("1".equals(getValue())) {
					results.append("男");
				} else if ("2".equals(getValue())) {
					results.append("女");
				} else {
					results.append("请选择");
				}
				results.append("</span>");
			}
			pageContext.getOut().write(results.toString());
		} catch (IOException ex) {
			throw new JspTagException("错误");
		}
		return EVAL_PAGE;
	}
	// collection只是传递一个标识,具体下拉值内容是从数据库取还是从请求中得到为不同具体实现
	protected String collection;
	// 传递的值
	protected String value;
	// 该属性的名称
	protected String name;
	public String getCollection() {
		return collection;
	}
	public void setCollection(String collection) {
		this.collection = collection;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getValue() {
		return value;
	}
	public void setValue(String value) {
		this.value = value;
	}

tld文件就不写了,根据属性去配置就好了,这是jsp代码验证,我这里value值为1,也就是男,如果数据显示为了男那就是对了

	请选择:
		<x:select name="sex" style="width:100px">
			<x:options collection="SEX"></x:options>
		</x:select> 
		显示性别:
		<x:selectDisplay collection="SEX" value="1" name="sex"></x:selectDisplay>

结果为:显示性别为男,我如果改为2,显示性别就为女了
自定义jsp标签案例_html_03