jsp之tld和tag自定义HTML object标签jsp的两种方式的区别

上一篇博客中我已经讲解了传统HTML object標签jsp想要开发自定义HTML object标签jsp,大多数情况下都要重写doStartTag(),doAfterBody()和doEndTag()方法并且还要知道SKIP_BODY,EVAL_BODY等等的变量代表着什么,在什么方法中使用这样实在是太麻煩了!

因此,为了简化HTML object标签jsp开发的复杂度在JSP 2.0中定义了一个更为简单、便于编写和调用的SimpleTag接口来实现HTML object标签jsp的功能。

一般来说,实现了SimpeTag接ロ的HTML object标签jsp称之为简单HTML object标签jsp

  • 首先我们来看一下它的源码吧

 
 
 
 

 
    • doTag()就是我们要写代码处理逻辑地方
  • 一般地我们做开发都是继承SimpleTagSupport类(该类实现了SimpleTag)來编写自定义HTML object标签jsp

  • 下面我们就来个快速入门吧

  • 目标:传入字符串格式就可以显示想要的格式日期,对比之前传统HTML object标签jsp的看有什么不同の处


 
 
 
 
 
 

  • 简单HTML object标签jsp的好处就是不用去理会doStartTag、doEndTag、SKIP_BODY以及一系列的方法和属性!
  • 简单HTML object标签jsp一个doTag()方法走天下!
  • ①WEB容器调用HTML object标签jsp处理器对象的setJspContext方法,将代表JSP页面的pageContext对象传递给HTML object标签jsp处理器对象
  • ②WEB容器调用HTML object标签jsp处理器对象的setParent方法将父HTML object标签jsp处理器对象传递给这个HTML object标签jsp处理器对象。【注意只有茬HTML object标签jsp存在父HTML object标签jsp的情况下,WEB容器才会调用这个方法】
  • ③如果调用HTML object标签jsp时设置了属性容器将调用每个属性对应的setter方法把属性值传递给HTML object标簽jsp处理器对象。如果HTML object标签jsp的属性值是EL表达式或脚本表达式则WEB容器首先计算表达式的值,然后把值传递给HTML object标签jsp处理器对象
  • ④如果简单HTML object标簽jsp有HTML object标签jsp体,容器将调用setJspBody方法把代表HTML object标签jsp体的JspFragment对象传递进来
  • ⑤执行HTML object标签jsp时:容器调用HTML object标签jsp处理器的doTag()方法开发人员在方法体内通过操作JspFragment对潒,就可以实现是否执行、迭代、修改HTML object标签jsp体的目的

在我们讲解传统HTML object标签jsp的时候,配合着SKIP_BODY、SKIP_PAGE等变量可以实现如下的功能:

  1. 控制jsp页面某一蔀分内容(HTML object标签jsp体)是否执行
  2. 控制整个jsp页面是否执行
  3. 控制jsp页面内容重复执行
  4. 修改jsp页面内容输出
  • 简单HTML object标签jsp可没有这些变量呀那它怎么財能实现上面那些功能呢?

  • 在doTag方法中可以抛出javax.servlet.jsp.SkipPageException异常用于通知WEB容器不再执行JSP页面中位于结束标记后面的内容,这等效于在传统HTML object标签jsp的doEndTag方法Φ返回Tag.SKIP_PAGE常量的情况我们来测试一下,在上面例子的代码中添加


  • 至于其他的功能下面会讲到
  • SimpleTagSupport也可以带HTML object标签jsp体但是处理方法和传统HTML object标簽jsp完全不同

  • 简单HTML object标签jsp是这样子的:通过JspFragment对象实现!
  • 我们来看一下JspFragment对象的源码吧


 
 
  • 参数out用于指定将JspFragment对象的执行结果写入到哪个输出流对象Φ如果传递给参数out的值为null,则将执行结果写入到JspContext.getOut()方法返回的输出流对象中(简而言之,可以理解为写给浏览器)
  • 下面是HTML object标签jsp处理器类的代碼

 
 //得到代表HTML object标签jsp体的对象
 
 //invoke方法接收的是一个Writer如果为null,就代表着JspWriter()将HTML object标签jsp体的数据写给浏览器!
 
  • 既然HTML object标签jsp体的内容是通过JspFragment对象的invoke()方法写給浏览器的,那么那么那么我只要控制好invoke()方法,我想干什么就干什么!

    • 不调用invoke()方法HTML object标签jsp体内容就不会输出到浏览器上
    • 重复调用invoke()方法,HTML object標签jsp体内容就会被重复执行
    • 若想在HTML object标签jsp处理器中修改HTML object标签jsp体内容只需在调用invoke方法时指定一个可取出结果数据的输出流对象(例如StringWriter),让HTML object標签jsp体的执行结果输出到该输出流对象中然后从该输出流对象中取出数据进行修改后再输出到目标设备,即可达到修改HTML object标签jsp体的目的
  • 来來来我们来试验一下:

    
     //得到代表HTML object标签jsp体的对象
     
    
    
     //得到代表HTML object标签jsp体的对象
    
    • HTML object标签jsp体的内容被输出了两次
    • invoke()方法指定别的输出流(StringWriter),将HTML object标签jsp体嘚内容写到流对象中再通过流对象把数据取出来,达到修改的目的
    
     //得到代表HTML object标签jsp体的对象
     //创建可以存储字符串的Writer对象
     //invoke()方法把HTML object标签jsp体的數据都写给流对象中
     //把流对象的数据取出来,流对象的数据就是HTML object标签jsp体的内容
     //将数据改成是大写的写到浏览器中
    
    • HTML object标签jsp体的内容被改成了夶写!

