七、jsp基础(六)- jsp自定义标签

回顾

1 课程回顾
Jsp加强
	1)Jsp的9大内置对象
			request       HttpServletRequet
			response     HttpServletResponse
			config         ServletConfig
			application     ServletContext
			exception      Throwable
			page          Object
			pageContext    PageContext
			out              JspWriter
			session        HttpSession

	2)Jsp的4个域对象
			request    
			session
			application
			pageContext
	
			作用范围:
				pageContext : 处于当前jsp页面中有效的!!
				request:      处于同一个请求中有效的!!
				session:      处于同一个会话中有效的!
				application:   处于同一个web应用中有效的!
		
	3)EL表达式
			替代jsp表达式,用于向浏览器输出域对象中的变量值和表达式计算的结果。

			语法:
					${变量}
				  3.1 输出普通字符串: ${name}
				  3.2 输出对象属性:  ${student.name}  注意: .name 相当于  .getName()方法
				  3.3 输出List集合:   ${list[0].name }   注意: [0]  相当于 get(下标)方法
				  3.4 输出map集合:  ${map[key].name}  注意: [key]相当于get(key)方法

	4)jsp标签
			替代jsp脚本,用于在jsp页面中执行java代码

			4.1 内置标签:
					<jsp:foward/>   request.getRequesetDipsacher("/路径").foward(request,response);
		  			<jsp:param/>   参数标签    ?name=eric
					<jsp:include/>   包含其他页面 ,动态包含
							静态包含: 先合并再翻译。不能传递参数
							动态包含: 先翻译再合并。可以传递参数

			4.2 jstl标签库 (java标准标签库)
					使用步骤:
							1)确保jstl支持的jar包存在于项目中
							2)在jsp页面中导入标签库
 								<%@taglib uri="标签库声明文件tld文件的标记" prefix="前缀"%>
							3)使用标签库中的标签
				
					核心标签库:
							<c:set />     保存数据到域对象中
							<c:out/>     从域中取  出数据
							<c:if/>       单条件判断
							<c:choose/> + <c:when/> + <c:otherwise/>  多条件判断
							<c:forEach />  遍历数据 
							<c:forTokens/>  遍历特殊字符串
							<c:redirect/>   重定向

一、 自定义标签开发步骤

		1)编写一个普通的java类,继承SimpleTagSupport类,实现doTag()方法
				
				SimpleTagSupport实现了SimpleTag接口,而SimpleTag接口中有一
				个方法setJspContext(JspContext  jspContext),该方法会将
				PageContext传入该类中。
				
				所以,我们可以在该类中通过 this.getJspContext()获取PageContext对象。(PageContext是JspContext的子类, 多态)
				
		
		2)在web项目的WEB-INF目录下建立itcast.tld文件,这个tld叫标签库的声明文件。(参考核心标签库的tld文件)
		
		3) 在jsp页面的头部导入自定义标签库
				    <%@taglib uri="http://gz.it.cn" prefix="itcast"%>

		4) 在jsp中使用自定义标签
					<itcast:showIp></itcast:showIp>
					

1.1 第一个自定义标签开发步骤

需求: 向浏览器输出当前客户的IP地址 (只能使用jsp标签)

1)编写一个普通的java类,继承SimpleTagSupport类,叫标签处理器类
/**
 * 标签处理器类
 * @author APPle
 * 1)继承SimpleTagSupport
 *
 */
public class ShowIpTag extends SimpleTagSupport{
	private JspContext context;
	
	/**
	 * 传入pageContext
	 */
	@Override
	public void setJspContext(JspContext pc) {
		this.context = pc;
	}

	/**
	 * 2)覆盖doTag方法
	 */
	@Override
	public void doTag() throws JspException, IOException {
		//向浏览器输出客户的ip地址
		PageContext pageContext = (PageContext)context;
		
		HttpServletRequest request = (HttpServletRequest)pageContext.getRequest();
		
		String ip = request.getRemoteHost();
		
		JspWriter out = pageContext.getOut();
		
		out.write("使用自定义标签输出客户的IP地址:"+ip);
		
	}
}

