这篇的内容主要是为了使用自定义JSP标签更加的熟练
第一步建立标签处理类
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;
}
}
第二步建立测试数据辅助类
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 + "]";
}
}
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;
}
}
第三步在标签描述库写 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>
测试我们统一到最后再来测试
接下来就是自定义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();
}
}
第三步在标签描述库写 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>
再就是测试标签是否可用
<%@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>