我想知道 JSP 有没有被编译过?我问的原因是因为每当我在 Web 服务器上部署我的 Java EE 应用程序时,我只能在 WEB-INF 文件夹中看到那些 servlet 和 beans 类文件,因为它们是编译的,而不是那个 JSP,所以它是如何工作的,以及正常请求/响应周期的逻辑流程和大图是什么。
4 回答
基本上:
.jsp
在您的 servlet 容器中,JSP servlet 映射到以(通常)结尾的任何 URL当请求其中一个
.jsp
URL 时,该请求将转到 JSP servlet。然后,这个 servlet 检查 JSP 是否已经编译。如果 JSP 尚未编译,则 JSP servlet 会将 JSP 转换为一些实现
Servlet
接口的 Java 源代码。然后它将这个 Java 源代码编译成一个.class
文件。该.class
文件通常位于应用程序的 servlet 容器的工作目录中的某个位置。一旦 JSP servlet 从 JSP 源代码编译了 servlet 类,它就将请求转发给这个 servlet 类。
问题是,除非您专门预编译您的 JSP,否则所有这些都发生在运行时,并且隐藏在 servlet 容器的工作目录中,因此它是“不可见的”。还要记住,这是“概念上”发生的事情,在这个工作流程中可以进行一些优化。
是的,它们是编译的!
较旧的编译器甚至会生成 java 和 class 文件。
看起来使用较新的编译器(至少从 Sun JDK 6 update 30 开始),它们可以在内存中生成所有字节码,因此您在应用程序work
或temp
目录中看不到任何痕迹。
JSP 编译为 Servlet。他们只有一个特殊的编译器,通常嵌入在容器中。
来自优秀的 ole 维基百科:
在架构上,JSP 可以被视为 Java servlet 的高级抽象。JSP 在运行时被翻译成 servlet;每个 JSP 的 servlet 都被缓存并重新使用,直到原始 JSP 被修改。
在运行时,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 Williams的Professional Java for Web Applications