24

我想知道 JSP 有没有被编译过?我问的原因是因为每当我在 Web 服务器上部署我的 Java EE 应用程序时,我只能在 WEB-INF 文件夹中看到那些 servlet 和 beans 类文件,因为它们是编译的,而不是那个 JSP,所以它是如何工作的,以及正常请求/响应周期的逻辑流程和大图是什么。

4

4 回答 4

61

基本上:

  • .jsp在您的 servlet 容器中,JSP servlet 映射到以(通常)结尾的任何 URL

  • 当请求其中一个.jspURL 时,该请求将转到 JSP servlet。然后,这个 servlet 检查 JSP 是否已经编译。

  • 如果 JSP 尚未编译,则 JSP servlet 会将 JSP 转换为一些实现Servlet接口的 Java 源代码。然后它将这个 Java 源代码编译成一个.class文件。该.class文件通常位于应用程序的 servlet 容器的工作目录中的某个位置。

  • 一旦 JSP servlet 从 JSP 源代码编译了 servlet 类,它就将请求转发给这个 servlet 类。

问题是,除非您专门预编译您的 JSP,否则所有这些都发生在运行时,并且隐藏在 servlet 容器的工作目录中,因此它是“不可见的”。还要记住,这是“概念上”发生的事情,在这个工作流程中可以进行一些优化。

于 2012-05-15T19:33:17.140 回答
7

是的,它们是编译的!

较旧的编译器甚至会生成 java 和 class 文件。

看起来使用较新的编译器(至少从 Sun JDK 6 update 30 开始),它们可以在内存中生成所有字节码,因此您在应用程序worktemp目录中看不到任何痕迹。

于 2012-05-15T19:26:50.667 回答
7

JSP 编译为 Servlet。他们只有一个特殊的编译器,通常嵌入在容器中。

来自优秀的 ole 维基百科:

在架构上,JSP 可以被视为 Java servlet 的高级抽象。JSP 在运行时被翻译成 servlet;每个 JSP 的 servlet 都被缓存并重新使用,直到原始 JSP 被修改。

于 2012-05-15T19:27:53.160 回答
1

在运行时,JSP 代码由 JSP 编译器解释,它解析出 JSP 代码中的所有特殊功能并将它们转换为 Java 代码。从每个 JSP 创建的 Java 类实现Servlet. 然后,Java 代码会经历与通常情况相同的循环。仍然在运行时,它被编译成字节码,然后编译成机器码。最后,JSP-turned-Servlet 像任何其他 Servlet 一样响应请求。

如果您查看 *_jsp.java 文件,您应该会发现一个扩展的类org.apache.jasper.runtime.HttpJspBase。这个抽象类扩展了HttpServlet. HttpJspBase提供了一些基础功能,Tomcat 编译的所有 JSP 都将使用这些功能,并且当您的 JSP 执行时,最终会执行该 Servlet 上的服务方法,该方法最终会执行 _jspService 方法。如果您检查 _jspService 方法,您会发现一系列方法调用将您的 HTML 写入输出流。这段代码对您来说应该很熟悉,因为它与您用这个 JSP 替换的 Java 代码没有什么不同。

当然,JSP Servlet 类在每个 Web 容器上看起来都不一样。例如,org.apache.jasper 类是 Tomcat 特定的类。您的 JSP 在您运行它的每个不同 Web 容器上的编译方式都不同。重要的一点是 JSP 的行为和语法有一个标准规范,只要您使用的 Web 容器符合规范,您的 JSP 应该在所有容器上运行相同,即使它们的 Java 代码翻译成看起来完全不同。

摘自Nicholas S WilliamsProfessional Java for Web Applications

于 2016-12-31T16:41:01.840 回答