JavaWeb_带标签体的自定义标签

  • 带标签体的自定义标签


带标签体的自定义标签

  • 1.带标签体的自定义标签:
     1)若一个标签有标签体:
     < xs:testJspFragment>abcdefg< /xs:testJspFragment>
     在自定义标签的标签处理器中使用 JspFragment 对象封装标签体信息。
     2)若配置了标签含有标签体,则 JSP 引擎会调用 setJspBody() 方法把 JspFragment 传递给标签处理器类在 SimpleTagSupport 中还定义了一个 getJspBody() 方法,用于返回 JspFragment 对象。
     3)JspFragment 的 invoke(Writer) 方法:把标签体内容从 Writer 中输出,若为 null,则等同于 invoke(getJspContext().getOut()),即直接把标签体内容输出到页面上。
     有时,可以借助于 StringWriter,可以在标签处理器类中先得到标签体的内容:
//1. 利用 StringWriter 得到标签体的内容.
StringWriter sw = new StringWriter();
bodyContent.invoke(sw);

//2. 把标签体的内容都变为大写
String content = sw.toString().toUpperCase();

.
   4)在 tld 文件中,使用 body-content 节点来描述标签体的类型:
   < body-content>: 指定标签体的类型, 大部分情况下, 取值为 scriptless。可能取值有 3 种:
    ①empty:没有标签体
    ②scriptless:标签体可以包含 el 表达式和 JSP 动作元素,但不能包含 JSP 的脚本元素。
    ③tagdependent:表示标签体交由标签本身去解析处理。若指定 tagdependent,在标签体中的所有代码都会原封不动的交给标签处理器,而不是将执行结果传递给标签处理器。
   < body-content>tagdependent< /body-content>
   5)定义一个自定义标签: < xs:printUpper time=“10”>abcdefg< /xs> 把标签体内容转换为大写,并输出 time 次到浏览器上。
   6)实现 forEach 标签:

> 两个属性:items(集合类型,Collection),var(String 类型)
	> doTag:
		* 遍历 items 对应的集合
		* 把正在遍历的对象放入到 pageContext 中,键:var,值:正在遍历的对象。
		* 把标签体的内容直接输出到页面上。
  • 2.把标签体转为大写和实现forEach标签代码:
    mytag.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>MyTag 1.2 core library</description>
  <display-name>MyTag core</display-name>
  <tlib-version>1.2</tlib-version>
  <short-name>xs</short-name>
  <uri>http://xs.com/jsp/MyTag/core</uri>
  
   <tag>
  	<name>printUpper</name>
  	<tag-class>com.xs.javaweb.PrintUppertag</tag-class>
  	<body-content>scriptless</body-content>
  	
  	<attribute>
  		<name>time</name>
  		<required>true</required>
  		<rtexprvalue>true</rtexprvalue>
  	</attribute>
  	
  </tag>
  
  <tag>
  	<name>forEach</name>
  	<tag-class>com.xs.javaweb.ForEachTag</tag-class>
  	<body-content>scriptless</body-content>
  	
  	<attribute>
  		<name>items</name>
  		<required>true</required>
  		<rtexprvalue>true</rtexprvalue>
  	</attribute>
  	
  	<attribute>
  		<name>var</name>
  		<required>true</required>
  		<rtexprvalue>true</rtexprvalue>
  	</attribute>
  	
  </tag>
</taglib>

test.jsp

<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="com.xs.javaweb.Customer"%>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<%@ taglib prefix="xs" uri="http://xs.com/jsp/MyTag/core" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	
	<xs:printUpper time="10">xs</xs:printUpper>
	
	<%
		List<Customer> customers = new ArrayList<Customer>();
		
		customers.add(new Customer(1,"AAA"));
		customers.add(new Customer(2,"BBB"));
		customers.add(new Customer(3,"CCC"));
		customers.add(new Customer(4,"DDD"));
		customers.add(new Customer(5,"EEE"));
		
		request.setAttribute("customers", customers);
	%>
	
	<c:forEach items="${requestScope.customers }" var="customer">
		${customer.id } -- ${customer.name }<br>
	</c:forEach>
	
	<br><br>
	
	<xs:forEach items="${requestScope.customers }" var="customer">
		${customer.id } --> ${customer.name }<br>
	</xs:forEach>
	
	<br><br>
	
	<xs:forEach items="${requestScope.customers }" var="customer">
		${pageScope.customer.id } --> ${pageScope.customer.name }<br>
	</xs:forEach>

