Day11
到目前为止JSP还剩两个技术,一个是自定义标签,另一个是EL表达式
一.自定义标签库开发
1.1自定义标签简介
自定义标签主要用于移除Jsp页面中的java代码
使用自定义标签移除jsp页面中的java代码,只需要完成以下两个步骤
(1)编写一个实现Tag接口的Java类(标签处理器类)
(2)编写标签库描述符(tld)文件,在tld文件中对标签处理器类进行描述
快速入门:使用标签输出客户机IP
Tag接口的方法:

doEndTag()是在处理结束标签时用这个方法
doStartTag()是在处理开始标签时用这个方法
getParent()获取父类标签,其实父类标签也是一个java类
setParent(Tag t)是设置父标签
release()释放标签在运行时所占的资源
setPageContext(PageContext pc)标签处理器中最重要的方法,服务器在执行这个标签时会调用这个方法
然后将页面中PageContaxt对象传递给标签处理器,标签处理器通过这个方法拿到pageContext就可以拿到八大隐式对象
(3)3.在jsp页面中导入并使用自定义标签
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast" prefix="itcast"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>显示来访者ip</title> </head> <body> 您的ip地址是:<itcast:viewIP/> </body> </html>
(1).编写一个实现tag接口的java类(标签处理器类),并覆盖它的dostartTag方法,然后在该方法中写jsp页面中需移除的java代码
package cn.itcast.web.tag; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; public class ViewIPTag extends TagSupport {//setPageContext,为了避免Tag接口的所有方法所以就继承它的子类TagSupport @Override public int doStartTag() throws JspException { //拿到pageContext HttpServletRequest request = (HttpServletRequest) this.pageContext.getRequest(); JspWriter out = this.pageContext.getOut(); String ip = request.getRemoteAddr(); try { out.write(ip); } catch (IOException e) { throw new RuntimeException(e); } return super.doStartTag(); } }
(2).在web-inf目录中新建一个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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast</uri> <tag> <name>viewIP</name> <tag-class>cn.itcast.web.tag.ViewIPTag</tag-class> <body-content>empty</body-content> </tag> </taglib>
二。Tag接口的执行流程

1、public void setPageContext(PageContext pc), JSP引擎实例化标签处理器后,将调用setPageContext方法将JSP页面的pageContext对象传递给标签处理器,标签处理器以后可以通过这个pageContext对象与JSP页面进行通信。
2、public void setParent(Tag t),setPageContext方法执行完后,WEB容器接着调用的setParent方法将当前标签的父标签传递给当前标签处理器,如果当前标签没有父标签,则传递给setParent方法的参数值为null。
3、public int doStartTag(),调用了setPageContext方法和setParent方法之后,WEB容器执行到自定义标签的开始标记时,就会调用标签处理器的doStartTag方法。
4、public int doEndTag(),WEB容器执行完自定义标签的标签体后,就会接着去执行自定义标签的结束标记,此时,WEB容器会去调用标签处理器的doEndTag方法。
5、public void release(),通常WEB容器执行完自定义标签后,标签处理器会驻留在内存中,为其它请求服务器,直至停止web应用时,web容器才会调用release方法。
三。自定义标签功能扩展
开发人员在编写Jsp页面时,经常还需要在页面中引入一些逻辑, 自定义标签除了可以移除jsp页面java代码外,它也可以实现以下功能
•控制jsp页面某一部分内容是否执行

从JSP中Tag接口的doStringTag方法中有上面一段话,这句话就明确的解释了如何控制jsp中的部分内容是否执行的原理,返回Tag.EVAL_BODY_INCLUDE or BodyTag.EVAL_BODY_BUFFERED就是去执行,
返回 SKIP_BODY就不执行,所以我们只要控制这个方法的返回值就可以控制是否执行jsp中的某段内容
注意我们在实现Tag接口的时候往往实现它的子类TagSupport,这样就不会覆盖Tag的全部方法
package cn.itcast.web.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.Tag; import javax.servlet.jsp.tagext.TagSupport; public class TagDemo1 extends TagSupport { @Override public int doStartTag() throws JspException { return Tag.EVAL_BODY_INCLUDE; } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast</uri> <tag> <name>demo1</name> <tag-class>cn.itcast.web.tag.TagDemo1</tag-class> <body-content>JSP</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用标签控制jsp页面内容是否执行</title> </head> <body> <itcast:demo1> aaaaaa </itcast:demo1> </body> </html>
•控制整个jsp页面是否执行。

在JSP中的Tag接口的doEndTag()方法中明确的说明了当返回EVAL_PAGE则标签之后余下的页面内容会执行,当返回SKIP_PAGE则标签之后余下的页面
内容不会执行,从而我们可以控制整个jsp页面是否执行,注意我们在实现Tag接口的时候往往实现它的子类TagSupport,这样就不会覆盖Tag的全部方法
package cn.itcast.web.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.Tag; import javax.servlet.jsp.tagext.TagSupport; public class TagDemo2 extends TagSupport { @Override public int doEndTag() throws JspException { // TODO Auto-generated method stub return Tag.EVAL_PAGE; } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast</uri> <tag> <name>demo2</name> <tag-class>cn.itcast.web.tag.TagDemo2</tag-class> <body-content>empty</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast" prefix="itcast" %> <itcast:demo2/> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用标签控制整个页面是否执行</title> </head> <body> This is my JSP page. <br> </body> </html>
•控制jsp页面内容重复执行
用于控制jsp页面内容重复执行的方法存在于Tag接口的子接口IterationTag中的doAfterBody()方法的返回值中,整个方式会在执行
每个标签的结束方法doEndTag()之前运行,这个方法中有一点明确说明如何控制jsp页面内容重复执行的话

所以当doAferBody()方法返回EVAL_BODY_AGAIN时则再次执行当前标签控制的内容,如果这个方法返回SKIP_BODY则不会再次执行当前标签的内容,接着回去执行标签的结束方法doEndTag()。
注意我们在实现IterationTag接口的时候往往实现它的子类TagSupport,这样就不会覆盖IterationTag的全部方法
package cn.itcast.web.tag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.IterationTag; import javax.servlet.jsp.tagext.Tag; import javax.servlet.jsp.tagext.TagSupport; public class TagDemo3 extends TagSupport {//这里继承TagSupport方法,因为它既是Tag接口的子类也是IterationTag接口的子类 int count = 0; //注意这个count是共享的,因为在doAferBody()执行之后就会执行doEndTag() @Override public int doStartTag() throws JspException { // TODO Auto-generated method stub return Tag.EVAL_BODY_INCLUDE; } @Override public int doAfterBody() throws JspException { count++; if(count<5){ return IterationTag.EVAL_BODY_AGAIN; }else{ return Tag.SKIP_BODY; } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast</uri> <tag> <name>demo3</name> <tag-class>cn.itcast.web.tag.TagDemo3</tag-class> <body-content>JSP</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用标签控制jsp页面内容重复输出</title> </head> <body> <itcast:demo3> aaaaaaa </itcast:demo3> </body> </html>
•修改jsp页面内容输出
上面讲的IterationTag只能是实现迭代,不能实现修改(比如讲JSP中的小写内容修改为大写),这个时候就需要用到IterationTag接口的,这个接口在IterationTag接口的基础上
新增了两个常量EVAL_BODY_BUFFERED,EVAL_BODY_TAG(过时)和两个个方法setBodyContent(),doInitBody()
如果我们建立的标签处理类实现的是这个类,JSP引擎在调用开始标签的时候,如果开始这个开始标签返回的是EVAL_BODY_INCLUDE执行标签体,这个时候它就会去调用
setBodyContent()这个方法将标签体作为一个BodyContent对象中传递给你,也就是说在执行开始标签的时候,如果返回的是EVAL_BODY_INCLUDE,服务器就会将标签
体封装到一个对象中去,然后再调用setBodyContent()方法把那个封装的对象体传递给标签处理器类,标签处理器类拿到标签体的类之后就可以任意修改标签体重的内容了,
最后在输出给浏览器,最后还要注意一点,在实现BodyTag接口时,我们往往继承它的子类BodyTagSupport

package cn.itcast.web.tag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.BodyContent; import javax.servlet.jsp.tagext.BodyTag; import javax.servlet.jsp.tagext.BodyTagSupport; import javax.servlet.jsp.tagext.Tag; public class TagDemo4 extends BodyTagSupport { //当执行开始标签时,如果返回的是BodyTag.EVAL_BODY_BUFFERED,服务器就会将标签体 //封装到一个对象BodyContent中去 public int doStartTag() throws JspException { return BodyTag.EVAL_BODY_BUFFERED; } //修改标签体内容 public int doEndTag() throws JspException { BodyContent bc = this.bodyContent; String content = bc.getString(); //得到标签体 content = content.toUpperCase(); try { this.pageContext.getOut().write(content); } catch (IOException e) { throw new RuntimeException(e); } //表示余下的JSP页面还是要执行 return Tag.EVAL_PAGE; } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast</uri> <tag> <name>demo4</name> <tag-class>cn.itcast.web.tag.TagDemo4</tag-class> <body-content>JSP</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用标签修改jsp页面内容输出,将标签中的内容修改为大写</title> </head> <body> <itcast:demo4>--java simpleTag aaaaaaaa </itcast:demo4> </body> </html>
以上总结:
自定义标签功能扩展:
1.用自定义标签如何控制jsp页面某一部分内容是否执行:
编写一个java类,实现tag接口,控制doStartTag方法的返回值,如果返回EVLAL_BODY_INCLUDE,则标签体会执行,如果返回SKIP_BODY,则标签体不会执行
2.用自定义标签如何控制jsp页面是否执行
编写一个java类,实现tag接口,控制doEndTag方法的返回值,如果返回EVLAL_PAGE,则标签余下的jsp会执行,如果返回SKIP_PAGE,则余下jsp不会执行
3.用自定义标签如何控制标签重复执行
编写一个java类,实现IterationTag接口,首先控制doStartTag方法的返回值,让它返回EVAL_BODY_INCLUDE,让标签体执行,然后控制doAfterBody方法,如果该方法返回EVAL_BODY_AGAIN,则标签就会重复执行,如果返回SKIP_BODY,则标签体不会再执行。
4.用自定义标签如何修改标签体
编写一个java类,实现BodyTag接口,首先控制doStartTag方法的返回值,让它返回EVAL_BODY_BUFFERED,则服务器会创建一个BODYCOntent对象封装标签体,并调用setBodyContent方法,把代表标签体的BODYCOntent对象传递给标签处理器类,开发人员在doendtag方法中,拿到BODYCOntent对象就拿到标签体,从而可以对标签体作出修改后再输出。
三。简单标签
很不幸的是SUN公司在JSP2.0中定义了一个新的接口SimpleTag代替上面所学的Tag,IterationTag以及BodyTag接口所所是实现的方法,也就是所上面我们所学的SimpleTag都可
以实现,所以我们又不得不去学习这个接口了
由于传统标签使用三个标签接口来完成不同的功能,显得过于繁琐,不利于标签技术的推广, SUN公司为降低标签技术的学习难度,在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现标签的功能。实现SimpleTag接口的标签通常称为简单标签。简单标签共定义了5个方法


package cn.itcast.web.simpletag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; //控制标签体是否执行 public class SimpleTagDemo1 extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { //如果不想执行则不写以下代码 JspFragment jf = this.getJspBody(); //得到标签体对象 //jf.invoke(this.getJspContext().getOut()); //标签体执行到那里去 jf.invoke(null); //传一个null表示默认传给浏览器 } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast_simple</uri> <tag> <name>simpledemo1</name> <tag-class>cn.itcast.web.simpletag.SimpleTagDemo1</tag-class> <body-content>scriptless</body-content> <!--SUN公司在jsp2.0之后强迫不能实在jsp中使用脚本代码嵌入java代码,所以此处不是JSP而是scriptless--> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast_simple" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用简单标签控制标签体是否执行</title> </head> <body> <itcast:simpledemo1> aaaaa </itcast:simpledemo1> </body> </html>
(2)重复执行标签体
package cn.itcast.web.simpletag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; //重复执行标签体 public class SimpleTagDemo2 extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { JspFragment jf = this.getJspBody(); //得到标签体 for(int i=0;i<5;i++){ jf.invoke(null); } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast_simple</uri> <tag> <name>simpledemo2</name> <tag-class>cn.itcast.web.simpletag.SimpleTagDemo2</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast_simple" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用简单标签控制标签体重复执行</title> </head> <body> <itcast:simpledemo2> aaaaa </itcast:simpledemo2> </body> </html>
(3)用简单标签修改标签体
package cn.itcast.web.simpletag; 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; //用简单标签修改标签体 public class SimpleTagDemo3 extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { JspFragment jf = this.getJspBody(); StringWriter sw = new StringWriter(); //创建一个带缓存功能的writer jf.invoke(sw); //将标签体写到带缓存中去,然后在从缓冲中拿出来修改修改然后就可以写给浏览器了, //而这里invoke(Writer writer)中需要一个Writer,所以必须创建一个带缓存的writer //既满足带有缓存功能的writer,又可以得到缓存数据就只有两个CharArrayWriter和StringWriter String content = sw.toString(); content = content.toUpperCase(); //修改成大写 this.getJspContext().getOut().write(content); //写给浏览器 } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast_simple</uri> <tag> <name>simpledemo3</name> <tag-class>cn.itcast.web.simpletag.SimpleTagDemo3</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast_simple" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>用简单标签修改标签体</title> </head> <body> <itcast:simpledemo3> aaaaa </itcast:simpledemo3> </body> </html>
package cn.itcast.web.simpletag; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class SimpleTagDemo4 extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { throw new SkipPageException(); //只要doTag()方法抛SkipPageException异常就不会执行这个jsp页面 } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast_simple</uri> <tag> <name>simpledemo4</name> <tag-class>cn.itcast.web.simpletag.SimpleTagDemo4</tag-class> <body-content>empty</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/itcast_simple" prefix="itcast" %>
<itcast:simpledemo4/>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>用简单标签控制jsp页面是否执行</title>
</head>
<body>
</body>
</html>


package cn.itcast.web.simpletag; import java.io.IOException; import java.util.Date; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.JspFragment; import javax.servlet.jsp.tagext.SimpleTagSupport; public class SimpleTagDemo5 extends SimpleTagSupport { private int count; //这个数据可以自动转换成int,转换只支持八种基本数据类型 private Date date; public void setCount(int count) { this.count = count; } public void setDate(Date date) { this.date = date; } @Override public void doTag() throws JspException, IOException { JspFragment jf = this.getJspBody(); for(int i=0;i<count;i++){ jf.invoke(null); } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/itcast_simple</uri> <tag> <name>simpledemo5</name> <tag-class>cn.itcast.web.simpletag.SimpleTagDemo5</tag-class> <body-content>scriptless</body-content> <attribute> <!-- 标签的属性描述 --> <description>指定标签把标签体执行几次</description> <name>count</name> <required>true</required> <!-- 问这个属性是否是必须的 --> <rtexprvalue>true</rtexprvalue> <!-- 问这个属性是否是运行时的表达式,如果为true也就是说在Jsp页面中属性的值可以是运行脚本表达式, 也可以是EL表达式 ,如果为false就表示属性的值是一个固定的值,一般来说都写成true--> </attribute> <attribute> <name>date</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/itcast_simple" prefix="itcast" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>让标签带属性</title> </head> <body> <itcast:simpledemo5 count="4" date="${date}"> <!-- 注意哈,属性的值都是字符串,到标签处理器那边会自动转换, 但是这种转换只支持八种基本数据类型的转换,对于不是八种基本数据类型的可以用EL表达式 --> aaaaa </itcast:simpledemo5> </body> </html>
package cn.itcast.example; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; 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); } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/example</uri> <tag> <name>if</name> <tag-class>cn.itcast.example.IfTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/example" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>c:if标签</title> </head> <body> <c:if test="${user==null }"> xxxx </c:if> </body> </html>
(2)开发<c:if><c:else>标签
package cn.itcast.example; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class ChooseTag extends SimpleTagSupport { private boolean isExcute; //boolean默认值为false public boolean isExcute() { return isExcute; } public void setExcute(boolean isExcute) { this.isExcute = isExcute; } @Override public void doTag() throws JspException, IOException { //if...else执行的前提是父类标签要执行 this.getJspBody().invoke(null); } }
package cn.itcast.example; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class WhenTag extends SimpleTagSupport { private boolean test; public void setTest(boolean test) { this.test = test; } @Override public void doTag() throws JspException, IOException { ChooseTag parent = (ChooseTag) this.getParent(); if(test && !parent.isExcute()){ this.getJspBody().invoke(null); parent.setExcute(true); } } }
package cn.itcast.example; import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class OtherwiseTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { ChooseTag parent = (ChooseTag) this.getParent(); if(!parent.isExcute()){ this.getJspBody().invoke(null); } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/example</uri> <tag> <name>choose</name> <tag-class>cn.itcast.example.ChooseTag</tag-class> <body-content>scriptless</body-content> </tag> <tag> <name>when</name> <tag-class>cn.itcast.example.WhenTag</tag-class> <body-content>scriptless</body-content> <attribute> <name>test</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> <tag> <name>otherwise</name> <tag-class>cn.itcast.example.OtherwiseTag</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/example" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>c:choose c:when c:otherwise标签</title> </head> <body> <c:choose> <!-- 父标签定义一个变量来控制if...else --> <c:when test="${user!=null}"> xxxx </c:when> <c:otherwise> yyyy </c:otherwise> </c:choose> </body> </html>
(3)开发迭代标签
package cn.itcast.example; import java.io.IOException; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.Map; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; public class Foreach2Tag extends SimpleTagSupport { private Object items; //map list set object[] private String var; private Collection collection; public void setItems(Object items) { //items int[] this.items = items; if(items instanceof Collection){ this.collection = (Collection) items; } if(items instanceof Map){ Map map = (Map) items; this.collection = map.entrySet(); } //通用的数组的操作方式,既可以判断8种基本数据类型也可以判断非8种基本数据类型 if(items.getClass().isArray()){ //判断是否为数组 this.collection = new ArrayList(); int len = Array.getLength(items); for(int i=0;i<len;i++){ Object obj = Array.get(items, i); //不管是8种基本数据类型的数组还是对象数组都可以取 this.collection.add(obj); } } //对于8种基本数据类型SUN公司用的方法就是很老实的一个一个的判断,这个很垃圾 /*if(items instanceof Object[]){ Object objs[] = (Object[]) items; this.collection = Arrays.asList(objs); } if(items instanceof int[]){ int arr[] = (int[]) items; //this.collection = Arrays.asList(arr); this.collection = new ArrayList(); for(int i=0;i<arr.length;i++){ this.collection.add(arr[i]); } } if(items instanceof double[]){ } if(items instanceof char[]){ } if(items instanceof float[]){ } */ } public void setVar(String var) { this.var = var; } @Override public void doTag() throws JspException, IOException { Iterator it = this.collection.iterator(); while(it.hasNext()){ Object obj = it.next(); this.getJspContext().setAttribute(var, obj); this.getJspBody().invoke(null); } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/example</uri> <tag> <name>foreach2</name> <tag-class>cn.itcast.example.Foreach2Tag</tag-class> <body-content>scriptless</body-content> <attribute> <name>var</name> <required>true</required> </attribute> <attribute> <name>items</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/example" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>c:foreach2标签</title> </head> <body> <% List list = new ArrayList(); list.add("aaa"); list.add("bbb"); list.add("ccc"); request.setAttribute("list",list); %> <c:foreach2 var="str" items="${list}"> ${str }<br/> </c:foreach2> <hr> <% Map map = new HashMap(); map.put("aa","111"); map.put("bb","222"); map.put("cc","333"); request.setAttribute("map",map); %> <c:foreach2 var="entry" items="${map}"> ${entry.key }=${entry.value }<br/> </c:foreach2> <hr> <% Integer arr[] = {1,2,3}; request.setAttribute("arr",arr); %> <c:foreach2 var="num" items="${arr}"> ${num } </c:foreach2> <hr> <% int a[] = {1,2,3}; request.setAttribute("a",a); %> <c:foreach2 var="num" items="${a}"> ${num } </c:foreach2> <hr> <% double d[] = {5,2,3}; request.setAttribute("d",d); %> <c:foreach2 var="num" items="${d}"> ${num } </c:foreach2> </body> </html>
package cn.itcast.example; import java.io.IOException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspException; import javax.servlet.jsp.PageContext; import javax.servlet.jsp.SkipPageException; import javax.servlet.jsp.tagext.SimpleTagSupport; //防盗链标签 public class RefererTag extends SimpleTagSupport { private String site; private String page; public void setSite(String site) { this.site = site; } public void setPage(String page) { this.page = page; } @Override public void doTag() throws JspException, IOException { PageContext pageContext = (PageContext) this.getJspContext(); HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); HttpServletResponse response = (HttpServletResponse) pageContext.getResponse(); String referer = request.getHeader("referer"); if(referer==null || !referer.startsWith(site)){ //如果为盗链,则重定向 // /day11/index.jsp // /index.jsp // index.jsp if(page.startsWith("/")){ if(page.startsWith(request.getContextPath())){ // /day11 response.sendRedirect(page); }else{ response.sendRedirect(request.getContextPath() + page); } }else{ response.sendRedirect(request.getContextPath() + "/" + page); } throw new SkipPageException(); } } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/example</uri> <tag> <name>referer</name> <tag-class>cn.itcast.example.RefererTag</tag-class> <body-content>empty</body-content> <attribute> <name>site</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>page</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@taglib uri="/example" prefix="c" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <!-- site属性指定:允许访问的网站 page属性指定:非允许访问的网站来访问的话,跳到哪个页面 --> <c:referer site="http://localhost" page="index.jsp"/> <html> <head> <title>My JSP '5.jsp' starting page</title> </head> <body> 凤姐语录!!!! </body> </html>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <a href="${pageContext.request.contextPath }/example/5.jsp">凤姐语录</a> </body> </html>
(5)开发html转义标签
package cn.itcast.example; 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; public class HtmlFilterTag extends SimpleTagSupport { @Override public void doTag() throws JspException, IOException { StringWriter sw = new StringWriter(); JspFragment jf = this.getJspBody(); jf.invoke(sw); String content = sw.toString(); content = filter(content); this.getJspContext().getOut().write(content); } //这个转移HTML的代码在TomCat中有的HTMLfilter.java中有 public String filter(String message) { if (message == null) return (null); char content[] = new char[message.length()]; message.getChars(0, message.length(), content, 0); StringBuffer result = new StringBuffer(content.length + 50); for (int i = 0; i < content.length; i++) { switch (content[i]) { case '<': result.append("<"); break; case '>': result.append(">"); break; case '&': result.append("&"); break; case '"': result.append("""); break; default: result.append(content[i]); } } return (result.toString()); } }
<?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>A tag library exercising SimpleTag handlers.</description> <tlib-version>1.0</tlib-version> <short-name>SimpleTagLibrary</short-name> <uri>/example</uri> <tag> <name>htmlfilter</name> <tag-class>cn.itcast.example.HtmlFilterTag</tag-class> <body-content>scriptless</body-content> </tag> </taglib>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="/example" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP '5.jsp' starting page</title>
</head>
<body>
<a href="">点点</a>
<c:htmlfilter>
<a href="">点点</a>
</c:htmlfilter>
</body>
</html>





package cn.itcast.demo; import java.awt.Frame; public class Demo { public static void main(String[] args) { Frame f = new Frame(); f.setSize(300,300); f.setVisible(true); } }
工程文件的路径地址

第二步:将这个工程打成一个jar包









a




package cn.itcast.client; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; public class MyIE { /** * @param args * @throws IOException */ public static void main(String[] args) throws IOException { //HttpURLConnection sendHttp(); } //向服务器发送http请求 seo private static void sendHttp() throws MalformedURLException, IOException { URL url = new URL("http://localhost:8080/bb/servlet/ServletDemo1"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //要设置setDoOutput(true)才可以写到URLConnection中去 conn.setDoOutput(true); //设置请求方式 conn.setRequestMethod("POST"); //设置请求的消息头 conn.setRequestProperty("referer", "http://www.sina.com/index.html"); //设置请求数据 OutputStream out = conn.getOutputStream(); out.write("name=aaaa".getBytes()); //有请求有响应才是一个完整的请求,这里接受响应就表示是一个完整的请求 conn.getResponseCode(); } //读取服务器回送的http响应 private static void readHttp() throws MalformedURLException, IOException { URL url = new URL("http://localhost:8080/bb/servlet/ServletDemo1"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); //获取响应状态码 System.out.println(conn.getResponseCode()); //获取响应某个头 System.out.println(conn.getHeaderField("Content-Length")); //获取响应数据 InputStream in = conn.getInputStream(); try { int len = 0; byte buffer[] = new byte[1024]; while ((len = in.read(buffer)) > 0) { System.out.println(new String(buffer,0,len)); } } finally { if (in != null) try { in.close(); } catch (Exception e) { }; } } }
Sevlet
package cn.itcast.web.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("hahhaha"); //响应给浏览器的数据 //打印浏览器发过来的请求方式,请求头,请求数据 System.out.println(request.getMethod()); System.out.println(request.getHeader("referer")); System.out.println(request.getParameter("name")); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

浙公网安备 33010602011771号