2)在web项目的WEB-INF目录下建立itcast.tld文件,这个tld叫标签库的声明文件。(参考核心标签库的tld文件)
<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">
  <!-- 标签库的版本 -->
  <tlib-version>1.1</tlib-version>
  <!-- 标签库前缀 -->
  <short-name>itcast</short-name>
  <!-- tld文件的唯一标记 -->
  <uri>http://gz.itcast.cn</uri>

  <!-- 一个标签的声明 -->
  <tag>
    <!-- 标签名称 -->
    <name>showIp</name>
    <!-- 标签处理器类的全名 -->
    <tag-class>gz.itcast.a_tag.ShowIpTag</tag-class>
    <!-- 输出标签体内容格式 -->
    <body-content>scriptless</body-content>
  </tag>

</taglib>
3) 在jsp页面的头部导入自定义标签库
			    <%@taglib uri="http://gz.itcast.cn" prefix="itcast"%>
4) 在jsp中使用自定义标签
					<itcast:showIp></itcast:showIp>

二、自定义标签的执行原理

2.1 自定义标签执行过程

问题: http://localhost:8080/day14/01.hellotag.jsp 如何访问到自定义标签?

前提: tomcat服务器启动时,加载到每个web应用,加载每个web应用的WEB-INF目录下的所有文件!!!例如。web.xml, tld文件!!!
			
			1)访问01.hellotag.jsp资源
			2)tomcat服务器把jsp文件翻译成java源文件->编译class->构造类对象->调用_jspService()方法
			3)jsp标签的执行原理主要在翻译这个步骤。
						
					   服务器翻译jsp文件时,会找到对应的标签处理器类
							---> 服务器翻译jsp文件时,会自动识别taglib指令
							---> 通过taglib指令获取到uri路径
							---> 通过uri路径获取到对应的tld文件
							---> 通过标签名称在tld文件中查找到对应的tag标签
							---> 通过tag标签获取标签对应的处理器类。

					   服务器会在翻译java源文件会自动生成标签相关的代码
					   			--初始化标签处理器类
					   			--调用doTag方法
					   			
					   用户访问时,执行翻译后的java代码即可。


2.2 自定义标签的源码分析

2.2.1 示例

1)以下代码是自定义标签的代码

ShowIpTag .java



public class ShowIpTag extends SimpleTagSupport {
	
	
	@Override
	public void doTag() throws JspException, IOException {
		
		PageContext contxt=(PageContext) this.getJspContext();
		HttpServletRequest req=(HttpServletRequest) contxt.getRequest();
		ServletResponse resp = contxt.getResponse();
		
		String ip = req.getRemoteHost();
	
		
		resp.getWriter().write("当前ip:"+ip);
		
	}
}

在WEB-INF下新建mytag.tld文件

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>m</short-name>
  <uri>http://java.sun.com/jsp/jstl/my</uri>

  <tag>
    <name>showip</name>
    <tag-class>org.jsoft.hello.ShowIpTag</tag-class>
    <body-content>scriptless</body-content>
   
  </tag>


</taglib>

2)以下代码是使用自定义标签的代码

inedx.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
    
<%@taglib uri="http://java.sun.com/jsp/jstl/my"  prefix="m" %>    
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Demo</title>
</head>
<body>

<m:showip></m:showip>
re
</body>
</html>

3)访问
在这里插入图片描述

2.2.2 查看jsp标签的被翻译后的源代码
	由上面的实例,我们查看tomcat服务器中生成的缓存文件,即jsp翻译后源代码。如下。
	
	1.由下面的代码,我们可以得知,标签对应的地方,会被自动翻译成
		 	if (_jspx_meth_m_005fshowip_005f0(_jspx_page_context))
		        return;
	
	2.该方法会自动生成,该方法主要是实例化标签处理器对象,然后调用doTag()方法。

public final class index3_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {


