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自定义标签的核心内容就以两次博客分享了,在写代码前弄清楚思路再动手,以及你想要去自己定义某一个标签时,可以去看看自定义标签的生命周期图,弄明白具体流程,以及一定要细心,这样可以避免一些不该出现的错误,欢迎评论留言交流!

猜你喜欢

转载自blog.csdn.net/qq_45464930/article/details/106406468