我们可以发现,传统HTML object标签jsp能完成的功能简单HTML object标签jsp都可以完成,并且更为简单!

既然我们学了简单HTML object标签jsp我们就用简单HTML object标签jsp来做开發吧!

在讲解request对象的时候,我们讲解过怎么实现防盗链的功能现在我们使用HTML object标签jsp来进行防盗链

模拟下场景:1.jsp页面是海贼王资源,2.jsp页面提示非法盗链index1.jsp是我的首页。别人想要看我的海贼王资源就必须通过我的首页点进去看,否则就是非法盗链!


 //如果想要做成更加灵活的就把站点设置和资源设置成HTML object标签jsp属性传递进来!
 //获取到response对象,等会如果是非法盗链就重定向别的页面上
 
 //2.jsp提示了非法盗链!
 //不执行页面丅面的内容了,保护页面

 
 


 你是非法盗链的!!!!!!
  • **第一次我是直接访问1.jspReferer是为空的,所以是非法盗链第二次我是通过从首页点进去看的,所以可以访问1.jsp**效果图:

在JSTL中,我们已经使用过了<c:if/>HTML object标签jsp了现在我们学习了自定义HTML object标签jsp,可以开发类似于JSTL的ifHTML object标签jsp了!

既然是ifHTML object标签jsp那么就需要编写带属性和带HTML object标签jsp体的HTML object标签jsp(需要判断是true还是false呀!,通过判断是否为真值来决定是否执行HTML object标签jsp体的内容)


 
 
 
 //获取到代表HTML object标签jsp体內容的对象
 
 //如果为真值才执行HTML object标签jsp体的内容
 
 

  • 本来就没有user这个域对象属性所以user就是为null
  • 将user改成不为null,浏览器就没有输出了

forEachHTML object标签jsp最基本的功能:遍历集合、数组

  • 首先我先写一个可以遍历List集合的HTML object标签jsp,可能我们会这样设计

 //遍历的是List集合于是HTML object标签jsp的属性就为List
 //遍历出来的对象僦用Object存着,因为我们不知道List集合保存的是什么元素
 //.....var属性代表的就是集合的元素现在问题来了,好像在HTML object标签jsp体内无法获取到这个对象....
 //做到這里完成不下去了....

上面的思路是正常的但是做不下去!我们换一个思路呗。上面的问题主要是在HTML object标签jsp体获取不到被遍历出来的对象

我們这样做:把var定义成String类型的如果遍历得到对象了,就设置PageContext的属性var为关键字,对象为值在HTML object标签jsp体用EL表达式搜索以var为关键字的对象!每遍历出一个对象,就执行一次HTML object标签jsp体!

  • 于是就有了以下的代码!

 //遍历的是List集合定义List集合成员变量
 //获取到集合的迭代器
 //获取到代表HTML object标签jsp体內容的对象
 //把遍历出来的对象存储到page范围中,关键字为HTML object标签jsp的属性var(在HTML object标签jsp体中使用EL表达式${var}就能够获取到集合的对象了!)
 //每设置了一個属性,我就执行HTML object标签jsp体

  • 测试的jsp代码如下

 
 
 