  public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
        throws java.io.IOException, javax.servlet.ServletException {

     final javax.servlet.jsp.PageContext pageContext;
     javax.servlet.http.HttpSession session = null;
    
    ...

      response.setContentType("text/html; charset=utf-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("    \r\n");
      out.write("    \r\n");
      out.write("<!DOCTYPE html>\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<meta charset=\"utf-8\">\r\n");
      out.write("<title>Demo</title>\r\n");
      out.write("</head>\r\n");
      out.write("<body>\r\n");
      out.write("\r\n");
      
      if (_jspx_meth_m_005fshowip_005f0(_jspx_page_context))
        return;
        
      out.write("\r\n");
      out.write("re\r\n");
      out.write("</body>\r\n");
      out.write("</html>");
  		
  	  ...
  }
	
  /**
	* 标签翻译后自动生成的标签处理器初始化的代码。
	*
	*/	
  private boolean _jspx_meth_m_005fshowip_005f0(javax.servlet.jsp.PageContext _jspx_page_context)
          throws java.lang.Throwable {
    javax.servlet.jsp.PageContext pageContext = _jspx_page_context;
    javax.servlet.jsp.JspWriter out = _jspx_page_context.getOut();
    //  m:showip
    org.jsoft.hello.ShowIpTag _jspx_th_m_005fshowip_005f0 = new org.jsoft.hello.ShowIpTag();
    _jsp_getInstanceManager().newInstance(_jspx_th_m_005fshowip_005f0);
    try {
      _jspx_th_m_005fshowip_005f0.setJspContext(_jspx_page_context);
      _jspx_th_m_005fshowip_005f0.doTag();
    } finally {
      _jsp_getInstanceManager().destroyInstance(_jspx_th_m_005fshowip_005f0);
    }
    return false;
  }
}

2.3 自定义标签的原理

	jsp会被翻译成java源文件。对于jsp标签,服务器会自动生成一个方法,用于处理自定义标签。
	该方法主要用于初始化自定义标签处理器。
			
			->  setJspContext(一定执行,传入JspContext)
			->	setParent (有父级标签才会执行)
			->  setXXX 	  (有属性值才会执行)
			->  setJspBody 	(有标签体内容才会执行)
			->  doTag


三、自定义标签处理器的生命周期(自定义标签处理器的初始化)

	jsp标签会被翻译成源代码中的一个方法,该方法主要作用就是实现标签处理器的初始化操作。
	标签处理器的初始化操作按照以下方法的次序依次执行。
	
		setJspContext(一定执行)->	setParent ->setXXX ->setJspBody ->doTag

	
		该方法中的代码表示了自定义标签处理器的生命周期。方法中的代码执行顺序:
		
					setJspContext(JspContext pc)    一定执行
					
					setParent(JspTag parent)        有父级标签就会执行,否则不会
					
					setXXX()    					有属性值就会执行,否则不会
					
					setJspBody(JspFragment jspBody) 有标签体内容就会执行,否则不会。
					
					doTag()    					    一定执行
				

	
	SimpleTag接口: 
	
				setJspContext(JspContext pc)  --设置pageContext对象,传入pageContext(一定调用)
												通过getJspCotext()方法得到pageContext对象
				
											
				setParent(JspTag parent)  --设置父标签对象,传入父标签对象,
											如果没有父标签,则不调用此方法。
											通过getParent()方法得到父标签对象。
				
				setXXX()             --设置属性值。
				
				setJspBody(JspFragment jspBody) --设置标签体内容。标签体内容
												  标签体内容都会被封装到JspFragment对象中,
												  
												  通过该方法传入JspFragment对象。
												  通过getJspBody()方法获取标签体内容
												  														得到标签体内容。如果没有标签体内容,则不会调														用此方法
				doTag()                     --执行标签时调用的方法。(一定调用)




【PageContext是JspContext的子类,可以通过getJspCotext()获取pageContext内置对象】	

【标签体内容会被自动封装到JspFragment对象中,我们可以通过getJspBody()获取JspFragment对象,从而获取标签体内容】

四、标签处理器中相关API

