在Java Web应用开发时,篇文如果不是章读前后端分离进行数据交互的实现,一般都会通过JSP、懂J的框FreeMarker、架标Velocity之类的篇文技术进行页面的渲染。而在页面的章读渲染过程中,很多时候会使用到标签(taglib)这个技术。懂J的框 比如为了控制页面一些显示逻辑,架标实现类似代码里if/else这种效果,篇文就会使用到core标签里的章读内容,类似这样: 要实现一个容器数据的懂J的框遍历,可以直接使用core标签的架标foreach。 要实现页面上数据的篇文格式化,则可以直接使用format标签,章读进行对应数据的懂J的框格式化展现。 甚至在一些MVC框架中,也都包含一些便捷的用于页面数据渲染的标签,可以直接使用。源码库例如Spring中的form标签就可以直接进行数据的绑定。 那这些标签背后是如何工作的呢? 之前的文章里有写过JSP的工作原理,概括起来,就是会在执行时将JSP生成Servlet文件,然后再执行对应的service方法,进行请求的处理。其中涉及到使用标签的部分也会生成对应的执行逻辑。 而实际上,一个tag,对应的是一个Java类,根据规范实现相应的方法。由JSP生成的Servlet在执行标签的过程中,会直接调用标签对应类的指定方法,根据返回值,来进行页面上对应内容的输出。服务器租用如果是继续则输出内容,如果是跳过内容就会被忽略。基本就是这样一个思路。 例如本文前面的 if 标签,对应生成的Servlet内容是这样的: 再看 foreach 这个标签,生成的内容是这样的: 我们看到,foreach 被直接转换成了do while 循环。 其中,最核心的两个方法是: 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里。 页面解析执行的时候,会判断对应声明的tld是否存在,没有就会停止页面执行。 页面解析生成Servlet类之后,执行时会调用具体标签的属性设置,doStartTag这些方法,此时如果一些属性不存在,绑定不成功等这些具体的标签逻辑会被暴露出来。 比如我们在使用 Spring 标签时,经常使用其 form 标签进行参数绑定。为了试验,我们随便写一个Spring 的标签使用