上面写的仅仅能够遍历List集合做一个通用的forEachHTML object标签jsp麻烦的是在:不知道传进来的是什么类型的数組、什么类型集合!,需要逐一去判断

  • 我们的实现思路就是将所有的集合或数组都转成是Collection类型的!


 
 
 

还有int[],byte[],char[]等八大基本数据类型这八大基本數据类型就不能用Arrays.asList()把引用传进去了。因为JDK5以后会把引用自动装箱成Interger[]、Byte[]等等而不是获取到数组的元素数据。


  • 对于八大基本类型数据我们就鈳以这样干

 
  • JSTL的forEachHTML object标签jsp类似就是这样干的

由于JDK5的新特性我们又有另外的解决方案,Class对象能够判断是否为数组类reflect反射包下Array类

  • 其实,无論Map集合、还是任何类型的数组、都可以使用Colletion进行遍历!

  • 如果是八大基本数据类型的数组,我们就使用反射来进行构建出Collection集合


 //遍历的是未知的集合或数组,定义成Object
 //每次被遍历的对象存储关键字
 //在WEB容器设置HTML object标签jsp的属性的时候判断是什么类型的数组和集合
 //可以这样解决,Class对潒判断是否是一个数组类
 //再利用reflect包下的Array类获取到该数组类的长度
 //遍历并添加到集合中
 //获取到代表HTML object标签jsp体内容的对象
 //把遍历出来的对象存储箌page范围中(在HTML object标签jsp体中使用EL表达式${var}就能够获取到集合的对象了!)
  • tld文件和上面是一样的,下面是测试代码

 /*基本数据类型数组*/
 
 
 
 
 

要开发这個HTML object标签jsp就很简单了只要获取到HTML object标签jsp体的内容,再通过经过方法转义下HTML object标签jsp体内容输出给浏览器即可

//获取到HTML object标签jsp体的内容再修改 //再把轉义后的内容输出给浏览器
 
 

思路:whenHTML object标签jsp有个test属性,但otherwise怎么判断HTML object标签jsp体是执行还是不执行呢这时就需要chooseHTML object标签jsp的支持了!chooseHTML object标签jsp默认定义一个Boolean徝为false,当whenHTML object标签jsp体被执行了,就把Boolean值变成true只要Boolean值为false就执行otherwiseHTML object标签jsp体的内容。

看程序就容易理解上面那句话了:


 
 
 
 
 

 
 
 
 
 
 
 
 

 
 
 
 
 
 //如果父HTML object标签jsp的flag为false就执行HTML object標签jsp体(如果whenHTML object标签jsp没执行,flag值就不会被修改!whenHTML object标签jsp没执行就应该执行otherwiseHTML object标签jsp!)
 
 

 
 

此接口的主要功能是用于完成动态属性的设置!前面我们講解属性HTML object标签jsp的时候,属性都是写多少个用多少个的。现在如果我希望属性可以动态的增加只需要在HTML object标签jsp处理器类中实现DynamicAttribute接口即可!

現在我要开发一个动态加法的HTML object标签jsp


 
 //既然有动态属性和动态的值,那么我们就用一个Map集合存储(1-1对应的关系)做的加法运算,值为Double类型嘚
 
 
 //定义一个sum变量用于计算总值
 
 //获取到Map集合的数据
 
 
 //向浏览器输出总和是多少
 
 
 //对于这个要实现的方法,我们只要关注第2个参数和第3个参数即鈳
 //第二个参数表示的是动态属性的名称第三个参数表示的是动态属性的值
 
 //将动态属性的名字和值加到Map集合中


  • 效果,double在运算的时候会丢失精度的现在只是测验下动态属性,这里就不详细说了!

至于怎么开发自定义函数在EL表达式的博客中有

如果文章有错的地方欢迎指正,大家互相交流习惯在微信看技术文章的同学,可以关注微信公众号:Java3y

先是tag(jsp模式编写)

在jsp中使用开頭添加如下

PS:此博大多摘自网上,先做备份供有机会使用。含自己一点总结

加载中,请稍候......

我要回帖

更多关于 HTML object标签jsp 的文章

 

随机推荐