		标签体内容相关
					JspFragment jspBody = this.getJspBody();	
					JspWriter out = this.getJspContext().getOut();
					jspBody.invoke(out);
		
		设置带属性的标签
					1.在标签处理器中添加一个成语变量和setter方法
					2.在tld文件中声明属性值
		
		设置子父类标签
					和设置单个标签的方式一样,唯一不同的时,父类标签处理器用于子类标签处理器之间传参。
								

4.1 tld文件

tld文件的模板

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">
	  <!-- 标签库的版本 -->
	  <tlib-version>1.1</tlib-version>
	  <!-- 标签库前缀 -->
	  <short-name>itcast</short-name>
	  <!-- tld文件的唯一标记 -->
	  <uri>http://gz.itcast.cn</uri>
	

	  <!--showIp 标签 -->
	  <tag>
	    <!-- 标签名称 -->
	    <name>showIp</name>
	    <!-- 标签处理器类的全名 -->
	    <tag-class>gz.itcast.a_tag.ShowIpTag</tag-class>
	    <!-- 输出标签体内容格式 -->
	    <body-content>scriptless</body-content>
	  </tag>
	  
	  <!--demoTag标签 -->
	  <tag>
	    <name>demoTag</name>
	    <tag-class>gz.itcast.a_tag.DemoTag</tag-class>
	    <body-content>scriptless</body-content>
	    <!-- 属性声明 -->
	    <attribute>
	    	<!-- 属性名称 -->
	    	<name>num</name>
	    	<!-- 是否必填 -->
	    	<required>true</required>
	    	<!-- 是否支持EL表达式 -->
	    	<rtexprvalue>false</rtexprvalue>
	    </attribute>
	  </tag>

</taglib >

详解:


	  <tag>
		    <name>demoTag</name>
		    <tag-class>gz.itcast.a_tag.DemoTag</tag-class>
		    <body-content>scriptless</body-content>
		    <!-- 属性声明 -->
		    <attribute>
		    	<!-- 属性名称 -->
		    	<name>num</name>
		    	<!-- 是否必填 -->
		    	<required>true</required>
		    	<!-- 是否支持EL表达式 -->
		    	<rtexprvalue>true</rtexprvalue>
		    </attribute>
	  </tag>



	  输出标签体内容格式
				JSP:   在传统标签中使用的。可以写和执行jsp的java代码。
				scriptless:  标签体不可以写jsp的java代码
				empty:    必须是空标签。
				tagdependent : 标签体内容可以写jsp的java代码,但不会执行。
				

4.1 标签体内容相关

	标签体内容会被自动封装到JspFragment对象中,该对象会在标签处理器对象初始化时设置到
	标签处理器对象中。

	输出标签体内容
			方式一:
					JspFragment jspBody = this.getJspBody();	
					JspWriter out = this.getJspContext().getOut();
					jspBody.invoke(out);
			方式二:
					JspFragment jspBody = this.getJspBody();	
					JspWriter out = this.getJspContext().getOut();
					jspBody.invoke(null); //不设置输出流,默认输出流默认就为out

	不输出标签体内容,即隐藏标签体内容
					在标签体处理类的doTag()中不写以上代码就可以
	
	重复输出标签体内容
			    JspFragment jspBody = this.getJspBody();	
				JspWriter out = this.getJspContext().getOut();
				jspBody.invoke(null);
				jspBody.invoke(null);
				jspBody.invoke(null);  //标签体内容会被输出三次

	输出标签体外内容
				   什么都不处理。默认情况下,标签体外内容自动输出。
	 
	不输出标签体外内容
				   在doTag()中,抛出 SkipPageException()异常。
				   				throw new SkipPageException()。
				  该异常只会影响标签体外的内容输出,不会影响标签体内的内容输出。
				  
	
    改变标签体内容输出
    			
    			//创建StringWriter临时容器
    			StringWriter  sw=new StingWriter()
    			//拷贝标签体内容到临时容器
    			jspBody.invoke(sw);
    			String str=sw.toString()+ " hlp ";
				
				this.getJspContext().getOut().write(str);

4.2 设置带属性的标签

