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.
Imagine that you want to dynamically create a main.jsp
with this contents:
<jsp:include page="${page1}" />
<jsp:include page="${page2}" />
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);
}
}
}
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
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.