jsp 自定义标签-SimpleTagSupport 使用笔记

项目需求:jsp页面自定义搜索行,点击a标签搜索分类,重新刷新页面,select标签加载数据后由js控制搜索请求链接。
内容:搜索行主要包括A标签 和select标签,a标签生成时带href,具体内容由request获取的属性和属性值生成。select标签实现页面刷新时加载初始化数据即可。
这里只需要实现三个自定义标签即可:
1.父标签:
    selectlineTag,主要存放表示搜索指定分类的初始化值。
2.子标签:
    ATag:a标签,搜索某类的指定值,点击后带上这个标签代表的查询分类值,请求后台查询。

    SelectTag:select标签。

custom.tld  放在WEB-INF/文件夹下,自定义标签所需jar包:jsp-api.jar,servlet-api.jar

<taglib>
	<tlib-version>1.0</tlib-version>
	<jsp-version>2.0</jsp-version>
	<short-name>search row tld</short-name>
	<tag>
		<name>searchline</name>
		<tag-class>com.test.tag.SearchlineTag</tag-class>
		<body-content>scriptless</body-content>
		<attribute>
			<name>defaulvalue</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>选择行的默认值(选择行包括a 和select标签,默认值包括这些标签对应的值)。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>defaultcls</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>行选择其子项被选中时的class样式缺省值:""。</description>
		</attribute>
		<attribute>
			<name>basehref</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>子项a标签href搜索链接地址:""。</description>
		</attribute>
		<attribute>
			<name>defaultsplit</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>默认值分组符号,有时候默认值对应多个组件的值,多个select时用到:""。</description>
		</attribute>
	</tag>
	
	<tag>
		<name>select</name>
		<tag-class>com.test.tag.selectTag</tag-class>
		<body-content>scriptless</body-content>
		<attribute>
			<name>type</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>select类型,值:num|""。num数值时数据可以传start下拉选框的开始范围,end,step每个下拉项步长。属性缺省值:""。</description>
		</attribute>
		<attribute>
			<name>displayField</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>缺省值:""。</description>
		</attribute>
		<attribute>
			<name>valueField</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>缺省值:""。</description>
		</attribute>
		<attribute>
			<name>defaultValNo</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>对应父标签defaultvalue中的值第几个值,"杭州-下城区",0:杭州,1:下城区。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>defaultValNo</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>对应父标签defaultvalue中的值第几个值,"杭州-下城区",0:杭州,1:下城区。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>cls</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>select标签本身需要带有的样式。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>style</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>data</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>select标签数据内容。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>show</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>初始化时是否展示这个select html标签,show可选值:select 有选中值时显示,all 显示,no 不显示。 缺省值:""。</description>
		</attribute>
		<attribute>
			<name>start</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>type属性为num时,如年份表示option中年份开始时间。 缺省值:""。</description>
		</attribute>
		<attribute>
			<name>end</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>type属性为num时,如年份表示option中年份结束时间。 缺省值:""。</description>
		</attribute>
		<attribute>
			<name>step</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>type属性为num时,表示option中年份值步长。 缺省值:""。</description>
		</attribute>
		<attribute>
			<name>prompText</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>下拉框不代表任何选中的值,一般放在下拉选框的第一个选项,如“请选择”</description>
		</attribute>
	</tag>
	<tag>
		<name>a</name>
		<tag-class>com.test.tag.ATag</tag-class>
		<body-content>scriptless</body-content>
		<attribute>
			<name>type</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>href标记的属性值。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>cls</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>a标签的样式。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>needhref</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>是否需要href标签,根据父标签的basehref生成。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>text</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>a标签的文本内容。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>key</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>查询中a标签代表的字段名,生成href时在basehref基础上修改。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>value</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>a标签的值和其父标签的defaultvalue对应,且和key对应。缺省值:""。</description>
		</attribute>
		<attribute>
			<name>basehref</name>
			<required>false</required>
			<rtexprvalue>true</rtexprvalue>
			<description>父级标签带了,这里就不需要了。搜索链接地址:""。</description>
		</attribute>	
	</tag>
</taglib>


父级标签:searchlineTag

package com.test.tag;

import java.io.IOException;

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

public class SearchlineTag extends SimpleTagSupport {
	private String label;
	private String basehref;
	private String defaultcls;
	private String defaulvalue;
	private String defaultsplit;

	public String getDefaultsplit() {
		if (defaultsplit == null || "".equals(defaultsplit)) {
			return "-";
		}
		return defaultsplit;
	}