	自定义标签的属性值会在标签处理器对象初始化时设置到标签处理器对象中。

设置带属性的标签步骤:

1)在标签处理器中添加一个成语变量和setter方法
		public class IfTag  extends SimpleTagSupport{
				
				//1.声明属性的成员变量
				private boolean test;
				
				//2.关键点: 必须提供公开的setter方法,用于给属性赋值
				public void setTest(boolean test) {
					this.test = test;
				}
			}
	
2)在tld文件中声明属性值
	 <tag>
			    <name>demoTag</name>
			    <tag-class>gz.itcast.a_tag.DemoTag</tag-class>
			    <body-content>scriptless</body-content>
			    <!-- 属性声明 -->
			    <attribute>
				    	<!-- 属性名称 -->
				    	<name>test</name>
				    	<!-- 是否必填 -->
				    	<required>true</required>
				    	<!-- 是否支持EL表达式 -->
				    	<rtexprvalue>false</rtexprvalue>
			    </attribute>
		  </tag>
3)使用标签即可

案例:自定义if标签

1)以下代码,自定义标签
IfTag.java ,自定义标签处理器类

public class IfTag  extends SimpleTagSupport{
	
	private boolean test;
	
	public void setTest(boolean test) {
		this.test = test;
	}
	
	
	@Override
	public void doTag() throws JspException, IOException {
		if(test) {
			this.getJspBody().invoke(null);
		}
	}
}

设置tld文件

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>

	
   <tag>
    <name>if</name>
    <tag-class>org.jsoft.hello.IfTag</tag-class>
    <body-content>scriptless</body-content>
    <!-- 属性声明 -->
    <attribute>
    	<!-- 属性名称 -->
    	<name>test</name>
    	<!-- 是否必填 -->
    	<required>true</required>
    	<!-- 是否支持EL表达式 -->
    	<rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>	

</taglib>

2)以下代码,使用自定义标签
index.jsp

<%@page import="java.util.Random"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>
<%@ page language="java" 
    pageEncoding="utf-8"
    isErrorPage="true"
    %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
	
	<!-- if标签 -->
	<hlp:if test="${10>5 }">
		条件成立输出
	</hlp:if>
	
	<!-- 登录标签 -->
	<form action="">
		<hlp:login></hlp:login>                                                                                                      "
	</form>
</body>
</html>

3)访问

在这里插入图片描述

4.3 设置子父类标签

	jsp的每一个标签都会被翻译成一个方法,每一个方法都是用于初始化标签处理器对象。

设置子父类标签

   设置子父类标签时,把子类标签和父类标签都看作一个独立的标签去设置。唯一不同的时,子类标签和父类标签对应的标签处理器。
   
   设置父类标签对应的标签处理器,其主要作用是使用父类标签处理器,在子类标签处理器之间传参。

案例:自定义多条件输出标签
1)以下代码用于自定义标签

ChooseTag.java :choose标签对应的标签处理器

public class ChooseTag  extends SimpleTagSupport{
	
	//设置flag,但是flag只是作为一个成员变量,而不是choose标签的属性。
	//其主要作用是:用于子类标签之间传参
	private boolean flag;
	
	public boolean isFlag() {
		return flag;
	}

	public void setFlag(boolean flag) {
		this.flag = flag;
	}



	@Override
	public void doTag() throws JspException, IOException {
		this.getJspBody().invoke(null);
	}
}

WhenTag.java :when标签对应的标签处理器

public class WhenTag extends SimpleTagSupport{
	
	//设置test属性
	private boolean test;
	
	public void setTest(boolean test) {
		this.test = test;
	}
	
	@Override
	public void doTag() throws JspException, IOException {
			if(test) {
				this.getJspBody().invoke(null);
			}else {
				//传参
				ChooseTag parent=(ChooseTag) this.getParent();
				parent.setFlag(true);
			}
	}
}

OtherWiseTag.java:otherwise标签对应的标签处理器

public class OtherWiseTag extends SimpleTagSupport {
	
