Den*_*nov 13 java jsp rendering servlets jstl
我需要以编程方式呈现JSP页面.据我所知,JSP应该有一些编译器.问题是我可以在没有JspServlet和其他人的情况下直接使用这个编译器吗?我需要的只是文档如何使用JSP编译器(例如,Jasper).
我认为,一些额外的信息可以澄清情况.我不能使用标准的JspServlet.我想以某种方式在编译之前更改源JSP(准确地将两个JSP合并在一起),因此我需要一种方法直接使用JSP编译器从InputStream(或Reader)编译JSP结果.
两个JSP的合并是布局要求.你可以问:"但为什么这个人不使用SiteMesh或类似的东西?".其中一个JSP页面不是静态的.它由用户提供并存储在数据库中.我们清理并验证了这个JSP布局(用户只能使用标签的子集,并且所有这些标签都不是标准的,而是专门为它们创建的),缓存它们等等.但是现在我们需要一种方法来使用这些JSP页面(存储在内存中)作为用户请求的所有JSP页面的布局.
我需要programmaticaly渲染JSP页面.
毕竟功能要求是什么?你正在寻找一个错误方向的解决方案.是什么,您认为这是解决方案的问题/要求是什么?我们可能会提出更好的建议.
例如,你需要它的输出吗?如果是这样,那么java.net.URLConnection就足够了.
编辑:您编辑了您的问题:
我想以某种方式在编译之前更改源JSP(准确地将两个JSP合并在一起),因此我需要一种方法直接使用JSP compiller从InputStream(或Reader)编译JSP结果.
OK,这是一个有点更加清晰.但你需要什么呢?这些JSP实际代表什么?应该使用的最终结果是什么?
您是否只想在另一个中包含一个JSP?例如包括head.jsp一个main.jsp?如果是这样,那么<jsp:include>就足够了.或者更糟糕的是,它们是否包含原始Java代码以及您想要重用的某些特定代码?如果是这样,那么你应该使用普通的Java类和必要的taglibs.
编辑2:正如您所说:
但是现在我们需要一种方法来使用这些JSP页面(顺便说一下存储在内存中)作为用户请求的所有JSP页面的布局
只需将JSP文件存储在webapp的webcontent中的磁盘文件系统中(这ServletContext#getRealPath()可能会在这里解决)并将请求转发到您自己的主JSP文件,其中包含两个JSP文件,例如:
<jsp:include page="${page1}" />
<jsp:include page="${page2}" />
Run Code Online (Sandbox Code Playgroud)
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) {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
在http:// localhost:8080/playground/test(或者你正在使用的任何主机/上下文名称)执行它,你会看到
We are in first jsp
We are in second jsp
Run Code Online (Sandbox Code Playgroud)
为了提高效率,我会缓存每个资源,并使用它File#exists()来检查特定页面是否已保存在磁盘上.
我不完全确定这是否是您正在寻找的,但DWR框架包含一个方法WebContext.forwardToString,该方法将当前请求和假响应对象转发到URL,然后将缓冲区的内容读入内存.以下是代码示例:
StringWriter sout = new StringWriter();
StringBuffer buffer = sout.getBuffer();
HttpServletResponse realResponse = getHttpServletResponse();
HttpServletResponse fakeResponse = new SwallowingHttpServletResponse(realResponse, sout, realResponse.getCharacterEncoding());
HttpServletRequest realRequest = getHttpServletRequest();
realRequest.setAttribute(WebContext.ATTRIBUTE_DWR, Boolean.TRUE);
getServletContext().getRequestDispatcher(url).forward(realRequest, fakeResponse);
return buffer.toString();
Run Code Online (Sandbox Code Playgroud)
您可以使用它来获取jsp重新生成的结果并将它们存储在内存中.您可以从上面的链接下载源代码,了解SwallowingHttpServletResponse的工作原理.
| 归档时间: |
|
| 查看次数: |
20807 次 |
| 最近记录: |