首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JSP标记库的工作方式是否像某种受诱惑的JAVA代码生成?

JSP标记库的工作方式是否像某种受诱惑的JAVA代码生成?
EN

Stack Overflow用户
提问于 2015-01-28 04:00:45
回答 2查看 383关注 0票数 1

(这个问题更多地是关于容器如何包含标记的。更少地讨论如何实现标记。谢谢拉维·塔普莱亚尔指出这一点。

我对JSP很陌生。我了解到JSP页面最终被转化为Servlets。

因此,我使用一些JSTL标记和容器生成的servlet代码对JSP页面进行了比较。

似乎每个标记都封装了一个常用的Java代码块,其中有一些由标记属性填充/控制的槽。并将块插入到_jspService()方法中。

这是标记库如何为最终servlet Java代码贡献的通用机制吗?

加1

我为包含标记的JSP挖掘生成的<c:forEach> servlet代码。

JSP代码如下:

图片1:

生成的servlet代码如下:

图片2:

图片3:

它应该是一个2步骤的过程,以生成对客户端的最终响应:

  1. JSP (picture 1) ==> Servlet Java code (picture 2, 3)
  2. Servlet Java code ==> HTML (容器执行_jspService()方法)。

我的问题是:

  • 图2和图3的代码从何而来?
  • 谁将图片2和3的代码布局在JSP生成的servlet类中?

加2

通过检查图3中的代码和org.apache.taglibs.standard.tag.rt.core.ForEachTag类,我猜ForEachTag类型有点像iterator

  • 它被赋予一组要迭代的项。
  • 它为外部世界提供了一些API来控制迭代过程。

并公开迭代的数据:

  • 它使用scope作为桥梁,将当前迭代的项传递给外部世界。

而外部_jspx_meth_c_005fforEach_005f0方法只是使用ForEachTag类型来执行迭代。直到ForEachTag叫他停下来。

因此,我想图片2和3中的代码只是Web容器JSP解析逻辑的一部分,用于支持JSTL标记。

加3

如果我分析Web和Tab库之间的不同责任,容器如何知道如何生成类似于图2和图3的代码来支持--一个新的标记库

答案加3

作为一个简单的/经典的标记,容器只需要生成样板代码来调用它们的生命周期方法。下面是一个简单标记的示例:

容器只关心生命周期方法。如果存在body,容器将进一步解析主体以获得经典标记。对于简单的标记,doTag()方法涵盖了所有内容。

加4

在学习了classic tag lifecycle之后,我了解到org.apache.taglibs.standard.tag.rt.core.ForEachTag是一个典型的标记处理程序。图3中的代码是容器在评估标记体时调用经典的生命周期方法。

The ForEachTag

  • 包含要循环的集合数据。
  • 维护循环状态
  • 并使用其生命周期方法来控制循环。
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-28 06:21:19

是的,你的观察是正确的。标记库的行为就像运行Java代码的小型模板引擎(作为最终servlet的一部分),带有标记属性(可选)自定义Java实现。

如果您查看JSP文件头,即使用任何JSTL标记,您将注意到它通过引用其URI导入标记库描述符,并在稍后从库调用其中一个标记时为其分配前缀。

代码语言:javascript
复制
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

URI (由管理员)映射到一个.tld标记库描述符文件,该文件包含<tag>条目,将每个标记映射到其实现的Java,并描述标记支持的所有属性。如果要实现生成屏幕上键盘的自定义标记,则条目可能如下所示

代码语言:javascript
复制
<tag>
  <description>Generates an on-screen keyboard</description>
  <name>onScreenKB</name>
  <tag-class>com.myapp.jsp.tags.OnScreenKBTag</tag-class>
  <body-content>empty</body-content>
</tag>

此.tld文件被放置在/WEB-INF目录下的任何位置。标记处理程序类需要实现特定的接口,但是容器还提供了我们可以扩展的SimpleTagSupport类。

代码语言:javascript
复制
public class OnScreenKBTag extends SimpleTagSupport {

  public void doTag() throws JspException, IOException {
    StringBuilder html = new StrinBuilder();
    JspWriter out = getJspContext().getOut();

    // tag logic
    html.append(...);
    ...
    // print response
    out.print(html);
  }
}

然后在JSP文件中导入

代码语言:javascript
复制
<%@ taglib uri="/WEB-INF/tags/myapp.tld" prefix="app" %>

并将您的自定义标记用作

代码语言:javascript
复制
<div id="keyboard">
  <app:onScreenKB />
</div>
票数 2
EN

Stack Overflow用户

发布于 2015-01-28 14:21:51

在学习了经典的标记生命周期之后,我了解到org.apache.taglibs.standard.tag.rt.core.ForEachTag是一个经典的标记处理程序。图3中的代码是容器在评估标记体时调用经典的生命周期方法。

ForEachTag:

  • 包含要循环的集合数据。
  • 维护循环状态
  • 并使用其生命周期方法来控制循环。

答案加3

作为一个简单的/经典的标记,容器只需要生成样板代码来调用它们的生命周期方法。下面是一个简单标记的示例:

红色的是调用生命周期的方法。

容器只关心生命周期方法。如果存在body,容器将进一步解析主体以获得经典标记。对于简单的标记,doTag()方法涵盖了所有内容。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28184405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档