	@Override
	public void doTag() throws JspException, IOException {
		ChooseTag parent=(ChooseTag) this.getParent();
		if(parent.isFlag()) {
			this.getJspBody().invoke(null);
		}
		
	}
}

mytag.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>
	
	
   <tag>
	    <name>choose</name>
	    <tag-class>org.jsoft.hello.ChooseTag</tag-class>
	    <body-content>scriptless</body-content>
   </tag>	
  	
  	<tag>
	    <name>when</name>
	    <tag-class>org.jsoft.hello.WhenTag</tag-class>
	    <body-content>scriptless</body-content>
	    <!-- 属性声明 -->
	    <attribute>
	    	<!-- 属性名称 -->
	    	<name>test</name>
	    	<!-- 是否必填 -->
	    	<required>true</required>
	    	<!-- 是否支持EL表达式 -->
	    	<rtexprvalue>true</rtexprvalue>
	    </attribute>
  </tag>
  	
	<tag>
	    <name>otherwise</name>
	    <tag-class>org.jsoft.hello.OtherWiseTag</tag-class>
	    <body-content>scriptless</body-content>
   </tag>	
</taglib>

2)以下代码使用自定义标签

<%@page import="java.util.Random"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>
<%@ page language="java" 
    pageEncoding="utf-8"
    isErrorPage="true"
    %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>

	<!-- when 标签 -->
	<hlp:choose>			
			<hlp:when test="${10>5}">
				10>5
			</hlp:when>
			<hlp:when test="${5>4}">
				5>4
			</hlp:when>
			<hlp:otherwise>
				other
			</hlp:otherwise>
	</hlp:choose>
	
</body>
</html>

3)测试
在这里插入图片描述

五、自定义标签案例

案例1:自定义form表单登录标签

1)以下代码自定义登录标签
FormLoginTag.java 自定义标签处理器

/**
 *  自定义form表单标签
 * @author BGS
 *
 */
public class FormLoginTag extends SimpleTagSupport {
		
	
	String html="";
		                                                                                               	
	
	public FormLoginTag() {
		super();
		
		html+="<table border=\"1\"  align=\"center\" style=\"margin:200px auto;width:400px ;\" >";
		html+="		<caption>登录界面</caption>                                                                                 ";
		html+="		<tr>                                                                                                        ";
		html+="			<td>用户名1:</td>                                                                                        ";
		html+="			<td><input type=\"text\" name=\"user\"/></td>                                                               ";
		html+="		</tr>                                                                                                       ";
		html+="		<tr>                                                                                                        ";
		html+="			<td>密码1:</td>                                                                                          ";
		html+="			<td><input type=\"text\" name=\"user\"/></td>                                                               ";
		html+="		</tr>                                                                                                       ";
		html+="		<tr >                                                                                                       ";
		html+="			<td colspan=\"2\" align=\"center\"><input type=\"submit\" value=\"登录\" /> <input type=\"reset\" value=\"重置\"></td>";
		html+="		</tr>                                                                                                       ";
		html+="                                                                                                                 ";
		html+="</table>     "; 
	}



	@Override
	public void doTag() throws JspException, IOException {
		
		PageContext pageContext=(PageContext) this.getJspContext();
		
		pageContext.getRequest().setCharacterEncoding("UTF-8");
		
		pageContext.getOut().write(html);
		
	}
}

mytag.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>

  <tag>
    <name>login</name>
    <tag-class>org.jsoft.hello.FormLoginTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>


</taglib>

2)以下代码使用自定义登录标签
index.jsp 使用自定义标签

<%@page import="java.util.Random"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>
<%@ page language="java" 
    pageEncoding="utf-8"
    isErrorPage="true"
    %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Insert title here</title>
</head>
<body>
	
	<form action="">
		<hlp:login></hlp:login>                                                                                                      "
	</form>
</body>
</html>

展示如下:

在这里插入图片描述

案例2:自定义if标签

1)以下代码自定义if标签
IfTag .java 自定义标签处理器


public class IfTag  extends SimpleTagSupport{
		
