JSP 以编程方式呈现 [英] JSP programmatically render

查看:22
本文介绍了JSP 以编程方式呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要以编程方式呈现 JSP 页面.据我了解,JSP 应该有一些编译器.问题是我可以在没有 JspServlet 等的情况下直接使用这个编译器吗?我需要的只是关于如何使用 JSP 编译器(例如 Jasper)的文档.

I need to programmatically render JSP page. As far as I understand, JSP should have some compiler. The question is can I use this compiler dirrectly without JspServlet and others? All I need is documentation how to use JSP compiler (Jasper, for example).

我认为一些额外的信息可以澄清情况.我不能使用标准的 JspServlet.我想在编译前以某种方式更改源JSP(准确地说是将两个JSP合并在一起),所以我需要一种直接使用JSP编译器从InputStream(或Reader)编译JSP结果的方法.

Some additional information would clarify situation, I think. I can not use standard JspServlet. I want to change source JSP before compilation in some way (merge two JSP together to be precise), so I need a way to compile JSP result from InputStream (or Reader) using the JSP compiler directly.

合并两个 JSP 是布局要求.你可以问:但为什么这个人不使用 SiteMesh 或类似的东西?".JSP 页面之一不是静态的.它由用户提供并存储在数据库中.我们清理和验证这个 JSP 布局(用户只能使用标签的子集,所有这些都不是标准的,而是专门为他们创建的),缓存它们等等.但是现在我们需要一种方法来使用这些 JSP 页面(它们存储在内存中)作为用户请求的所有 JSP 页面的布局.

Merging of two JSP is layout requirement. You can ask: "But why this guy just doesn't use SiteMesh or something like this?". One of JSP pages is not static. It's provided by user and stored in database. We sanitify and validates this JSP layout (users are able to use only subset of tags, and all of them are not standart but created specially for them), cache them and so on. But now we need a way to use these JSP pages (which are stored in memory) as layouts for all JSP pages that user request.

推荐答案

如果服务器的部署文件夹是可写的并且服务器被配置为热发布部署文件夹中的任何更改(Tomcat默认情况下是这样),那么你可以让一个servlet直接在那里写入 JSP 文件并将请求转发到某个主要的 JSP 文件.

If the server's deploy folder is writable and the server is configured to hotpublish any changes in deploy folder (Tomcat by default does), then you could just let a servlet write JSP files right there and forward the request to some main JSP file.

想象一下,您想动态地创建一个带有以下内容的 main.jsp:

Imagine that you want to dynamically create a main.jsp with this contents:

<jsp:include page="${page1}" />
<jsp:include page="${page2}" />

其中 ${page1} 解析为 page1.jsp${page2} 解析为 page2.jsp,然后是 SSCCE:

Where ${page1} resolves to page1.jsp and ${page2} resolves to page2.jsp, then here's an SSCCE:

package com.stackoverflow.q1719254;

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;

@WebServlet("/test")
public class TestServlet extends HttpServlet {

    @Override
    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 {
        try (BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))) {
            writer.write(content);
        }
    }
    
}

在 http://localhost:8080/playground/test(或您使用的任何主机/上下文名称)执行它,你会看到

Execute it at http://localhost:8080/playground/test (or whatever host/contextname you're using) and you'll see

We are in first jsp
We are in second jsp

为了提高效率,我会缓存每个资源并使用 File#exists() 来检查特定页面是否已经保存在磁盘上.

To make it more efficient I would cache every resource and make use of File#exists() to check if the particular page is already saved on disk.

这篇关于JSP 以编程方式呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