	//此处省略 get/set....
	public void doTag() throws JspException, IOException {

		//SearchlineTag 标签作用显示标签体,以及作为其他两个标签的父标签;
		getJspBody().invoke(null);
	}

}
子标签:A标签实现

public class ATag extends SimpleTagSupport {

	private String key;
	private String value;
	private String text;
	private String needhref;
	private String type;
	private String cls;
	private String basehref;

	//此处省略 get/set.....

	public void doTag() throws JspException, IOException {
		PageContext pageContext = (PageContext) this.getJspContext();
		ServletRequest request = pageContext.getRequest();
		JspFragment jspFragment = this.getJspBody();
		String content = "";
		if (this.text != null) {
			content = this.text;
		}
		SearchlineTag parent = null;

		if (getParent() instanceof SearchlineTag) {
			parent = (SearchlineTag) getParent();
		} else {
			// 如果在父级和子标签中还嵌套了其他标签如<c:if>要访问父级以上的标签就用这个。
			parent = (SearchlineTag) ATag.findAncestorWithClass(this, SearchlineTag.class);
		}

		String hrefstr = "";
		String clsStr = "";
		String adefaultv = "";
		String defaultcls = "";
		String pbasehref = "";
		if (parent != null) {
			adefaultv = parent.getDefaulvalue();
			defaultcls = parent.getDefaultcls();
			pbasehref = parent.getBasehref();
		}

		if (adefaultv.equals(this.value) && defaultcls != "") {
			clsStr = " class ='" + (this.cls != null ? this.cls : "") + " " + defaultcls + "'";
		} else {
			clsStr = " class ='" + (this.cls != null ? this.cls : "") + "'";
		}
		if ("false".equals(this.needhref)) {
			hrefstr = " href='javascript:void(0);' ";
		} else if ("true".equals(this.needhref)) {
			if (this.basehref != null) {
				pbasehref = this.basehref;
			}
			hrefstr = " href='" + replaceHref(pbasehref, this.key, this.value) + "' ";
		}

		JspWriter out = getJspContext().getOut();
		String outstr = "";
		outstr = "<a ";
		outstr += hrefstr + clsStr;
		outstr += ">" + content + "</a>";
		out.println(outstr);

	}

	//替换搜索链接中标签代表的键和值
	public String replaceHref(String baseHref, String replaceKey, String replaceValue) {

		if (replaceKey == null || "".equals(replaceKey)) {
			return baseHref;
		}
		if (replaceValue == null) {
			replaceValue = "";
		}
		String[] bhref = baseHref.split("\\?");
		String[] paramhref = null;
		List newParam = new ArrayList();
		boolean ischecked = false;
		String newHref = "";
		if (bhref.length > 1) {
			paramhref = bhref[1].split("&");
		}

		if (paramhref != null) {
			int size = paramhref.length;
			for (int i = 0; i < size; i++) {
				String ps = paramhref[i];
				String[] ins = ps.split("=");
				if (replaceKey.equals(ins[0])) {
					String inns = "" + ins[0] + "=" + replaceValue;
					newParam.add(inns);
					ischecked = true;
				} else {
					newParam.add(ps);
				}
			}
		}

		if (!ischecked) {
			newParam.add("" + replaceKey + "=" + replaceValue);
		}
		int newsize = newParam.size();
		for (int k = 0; k < newsize; k++) {
			newHref += newParam.get(k).toString();
			if (k < newsize - 1) {
				newHref += "&";
			}
		}
		return bhref[0] + "?" + newHref;
	}
}

select标签实现:

public class selectTag extends SimpleTagSupport {
	private String data;
	private String key;
	private String value;
	private String text;
	private String cls;
	private String style;
	private String valueField;
	private String displayField;
	private String defaultValNo;
	private String show;
	private String start;
	private String end;
	private String step;
	private String type;
	private String prompText;

	//此处省略get/set。。。 z这里吧属性和tld中的属性对应

