jsp自定义标签02
前言
嘿,由于我的上一篇博客关于jsp自定义标签已经做好一系列的详细解释了,所以这次博客就来和大家分享一下forEach遍历标签以及seleect下拉框标签的实现过程!
jsp自定义标签(ForEach标签、Select标签)实战演示
实战演示一之ForEach标签:
1、 首先新建项目后,在src目录下创建一个放置标签的包,就像这样,因为可能会需要用到c标签做对比,所以可以先导入c标签的jar
2、实例化一个ForEach的标签助手类,具体代码如下
package com.wangqiuping.Tag;
import java.util.Iterator;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
/**
*
* @author 小汪同学 2020年5月28日 上午9:45:11
*
*/
public class ForEachTag extends BodyTagSupport{
private List<Object> items;//集合的项
private String var;//保存集合元素的key
private String varStatus;//保存index,count属性的对象的key
/**
* 内部类
* @author 小汪同学 2020年5月28日 上午9:51:51
*
*/
public static class Status{
private int index=0;//定义一个默认的下标值
public int getIndex() {//s.index会调用该方法
return index;
}
public void setIndex(int index) {
this.index = index;
}
public int getCount() {//s.count会调用该方法
return this.index+1;
}
void increment() {//自动递增的方法
this.index++;
}
}
public String getVarStatus() {
return varStatus;
}
public void setVarStatus(String varStatus) {
this.varStatus = varStatus;
}
public ForEachTag() {
super();
}
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getVar() {
return var;
}
public void setVar(String var) {
this.var = var;
}
@Override
public int doStartTag() throws JspException {
if(null!=varStatus && !"".equals(varStatus)) {
pageContext.setAttribute(varStatus,new Status());
}
//如果items的项不为空 并且items的大小不能为0
if(null!=items && 0!=items.size()) {
//使用迭代器遍历数据
Iterator<Object> it = items.iterator();
//寻找是否有下一个值
Object next = it.next();
//然后把var和it给存储起来
pageContext.setAttribute(var, next);//var是变量 不需要双引号
pageContext.setAttribute("it", it);//it是名称
return EVAL_BODY_INCLUDE;//计算标签主体内容
}
return super.doStartTag();
}
@Override
public int doAfterBody() throws JspException {
//从迭代器中取值
Iterator<Object> it =(Iterator<Object>)pageContext.getAttribute("it");
while(it.hasNext()) {//如果有下一个值
if(null!=varStatus && !"".equals(varStatus)) {
Status status =(Status)pageContext.getAttribute(varStatus);
status.increment();//调用自动增长的方法
pageContext.setAttribute(varStatus,status);
}
Object next = it.next();
pageContext.setAttribute(var,next);
return EVAL_BODY_AGAIN;
}
return super.doAfterBody();
}
}
注意: 如果只存储了var 没有存储 it 的话 会报空指针异常!
3、在WEB_INF的子目录下新建一个tld的配置文件,就像这样
然后找到fFile文件,把文件的后缀名改为tld就好!
我这里以我自己名字命名的tld文件为例,代码如下
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<description>JSTL 1.1 core library</description>
<display-name>JSTL core</display-name>
<tlib-version>1.1</tlib-version>
<short-name>w</short-name>
<uri>/wangqiuping</uri>
<!-- forEach标签 -->
<tag>
<name>foreach</name>
<tag-class>com.wangqiuping.Tag.ForEachTag</tag-class>
<body-content>JSP</body-content>
<attribute>
<name>items</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
<attribute>
<name>var</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>varStatus</name>
<required>false</required>
<rtexprvalue>true</rtexprvalue>
</attribute>
</tag>
<!-- select标签 -->
<tag>
<name>select</name>
<tag-class>com.wangqiuping.Tag.SelectTag</tag-class>
<body-content>empty</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>headText</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>headValue</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
<attribute>
<name>selected</name>
<required>false</required>
<rtexprvalue>false</rtexprvalue>
</attribute>
</tag>
</taglib>
4、新建一个任意名字的jsp页面,我这里以tag.jsp页面为例:
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="w" uri="/wangqiuping" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>自定义标签</h1>
<%
List<String> ls=new ArrayList<String>();
ls.add("lyf");
ls.add("zys");
ls.add("tyx");
String name="lyf";
pageContext.setAttribute("name", name);
request.setAttribute("names", ls);
%>
<h2>自定义标签的forEach标签</h2>
<ul>
<w:foreach items="${names}" var="n" varStatus="s" >
<li>${n},${s.index},${s.count}</li>
</w:foreach>
</ul>
</body>
</html>
实战演示二之select标签:
1、首先实例化一个select的标签助手类, 就像这样:
package com.wangqiuping.Tag;
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;
/**
*
* @author 小汪同学 2020年5月28日 上午10:39:35
*
*/
public class SelectTag extends BodyTagSupport {
private static final long serialVersionUID = 1L;
private List<Object> items;//定义一个集合
private String name;//下拉框的name
private String valueKey;//保存option中value的key
private String textKey;//保存option中text文本的key
private String cssStyle;//css样式
private String headValue;//请选择的文本值
private String headText;//请选择的默认ID
private String selected;//默认选中
public String getSelected() {
return selected;
}
public void setSelected(String selected) {
this.selected = selected;
}
public String getHeadValue() {
return headValue;
}
public void setHeadValue(String headValue) {
this.headValue = headValue;
}
public String getHeadText() {
return headText;
}
public void setHeadText(String headText) {
this.headText = headText;
}
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;
}
public SelectTag() {
super();
}
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
String html=toHtml();
System.out.println(html);
out.println(html);
} catch (Exception e) {
throw new RuntimeException(e);
}
return super.doStartTag();
}
//拼接的方法
private String toHtml() throws Exception{
StringBuffer sb=new StringBuffer();
//第一步:先拼<select name="" style="">
sb.append("<select name='"+name+"'");
sb.append(" style='"+cssStyle+"'");
sb.append(">");
//第二步:<option value=""></option>
//记得先判断
if(null!=items && 0!=items.size()) {
if(null!=headText && !"".equals(headText.trim())) {
sb.append("<option value= '"+headText+"'> "+headValue+" </option>'");
}
Object value=null;
Object text=null;
for (Object object : items) {
//记得导入反射取值的jar 才可使用反射的jar
//这里需要抛异常!
value=PropertyUtils.getProperty(object,valueKey);
text=PropertyUtils.getProperty(object,textKey);
if(value.toString().equals(selected.trim())) {
sb.append("<option selected value= '"+value+"'> "+text+" </option>'");
}
else {
sb.append("<option value= '"+value+"'> "+text+" </option>'");
}
}
}
sb.append("</select>");
return sb.toString();
}
}
2、因为在拼接的过程中会需要使用到反射取值的方法,所以需要导入以下这两个jar:
注意:
1、如果小伙伴的eclipse中加入了热部署的话,加入了这两个jar之后,要记得重新运行该项目~
2、写完了反射取值的代码后一定要记得抛异常!
3、在jsp页面调用标签:
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="w" uri="/wangqiuping" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>自定义标签中的select标签</h2>
<w:select items="${deptList}" valueKey="deptId" textKey="deptName"
cssStyle="width:150px;" headText="-1" headValue="---请选择---" selected="3"/>
</body>
</html>
最终效果
ForEach标签:
select标签:
默认选中的select标签的效果:
注意要点
1、在实例化好标签助手类后,一定要记得继承BodyTagSupport类!
2、在写tld配置文件的时候,弄清楚该标签中的属性是否必填、是否表达式!
3、在写配置文件的时候,头部记得引用taglib指令 中 prefix、uri不要写错!
4、在写select标签拼接代码的时候,使用单引号去转义时候,记得不要漏掉!
总结
JSP自定义标签的核心内容就以两次博客分享了,在写代码前弄清楚思路再动手,以及你想要去自己定义某一个标签时,可以去看看自定义标签的生命周期图,弄明白具体流程,以及一定要细心,这样可以避免一些不该出现的错误,欢迎评论留言交流!