• JSP自定义标签(foreach标签与select标签的自定义方式)


    这篇的内容主要是为了使用自定义JSP标签更加的熟练

    一、自定义foreach标签

    第一步建立标签处理类
    ForeachTag.java

    package com.zking.mymvc.tag;
    
    import java.util.Iterator;
    import java.util.List;
    import java.util.Objects;
    
    import javax.servlet.jsp.tagext.BodyTagSupport;
    
    /**
     * 助手类,标签处理类
     * @author zjjt
     *
     */
    public class ForeachTag extends BodyTagSupport {
    	// 我要给他做成一个合法的标签处理类,那么就必须extends BodyTagSupport
    	
    	//存放数据源
    	private List<?> items;//因为foreach标签需要循环,所以需要有一个循环结果集
    	
    	//每次循环获取的对象放入pageContext中,并以var属性的值为key进行保存
    	//示例: 页面上标签var属性指定为item,则每次循环取出的对象(obj)将执行如下:
    	//pageContext.setAttribute("item", obj); 
    	//页面中可以使用EL表达式取出对象中的属性, 如: ${item.name}
    	private String var;
    
    	//需要get(可不写)和set方法
    
    	public void setItems(List<?> items) {
    		this.items = items;
    	}
    
    	public void setVar(String var) {
    		this.var = var;
    	}
    	
    	@Override
    	public int doStartTag() {
    		//接下来就是判断 
    		if(Objects.isNull(this.items)||this.items.size()<=0) {//它为空或者集合为空
    			return SKIP_BODY;//没有数据不用处理,直接跳过
    		}
    		Iterator<?> it = this.items.iterator();//迭代器
    		Object next = it.next();//获取了一个对象
    		this.pageContext.setAttribute(var, next);//获取页面对象,把对象放到pageContext作用域(另一个页面可获取)
    		this.pageContext.setAttribute("iterator", it);//把迭代器放到pageContext
    		
    		return EVAL_BODY_INCLUDE;//返回这个继续处理标签体,调用doAfterBody
    	}
    	
    	@Override
    	public int doAfterBody() {
    		//要做的是判断这个方法是否有值,有值的话继续返回调用
    		Iterator<?> it = (Iterator<?>)this.pageContext.getAttribute("iterator");//这就是获取到了哪个迭代器
    		if(it.hasNext()) {//如果发现里面还有值
    			this.pageContext.setAttribute(var, it.next());
    			return EVAL_BODY_AGAIN;
    		}
    		return SKIP_BODY;
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61

    第二步建立测试数据辅助类
    Book.java

    package com.zking.mymvc.model;
    
    public class Book {
    	
    	private int id;
    	
    	private String name;
    
    	public int getId() {
    		return id;
    	}
    
    	public void setId(int id) {
    		this.id = id;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	@Override
    	public String toString() {
    		return "Book [id=" + id + ", name=" + name + "]";
    	}
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    TestData.java

    package com.zking.mymvc.model;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class TestData {
    	
    	public static List<Book> getBooks(){
    		
    		List<Book> books = new ArrayList<>();
    		
    		Book b1 =  new Book();
    		b1.setId(1);
    		b1.setName("水浒传");
    		Book b2 =  new Book();
    		b2.setId(2);
    		b2.setName("红楼梦");
    		Book b3 =  new Book();
    		b3.setId(3);
    		b3.setName("西游记");
    		
    		books.add(b1);
    		books.add(b2);
    		books.add(b3);
    		
    		return books;
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    第三步在标签描述库写 foreach

    <tag>
    		<name>foreach</name>
    		<tag-class>com.zking.mymvc.tag.ForeachTag</tag-class>
    		<body-content>jsp</body-content>
    		<description>foreach标签</description>
    		<attribute>
    			<name>items</name>
    			<required>true</required>
    			<rtexprvalue>true</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>var</name>
    			<required>true</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    	</tag>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    测试我们统一到最后再来测试
    接下来就是自定义select标签

    二、自定义select标签

    也是一样的,第一步先建立标签处理器
    SelectTag.java

    package com.zking.mymvc.tag;
    
    import java.io.IOException;
    import java.lang.reflect.InvocationTargetException;
    import java.util.List;
    
    import javax.servlet.jsp.JspWriter;
    import javax.servlet.jsp.tagext.BodyTagSupport;
    
    import org.apache.commons.beanutils.BeanUtils;
    
    import com.mysql.jdbc.StringUtils;
    
    public class SelectTag extends BodyTagSupport {
    	
    	//下面定义的属性都是select标签所具有的属性
    	private String id;
    	
    	private String name;
    	
    	private List<?> items;
    	
    	private String cssClass;
    	
    	private String cssStyle;
    	
    	private String value;
    	
    	private String text;
    	
    	private String selectValue;
    
    	//这下面是set方法,get方法可不写
    	public void setId(String id) {
    		this.id = id;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public void setItems(List<?> items) {
    		this.items = items;
    	}
    
    	public void setCssClass(String cssClass) {
    		this.cssClass = cssClass;
    	}
    
    	public void setCssStyle(String cssStyle) {
    		this.cssStyle = cssStyle;
    	}
    	
    	
    	public void setValue(String value) {
    		this.value = value;
    	}
    
    	public void setText(String text) {
    		this.text = text;
    	}
    
    	public void setSelectValue(String selectValue) {
    		this.selectValue = selectValue;
    	}
    
    	//重写父类的doStartTag方法
    	@Override
    	public int doStartTag() {
    		
    		JspWriter out = this.pageContext.getOut();
    		
    		
    		try {
    			String html = getSelectHtml();
    			out.print(html);
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
    		return SKIP_BODY;
    	}
    	
    	private String getSelectHtml() throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
    		StringBuilder sb = new StringBuilder();//就是把index.jsp那个页面写死的select标签放到这里面去
    		
    		//这一块构造页面需要的select元素,构造完成之后就在doStartTag()里面写这个输出方法this.pageContext.getOut();
    		//这一块的主要功能就是将页面上写死的select元素,通过字符串拼接的方式生成,然后通过this.pageContext.getOut()丢到页面上面去
    		//还可以做的功能,就是标签有没有默认值,有默认值我们可以直接在这里面把默认值做成显示状态
    		
    		sb.append("");
    		
    		return sb.toString();
    	}
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123

    第三步在标签描述库写 select

    <tag>
    		<name>select</name>
    		<tag-class>com.zking.mymvc.tag.SelectTag</tag-class>
    		<body-content>empty</body-content>
    		<attribute>
    			<name>id</name>
    			<required>true</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>name</name>
    			<required>true</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>items</name>
    			<required>true</required>
    			<rtexprvalue>true</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>cssClass</name>
    			<required>false</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>cssStyle</name>
    			<required>false</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>value</name>
    			<required>true</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>text</name>
    			<required>true</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    		<attribute>
    			<name>selectValue</name>
    			<required>false</required>
    			<rtexprvalue>false</rtexprvalue>
    		</attribute>
    	</tag>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    再就是测试标签是否可用

    <%@page import="com.zking.mymvc.model.*,java.util.List" %>
    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>
        <!-- 第一步引入标签库 -->
        <%@taglib prefix="z" uri="/zking" %><!-- 注意这里的uri要与标签库那个uri一样 -->
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
    <!-- foreach -->
    	<%
    	//获取测试数据
    		List<Book> books = TestData.getBooks(); 
    		//放入request对象中
    		request.setAttribute("books", books);
    		%>
    		
    		<z:foreach items="${books}" var="book">
    			${book.id} -- ${book.name} <br>
    		</z:foreach>
    	
    	<!-- 由下面的select标签的样子,我们可以知道我们在助手类需要定义哪些属性 -->
    <!-- 	<select id="test" name="test" class="" style="width:100px">
    		<option value="1">已付款</option>
    		<option value="1" selected >已发货</option>
    		<option value="1">已签收</option>
    	</select> -->
    	
    	
    	<select id="test" name="test" class="" style="width:100px;">
    		<option value=0>已付款</option>
    		<option value= selected>已发货</option>
    		<option value=2>已签收</option>
    	</select>
    	
    	<z:select id="test" 
    	   name="test" items="${books}" value="id"
    	   text="name" selectValue="3"/>
    	
    	
    </body>
    </html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
  • 相关阅读:
    使用 React 和 MUI 创建多选 Checkbox 树组件
    【SpringBoot】一文吃透SpringBoot多环境开发
    面试题整理:如何判断一个对象是否属于某个类?
    前端:css中的多列的实现与介绍
    MySQL 的数据目录
    Android 蓝牙BLE串口通信之高低位转换、16进制字符串转换float浮点型
    hive add columns 后查询不到新字段数据的问题
    论文翻译:2021_语音增强模型压缩_Towards model compression for deep learning based speech enhancement
    手写jQuery的封装
    存储资源盘活助力网络强国
  • 原文地址:https://blog.csdn.net/Champion_me/article/details/125884623