	public void doTag() throws JspException, IOException {
		PageContext pageContext = (PageContext) this.getJspContext();
		ServletRequest request = pageContext.getRequest();
		String selectdata = this.data != null ? this.data : "[]";
		String content = "";
		String clsStr = "";
		Integer startsel = null;
		Integer endsel = null;
		Integer stepsel = null;
		if (this.start != null) {
			try {
				startsel = Integer.parseInt(this.start);
			} catch (Exception e) {				
			}
		}

		if (this.end != null) {
			try {
				endsel = Integer.parseInt(this.end);
			} catch (Exception e) {				
			}
		}
		if (this.step != null) {
			try {
				stepsel = Integer.parseInt(this.step);
			} catch (Exception e) {				
			}
		}

		if (this.text != null) {
			content = this.text;
		}
		if (this.valueField == null) {
			this.valueField = "value";
		}
		if (this.displayField == null) {
			this.displayField = "text";
		}
		if (this.defaultValNo == null) {
			this.defaultValNo = "0";
		}
		if (this.cls == null) {
			this.cls = "";
		} else {
			clsStr = " class='" + this.cls + "'";
		}

		if (this.style == null) {
			this.style = "";
		}

		if (this.show == null) {
			this.show = "all";
		}
		if (this.type == null) {
			this.type = "";
		}
		SearchlineTag parent = null;
		if (getParent() instanceof SearchlineTag) {
			parent = (SearchlineTag) getParent();
		} else {
			parent = (SearchlineTag) ATag.findAncestorWithClass(this, SearchlineTag.class);
		}

		String optionstr = "";
		String seloptionstr = "";
		String adefaultv = "";
		String defaultcls = "";
		String pbasehref = "";
		String defaultsplit = "-";
		String[] adefaultvs = null;
		if (parent != null) {
			adefaultv = parent.getDefaulvalue();
			defaultcls = parent.getDefaultcls();
			pbasehref = parent.getBasehref();
			defaultsplit = parent.getDefaultsplit();
		}
		if (adefaultv != null && !"".equals(adefaultv)) {
			adefaultvs = adefaultv.split(defaultsplit);// defaultsplit:"-"
			int index = Integer.parseInt(this.defaultValNo);
			if (index < adefaultvs.length) {
				adefaultv = adefaultvs[index];
			} else {
				adefaultv = null;
			}
		}

		if (!"".equals(selectdata)) {
			JSONArray datajson = JSONArray.fromObject(selectdata);
			int size = datajson.size();
			for (int k = 0; k < size; k++) {
				Map map2 = (Map) datajson.get(k);
				String val = (String) map2.get(this.valueField);
				String textv = (String) map2.get(this.displayField);
				if (adefaultv != null && val.equals(adefaultv)) {
					seloptionstr = "<option value='" + val + "' selected>" + textv + "</option>";
				}

				optionstr += "<option value='" + val + "' >" + textv + "</option>";
			}
		}

		if ("num".equals(this.type) && ("[]".equals(selectdata) || "".equals(selectdata)) && startsel != null
				&& endsel != null && stepsel != null) {// year
			// 的值是数值类型select。
			Integer numV = null;
			try {
				numV = Integer.parseInt(adefaultv);
			} catch (Exception e) {
				numV = null;
			}
			if (stepsel < 0) {
				for (int k = startsel; k >= endsel; k = k + (stepsel)) {

					if (adefaultv != null && numV != null && k == numV) {
						seloptionstr = "<option value='" + k + "' selected>" + k + "</option>";
					}
					optionstr += "<option value='" + k + "' >" + k + "</option>";
				}
			} else if (stepsel > 0) {
				for (int k = startsel; k <= endsel; k = k + stepsel) {
					if (adefaultv != null && numV != null && k == numV) {
						seloptionstr = "<option value='" + k + "' selected>" + k + "</option>";
					}
					optionstr += "<option value='" + k + "' >" + k + "</option>";
				}
			} else {
				if (adefaultv != null && numV != null && startsel == numV) {
					seloptionstr = "<option value='" + startsel + "' selected>" + startsel + "</option>";
				}
				optionstr += "<option value='" + startsel + "' >" + startsel + "</option>";
			}
		}

		JspWriter out = getJspContext().getOut();
		String outstr = "";
		if ("no".equals(this.show) || ("select".equals(this.show) && "".equals(seloptionstr))) {
			clsStr += "  style='" + this.style + ";display:none;'";
		} else if (!"".equals(this.style)) {
			clsStr += "  style='" + this.style + "'";
		}
		if (this.prompText != null) {
			if ("".equals(seloptionstr)) {// 未有选中值,提示的内容默认选中。
				seloptionstr = "<option value='请选择' selected>" + this.prompText + "</option>";
			} else {
				seloptionstr += "<option   value='请选择' >" + this.prompText + "</option>";
			}
		}
		outstr = "<select ";
		outstr += clsStr;
		outstr += ">" + seloptionstr + optionstr + "</select>";
		out.println(outstr);
	}
}


jsp使用:

<%@ page contentType="text/html;charset=UTF-8" language="java"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<%@ taglib uri="/WEB-INF/custom.tld" prefix="cst" %>
<%@page import="java.net.URLEncoder"%>
<%@page import="java.util.*"%>
<%@page import="java.text.*"%>
<%@page import="net.sf.json.JSONArray"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
</head>
<body >