</body>
</html>

Customer.java

/**  
 * All rights Reserved,Designed By XS
 * @Title: Customer.java
 * @Package com.xs.javaweb
 * @Description: TODO
 * @author: XS
 * @date: 2019年3月14日 上午11:19:28
 * @version V1.0
 */
package com.xs.javaweb;

/**   
 * @ClassName: Customer
 * @Description: TODO
 * @author: XS
 * @date: 2019年3月14日 上午11:19:28
 * @version V1.0
 */
public class Customer {
	
	private int id;
	private String name;
	
	
	
	/**  
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**  
	 * @return the name
	 */
	public String getName() {
		return name;
	}

	/**  
	 * @param id: the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}
	
	/**  
	 * @param name: the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}

	/**   
	 * @Title: Customer
	 * @Description: TODO
	 * @param id
	 * @param name
	 */
	public Customer(int id, String name) {
		super();
		this.id = id;
		this.name = name;
	}
}

PrintUpperTag.java

/**  
 * All rights Reserved,Designed By XS
 * @Title: PrintUppertag.java
 * @Package com.xs.javaweb
 * @Description: TODO
 * @author: XS
 * @date: 2019年3月14日 上午11:11:35
 * @version V1.0
 */
package com.xs.javaweb;

import java.io.IOException;
import java.io.StringWriter;

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

/**   
 * @ClassName: PrintUppertag
 * @Description: TODO
 * @author: XS
 * @date: 2019年3月14日 上午11:11:35
 * @version V1.0
 */
public class PrintUppertag extends SimpleTagSupport {

	private String time;
	
	/**  
	 * @param time: the time to set
	 */
	public void setTime(String time) {
		this.time = time;
	}
	
	/**   
	 * <p>Title: doTag</p>
	 * <p>Description: </p>
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 * @throws JspException
	 * @throws IOException
	 */
	@Override
	public void doTag() throws JspException, IOException {
		JspFragment bodyContent = getJspBody();
		StringWriter sw = new StringWriter();
		bodyContent.invoke(sw);
		String content = sw.toString();
		
		content = content.toUpperCase();
		
		int count = 1;
		try {
			count = Integer.parseInt(time);
		} catch (Exception e) {	}
		for(int i = 0;i < count;i++) {
			getJspContext().getOut().print((i + 1) + ": " + content + "<br>");
		}
	}
	
}

ForEachTag.java

/**  
 * All rights Reserved,Designed By XS
 * @Title: ForEachTag.java
 * @Package com.xs.javaweb
 * @Description: TODO
 * @author: XS
 * @date: 2019年3月14日 下午12:57:18
 * @version V1.0
 */
package com.xs.javaweb;

import java.io.IOException;
import java.util.Collection;

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

/**   
 * @ClassName: ForEachTag
 * @Description: TODO
 * @author: XS
 * @date: 2019年3月14日 下午12:57:18
 * @version V1.0
 */
public class ForEachTag extends SimpleTagSupport {
	
	private Collection<?> items;
	
	/**  
	 * @param items: the items to set
	 */
	public void setItems(Collection<?> items) {
		this.items = items;
	}
	
	private String var;
	
	/**  
	 * @param var: the var to set
	 */
	public void setVar(String var) {
		this.var = var;
	}
	
	/**   
	 * <p>Title: doTag</p>
	 * <p>Description: </p>
	 * @see javax.servlet.jsp.tagext.SimpleTagSupport#doTag()
	 * @throws JspException
	 * @throws IOException
	 */
	@Override
	public void doTag() throws JspException, IOException {
		// 遍历items对应的集合
		if(items != null) {
			for (Object obj: items) {
				//把正在遍历的对象放入到pageContext中,键:var,值:正在遍历的对象。
				getJspContext().setAttribute(var, obj);
				//把标签体的内容直接输出到页面上。
				getJspBody().invoke(null);
				
			}
		}
	}
}