一篇文章读懂Java Web的框架标签
创始人
2025-02-13 10:21:20
0次

在Java Web应用开发时,如果不是前后端分离进行数据交互的实现,一般都会通过JSP、FreeMarker、Velocity之类的技术进行页面的渲染。而在页面的渲染过程中,很多时候会使用到标签(taglib)这个技术。

比如为了控制页面一些显示逻辑,实现类似代码里if/else这种效果,就会使用到core标签里的内容,类似这样:

实现类似代码里if/else这种效果,就会使用到core标签里的内容

要实现一个容器数据的遍历,可以直接使用core标签的foreach。

要实现页面上数据的格式化,则可以直接使用format标签,进行对应数据的格式化展现。

甚至在一些MVC框架中,也都包含一些便捷的用于页面数据渲染的标签,可以直接使用。例如Spring中的form标签就可以直接进行数据的绑定。

那这些标签背后是如何工作的呢?

之前的文章里有写过JSP的工作原理,概括起来,就是会在执行时将JSP生成Servlet文件,然后再执行对应的service方法,进行请求的处理。其中涉及到使用标签的部分也会生成对应的执行逻辑。

而实际上,一个tag,对应的是一个Java类,根据规范实现相应的方法。由JSP生成的Servlet在执行标签的过程中,会直接调用标签对应类的指定方法,根据返回值,来进行页面上对应内容的输出。如果是继续则输出内容,如果是跳过内容就会被忽略。基本就是这样一个思路。

例如本文前面的 if 标签,对应生成的Servlet内容是这样的:

本文前面的 if 标签,对应生成的Servlet内容

再看 foreach 这个标签,生成的内容是这样的:

 foreach 这个标签

我们看到,foreach 被直接转换成了do while 循环。

其中,最核心的两个方法是:

  • doStartTag
  • doEndTag

doStartTag

该方法会在JSP类内,被具体的标签实现类调用。用于实例的标签开始,执行时pageContext和一系列属性被认为已经设置完成。

会返回EVAL_BODY_INCLUDE或者SKIP_BODY,从这两个结果的变量名称可以看出,如果如果tag期望继续处理body,就返回前者,否则不处理就返回后者。

doEndTag用于确认该标签执行后,页面是否要继续渲染。

整个taglib使用起来都比较便捷,直接在JSP中声明 prefix 和 uri ,相当于把这部分内容依赖添加了进来,然后直接使用标签进行属性的设置,对应命名空间下标签的使用等。

而这些标签的声明,是通过类似这样的形式,被保存在Jar文件或者WEB-INF这些地方。

标签的声明

具体的标签实现类,一般继承TagSupport,然后重写我们上面提到的doStartTag 和 doEndTag 方法。

所以,对于一般在JSP页面内有大堆的 <% %>这种所谓的 scriptlet,可以直接定义一个标签,然后把逻辑移动到重写方法内即可。

这些Tag声明的tld,一般会在应用部署后启动时进行扫描,然后添加到Map里。

Tag声明的tld

页面解析执行的时候,会判断对应声明的tld是否存在,没有就会停止页面执行。

页面解析执行的时候,会判断对应声明的tld是否存在

页面解析生成Servlet类之后,执行时会调用具体标签的属性设置,doStartTag这些方法,此时如果一些属性不存在,绑定不成功等这些具体的标签逻辑会被暴露出来。

比如我们在使用 Spring 标签时,经常使用其 form 标签进行参数绑定。为了试验,我们随便写一个Spring 的标签使用

  1.  

此时,JSP生成的内容是这样的:

JSP生成的内容

然后页面渲染时,会真正的进行数据绑定,判断这些属性的合法性等等,这里由于是随便写的一行代码,无法绑定所有报错了。

数据绑定

所以,对于 Spring、Struts2 等等这些框架的标签,本质上执行也还是这些逻辑,如果页面在渲染的时候出现问题,了解清楚是在哪一步的时候出了问题,知道具体这些标签的工作原理。

例如下图 Spring 的 InputTag 继承关系,也没有脱离Servlet 的Tag这个框。

总结下,Taglib的工作原理,是在应用部署的时候,解析tld的声明。页面渲染的时候,解析如果引入的tld不存在,就会报错。tld合法之后执行 tag 的具体逻辑,根据返回值判断是否继续页面的渲染。

框架的标签也是如此。 

【本文为51CTO专栏作者“侯树成”的原创稿件,转载请通过作者微信公众号『Tomcat那些事儿』获取授权】

戳这里,看该作者更多好文

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
粉嫩如何诠释霸道 东芝M805... “霸道粉”是个什么玩意东芝M805拿过来的时候,笔者扑哧笑了,不是笑这款笔记本,而是笑这款产品的颜色...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
全面诠释网络负载均衡 负载均衡的出现大大缓解了服务器的压力,更是有效的利用了资源,提高了效率。那么我们现在来说一下网络负载...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
只需三步,让你掌握阿尔法路由器... 请参照以下阿尔法路由器设置方法,通过浏览器进入及设置宽带路由器。经过这三个步骤的设置,基本上能够熟悉...
30分钟搞定iOS自定义相机 最近公司的项目中用到了相机,由于不用系统的相机,UI给的相机切图,必须自定义才可以。就花时间简单研究...