<%
		request.setCharacterEncoding("UTF-8");
		//String key = java.net.URLEncoder.encode(request.getParameter("key"), "UTF-8");
		String key ="a";//搜索关键字		
		String area = "";
		String time= "";//生成时间
		String issue_time ="2014-2017";//发布时间
		String pageses= "";	
		String parentarea = "";
		String subarea = "";		
		request.setAttribute("parentarea","[{\"name\":\"杭州\"},{\"name\":\"绍兴\"},{\"name\":\"湖州\"}]");
		request.setAttribute("subarea","[{\"name\":\"拱墅区\"},{\"name\":\"西湖区\"},{\"name\":\"上城区\"}]");
	
		String basehref="search?key="+key+"&area="+area+"&time="+time
				+"&issue_time="+issue_time+"&pageses="+pageses;         
		String yeardata="";
		Date myDate = new Date();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy");  
		String startyear= dateFormat.format(myDate.getTime());		 
		request.setAttribute("start",startyear);
		request.setAttribute("end",Integer.parseInt(startyear)-100);		
		String hasLogin = request.getAttribute("isLogin") != null ? request.getAttribute("isLogin").toString() : "";			
	%>
		<div class="area"> 
			<span>地        区:</span>
			<cst:searchline  defaultcls="onclick" defaulvalue="<%=area%>" defaultsplit="-" basehref="<%=basehref %>"  >				
				<cst:a needhref="true"   key="area" value=""  text="不限" ></cst:a>
				<cst:select prompText="请选择" cls="regon" defaultValNo="0"  data="${parentarea}" displayField="text" valueField="value">
				</cst:select>
				<cst:select  prompText="请选择" cls="regonin" defaultValNo="1" show="select" data="${subarea}" displayField="text" valueField="value" >
				</cst:select>		
			</cst:searchline> 
		</div>
		<div class="issue_time">
			<span>发布时间:</span> 
			<cst:searchline  defaultcls="onclick" defaulvalue="<%=issue_time%>" defaultsplit="-" basehref="<%=basehref %>"  >				
				<cst:a needhref="true"   key="issue_time" value=""  text="不限" ></cst:a>
				<cst:a needhref="true"   key="issue_time" value="本月"  text="本月" ></cst:a>
				<cst:a needhref="true"   key="issue_time" value="本年"  text="本年" ></cst:a>
				<cst:a needhref="true"   key="issue_time" value="近三年"  text="近三年" ></cst:a>
				<cst:a needhref="true"   key="issue_time" value="近五年"  text="近五年" ></cst:a>
				<cst:a needhref="true"   key="issue_time" value="五年以上"  text="五年以上" ></cst:a>
				<em class="confim">
				<cst:select cls="yeah3" prompText ="请选择" defaultValNo="0" type="num" start="${start}" end="${end}" step="-1">
				</cst:select>
				<cst:select  cls="yeah4" prompText ="请选择" defaultValNo="1" type="num"  start="${start}" end="${end}" step="-1" >
				</cst:select>年</em>		<i id="confim">确认</i>
			</cst:searchline> 
		</div>
		
		<div class="time">
			<span>生成时间:</span> 
			<cst:searchline  defaultcls="onclick" defaulvalue="<%=time%>" defaultsplit="-" basehref="<%=basehref %>"  >				
				<cst:a needhref="true"   key="time" value=""  text="不限" ></cst:a>
				<cst:a needhref="true"   key="time" value="本月"  text="本月" ></cst:a>
				<cst:a needhref="true"   key="time" value="本年"  text="本年" ></cst:a>
				<cst:a needhref="true"   key="time" value="近三年"  text="近三年" ></cst:a>
				<cst:a needhref="true"   key="time" value="近五年"  text="近五年" ></cst:a>
				<cst:a needhref="true"   key="time" value="五年以上"  text="五年以上" ></cst:a>
				<em class="confim">
				<cst:select cls="yeah1" prompText ="请选择"   defaultValNo="0" type="num" start="${start}" end="${end}" step="-1">
				</cst:select>
				<cst:select  cls="yeah2" prompText ="请选择"  defaultValNo="1" type="num"  start="${start}" end="${end}" step="-1" >
				</cst:select>年</em>		<i id="confim">确认</i>
			</cst:searchline> 
		</div>
	</body>
</html>



el表达式可参考:http://blog.csdn.net/zdwzzu2006/article/details/4672383
el存取变量数据,如${name},表示取出某一范围中名称为name的变量,如果未指定范围,它会从Page、request、session、application范围查找。
jsp2tag标签:  http://www.ibm.com/developerworks/cn/java/j-lo-jsp2tag/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值