	//设置标签test属性
	private boolean test;	
	public void setTest(boolean test) {
		this.test = test;
	}
	
	@Override
	public void doTag() throws JspException, IOException {
		
		if(test) {
			this.getJspBody().invoke(null);
		}
	}
}


mytag.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>

  
	
   <tag>
    <name>if</name>
    <tag-class>org.jsoft.hello.IfTag</tag-class>
    <body-content>scriptless</body-content>
    <!-- 属性声明 -->
    <attribute>
    	<!-- 属性名称 -->
    	<name>test</name>
    	<!-- 是否必填 -->
    	<required>true</required>
    	<!-- 是否支持EL表达式 -->
    	<rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>	

	
</taglib>


2)以下代码使用自定义if标签
index.jsp 使用自定义标签

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>核心标签库</title>
</head>
<body>

<hlp:if test="${10>5 }">
	条件成立,输出
</hlp:if>

</body>
</html>

展示如下:

在这里插入图片描述

案例3:自定义choose多条件判断标签

1)以下代码自定义choose标签
ChooseTag .java 自定义标签处理器


public class ChooseTag  extends SimpleTagSupport{

	private boolean flag;
	
	
	public boolean isFlag() {
		return flag;
	}


	public void setFlag(boolean flag) {
		this.flag = flag;
	}


	@Override
	public void doTag() throws JspException, IOException {
		this.getJspBody().invoke(null);
	}
}


WhenTag .java 自定义标签处理器


public class WhenTag  extends SimpleTagSupport{
		
	//设置标签test属性
	private boolean test;	
	public void setTest(boolean test) {
		this.test = test;
	}
	
	@Override
	public void doTag() throws JspException, IOException {
		
		if(test) {
			this.getJspBody().invoke(null);
		}else {
			ChooseTag choose=(ChooseTag) this.getParent();
			choose.setFlag(true);
		}
		
	}
}


OtherWiseTag .java 自定义标签处理器


public class OtherWiseTag  extends SimpleTagSupport{
	
	@Override
	public void doTag() throws JspException, IOException {
		
		ChooseTag tag=(ChooseTag) this.getParent();
		if(tag.isFlag()) {
			this.getJspBody().invoke(null);
		}
	}
}


mytag.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>


  
  
   <tag>
    <name>choose</name>
    <tag-class>org.jsoft.hello.ChooseTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>	


	
   <tag>
    <name>when</name>
    <tag-class>org.jsoft.hello.WhenTag</tag-class>
    <body-content>scriptless</body-content>
    <!-- 属性声明 -->
    <attribute>
    	<!-- 属性名称 -->
    	<name>test</name>
    	<!-- 是否必填 -->
    	<required>true</required>
    	<!-- 是否支持EL表达式 -->
    	<rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>	
  
  	
   <tag>
    <name>otherwise</name>
    <tag-class>org.jsoft.hello.OtherWiseTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>	
  

	
</taglib>



2)以下代码使用自定义标签
index.jsp 使用自定义标签

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>核心标签库</title>
</head>
<body>

<hlp:if test="${10>5 }">
	条件成立,输出
</hlp:if>


<hlp:choose>
	<hlp:when test="${10>5}">
		10>5 ,输出
	</hlp:when>
	<hlp:when test="${10>6}">
		10>6 ,输出
	</hlp:when>
	<hlp:otherwise>
		other
	</hlp:otherwise>
	
</hlp:choose>

</body>
</html>

展示如下:

在这里插入图片描述

案例4:自定义forEach标签

1)以下代码自定义ForEachTag 标签
ForEachTag .java 自定义标签处理器


public class ForEachTag extends SimpleTagSupport {
	
	
	private  Object items;
	private  String var;
	
	
				
	public Object getItems() {
		return items;
	}



	public void setItems(Object items) {
		this.items = items;
	}






	public String getVar() {
		return var;
	}



	public void setVar(String var) {
		this.var = var;
	}



