我需要以编程方式呈现JSP页面。据我了解,JSP应该具有一些编译器。问题是我可以在没有JspServlet和其他组件的情况下直接使用此编译器吗?我所需要的只是记录如何使用JSP编译器(例如Jasper)。
我认为,一些其他信息可以澄清情况。我不能使用标准的JspServlet。我想在编译之前以某种方式更改源JSP(精确地将两个JSP合并在一起),因此我需要一种直接使用JSP编译器从InputStream(或Reader)编译JSP结果的方法。
合并两个JSP是布局要求。您可以问:“但是为什么这个人不使用SiteMesh或类似的东西?”。JSP页面之一不是静态的。它由用户提供并存储在数据库中。我们对此JSP布局进行消毒和验证(用户只能使用标签的子集,并且它们并不是标准的,而是为它们专门创建的),缓存它们等等。但是现在我们需要一种方法来使用这些JSP页面(存储在内存中)作为用户请求的所有JSP页面的布局。
我需要以编程方式呈现JSP页面。
到底有什么功能要求?您显然在寻找错误方向的解决方案。这是什么,您认为这是解决方案的问题/要求?我们可能会提出更好的建议。
例如,您是否仅需要其 输出 ?如果是这样,那么java.net.URLConnection就足够了。
java.net.URLConnection
编辑 :您编辑了问题:
我想在编译之前以某种方式更改源JSP(精确地将两个JSP合并在一起),因此我需要一种直接使用JSP编译器从InputStream(或Reader)编译JSP结果的方法。
OK,这是一个 有点 更加清晰。但是您需要什么呢?这些JSP实际代表什么?最终结果应用于什么?
例如,您是否只想将一个JSP包含在另一个JSP中?例如head.jsp在main.jsp?中包含a ?如果是这样,那么<jsp:include>就足够了。或更糟糕的是,它们是否包含原始Java代码以及您想重用的某些特定代码?如果是这样,那么您应该使用普通的Java类,并在必要时使用taglib。
head.jsp
main.jsp
<jsp:include>
编辑2 :如您所评论:
但是现在我们需要一种方法来使用这些JSP页面(这些存储在内存中)作为用户请求的所有JSP页面的布局
只需将JSP文件存储在webapp的webcontent内的磁盘文件系统上(ServletContext#getRealPath()这里可能会抢救),然后将请求转发到您自己的主JSP文件,其中包括使用以下两个JSP文件:
ServletContext#getRealPath()
<jsp:include page="${page1}" /> <jsp:include page="${page2}" />
编辑3 :我创建了一个SSCCE来证明其工作原理。
package mypackage; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { File root = new File(getServletContext().getRealPath("/")); String main = "<jsp:include page=\"${page1}\" /><jsp:include page=\"${page2}\" />"; write(main, new File(root, "main.jsp")); String page1 = "<p>We are in ${data1}"; write(page1, new File(root, "page1.jsp")); request.setAttribute("page1", "page1.jsp"); request.setAttribute("data1", "first jsp"); String page2 = "<p>We are in ${data2}"; write(page2, new File(root, "page2.jsp")); request.setAttribute("page2", "page2.jsp"); request.setAttribute("data2", "second jsp"); request.getRequestDispatcher("main.jsp").forward(request, response); } private static void write(String content, File file) throws IOException { BufferedWriter writer = null; try { writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8")); writer.write(content); } finally { if (writer != null) try { writer.close(); } catch (IOException ignore) {} } } }
在http:// localhost:8080 / playground / test(或您使用的任何主机/上下文名称)上执行它,您将看到
We are in first jsp We are in second jsp
为了提高效率,我将缓存每个资源,并利用它File#exists()来检查特定页面是否已保存在磁盘上。
File#exists()