直接从Java执行JSP

直接从Java执行JSP,java,jsp,Java,Jsp,我需要执行一个JSP。但是我需要直接从Java开始,而不使用Tomcat或任何其他servlet容器。编译JSP也是一件好事,但不是必需的。我认为org.apache.jasper包很适合这样做,但我在网上找不到任何好的示例或教程 我需要一些东西,比如: Class compiledJSP = compileJSP(new File("helloWorld.jsp")); String html = executeJSP(compiledJSP, httpServletRequest, http

我需要执行一个JSP。但是我需要直接从Java开始,而不使用Tomcat或任何其他servlet容器。编译JSP也是一件好事,但不是必需的。我认为org.apache.jasper包很适合这样做,但我在网上找不到任何好的示例或教程

我需要一些东西,比如:

Class compiledJSP = compileJSP(new File("helloWorld.jsp"));
String html = executeJSP(compiledJSP, httpServletRequest, httpServletResponse, ...);

html --> "Hello World, John!"

谢谢

您需要一个容器。JSP是Servlet上的抽象。Servlet依赖于容器提供的生命周期。您需要一个容器来提供生命周期。

如果您需要将JSP的输出捕获为字符串,那么从Servlet容器中可以相当简单(尽管从设计的角度来看还远不理想):
1.扩展javax.servlet.HttpServletResponseWrapper并重写getWriter()/getOutputStream()方法,以提供您自己的缓冲版本(例如StringWriter)
2.调用RequestDisparcher的“include()”方法,将原始响应包装到您自己的响应中。
3.抓取缓冲区的内容

现在,如果您需要在Servlet容器之外做同样的事情,您真的需要问自己“为什么?”。也许您应该使用模板引擎(FreeMarker/Velocity/StringTemplate/etc…)而不是JSP?如果JSP是格式良好的XML文件,并且没有使用任何java代码插入,那么将它们转换为FreeMarker模板(FreeMarker支持自定义JSP标记库)可能相当简单,这将大大简化您的任务。

然而,如果这是一个绝对的硬要求,您最直接的选择是:
1.运行外部Servlet容器并让它处理JSP解释。您的程序将向其提交HTTP请求并捕获输出。
2.同上,但您可以运行嵌入式Servlet容器(例如Jetty)

如果您的JSP在构建时可用,您可以按照其他答案中的建议,通过Jasper预编译它们


我强烈建议不要尝试实现您自己的servlet容器-您将走进一个受伤的世界。

如果没有servlet容器,这是可能的。这有两个步骤

首先是生成源代码。如果您查看JSPCAnt任务的源代码,就可以直接在代码中完成它。或者您可以直接调用ant任务

生成的代码只是一个Servlet,可以在容器外部调用Servlet上的方法:

只需实例化它,然后调用doGet(请求、响应)。我不确定您到底需要它做什么,但是使用spring模拟对象进行http请求和响应会使您的生活变得更轻松

这将填充响应对象。然后,您可以通过以下方式获得输出:

res.getContentAsString();
请参见此处的示例:


尝试执行它。不过,您需要首先编译JSP。我正在使用Maven 2来完成这个(和)

谢谢你的建议。实际上,我不想实现自己的servlet容器。我也不想编译和处理JSP,但我看不到任何替代方案。我想将服务器响应创建为JSON,如下所示:{html1:“1”,html2:“…”}每个html都必须使用JSP生成,但JSON不能存在。我使用了FreeMarker,但我不知道它是否有帮助。如果你知道我要找的方法,我会很感激的。谢谢。我不太清楚你想达到什么目的。您是否从servlet容器外部运行的应用程序返回JSON响应?为什么?我很难想象使用JSON进行应用程序间通信。如果你能澄清一下你想做什么,我很乐意帮忙。FreeMarker的不同之处在于,您可以完全从应用程序中运行它,而无需伪造servlet环境。例如,您的响应中的每个“html”片段都将由一个单独的FTL模板生成,您只需在每个模板上调用template.process(model,writer)。请注意,这(当前)在Jetty上不起作用,因为。它在Tomcat上运行良好。这里有一个关于这种方法的更详细的描述:但是你为什么要这样做呢?是否只想以编程方式生成HTML?这以前被标记为或的复制。不是。