	@Override
	public void doTag() throws JspException, IOException {
		PageContext pageContext=(PageContext) this.getJspContext();
		
		if(items instanceof List) {
		
			List list=(List) items;
			for(int i=0;i<list.size();i++) {
				pageContext.setAttribute(var, list.get(i));
				this.getJspBody().invoke(null);
			}
		}
		
		if(items instanceof Map) {
			Map map=(Map) items;
			Set entrys = map.entrySet();
			for(Object  o:entrys) {
				pageContext.setAttribute(var, o);
				this.getJspBody().invoke(null);
			}
		}
	}
}


mytag.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>

  
	
   
  
   <tag>
    <name>choose</name>
    <tag-class>org.jsoft.hello.ChooseTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>	


	
   <tag>
    <name>when</name>
    <tag-class>org.jsoft.hello.WhenTag</tag-class>
    <body-content>scriptless</body-content>
    <!-- 属性声明 -->
    <attribute>
    	<!-- 属性名称 -->
    	<name>test</name>
    	<!-- 是否必填 -->
    	<required>true</required>
    	<!-- 是否支持EL表达式 -->
    	<rtexprvalue>true</rtexprvalue>
    </attribute>
  </tag>	
  
  	
   <tag>
    <name>otherwise</name>
    <tag-class>org.jsoft.hello.OtherWiseTag</tag-class>
    <body-content>scriptless</body-content>
  </tag>	
  

	
</taglib>


2)以下代码使用自定义标签
index.jsp 使用自定义标签

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>核心标签库</title>
</head>
<body>

<%
	List l=new ArrayList();
	l.add(1);
	l.add(2);
	
	pageContext.setAttribute("l", l);
%>


<hlp:forEach items="${l }" var="item">
	${item}
</hlp:forEach>
	
	


</body>
</html>

展示如下:

在这里插入图片描述

案例5:自定义forTokens标签

1)以下代码自定义forTokens标签
ForTokeTag .java 自定义标签处理器


public class ForTokeTag extends SimpleTagSupport {
	
	private String str;
	
	private String split;
	
	
	public String getStr() {
		return str;
	}


	public void setStr(String str) {
		this.str = str;
	}


	public String getSplit() {
		return split;
	}



	public void setSplit(String split) {
		this.split = split;
	}



	@Override
	public void doTag() throws JspException, IOException {
		
		JspWriter out = this.getJspContext().getOut();
		
		String[] strs = str.split(split);
		for(String str:strs) {
			out.write(str);
		}
	}
}


mytag.tld

<?xml version="1.0" encoding="UTF-8" ?>

<taglib xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

  <tlib-version>1.1</tlib-version>
  <short-name>hlp</short-name>
  <uri>http://java.sun.com/jsp/jstl/hlp</uri>


  
  <tag>
    <name>forTokens</name>
    <tag-class>org.jsoft.hello.ForTokeTag</tag-class>
    <body-content>scriptless</body-content>
    <!-- 属性声明 -->
    <attribute>
    	<!-- 属性名称 -->
    	<name>str</name>
    	<!-- 是否必填 -->
    	<required>true</required>
    	<!-- 是否支持EL表达式 -->
    	<rtexprvalue>true</rtexprvalue>
    </attribute>
    <attribute>
    	<!-- 属性名称 -->
    	<name>split</name>
    	<!-- 是否必填 -->
    	<required>true</required>
    	<!-- 是否支持EL表达式 -->
    	<rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>	
	
</taglib>


2)以下代码使用自定义标签
index.jsp 使用自定义标签

<%@page import="java.util.HashMap"%>
<%@page import="java.util.Map"%>
<%@page import="java.util.List"%>
<%@page import="java.util.ArrayList"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/hlp" prefix="hlp" %>

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>核心标签库</title>
</head>
<body>

<%
	String str="您-好-吗";
	
	pageContext.setAttribute("str",str );
%>


<hlp:forTokens split="-" str="${str }"></hlp:forTokens>
	
	


</body>
</html>

展示如下:

在这里插入图片描述

发布了94 篇原创文章 · 获赞 0 · 访问量 651

猜你喜欢

转载自blog.csdn.net/weixin_45602227/article/details/104096740