мне нужно programmaticaly визуализации JSP-страницы.
Каково функциональное требование в конце концов? Вы явно ищете решение в неправильном направлении. Что это, проблема/требование, для которого вы думаете, что это решение? Мы можем придумать лучшие предложения.
Вам, например, нужно только его выход? Если да, то может быть достаточно java.net.URLConnection
.
Edit: вы изменяли вопрос:
Я хочу изменить источник JSP перед компиляцией каким-то образом (объединить два JSP вместе, чтобы быть точным), поэтому мне нужен способ, чтобы составить JSP результат от InputStream (или Reader) напрямую с помощью JSP-компилятора.
ОК, это немного более ясным. Но зачем вам это нужно? Что представляют собой эти JSP? Каков конечный результат, который должен использоваться?
Вы, например, просто хотите включить один JSP в другой? Например. включая head.jsp
в main.jsp
? Если это так, то может быть достаточно <jsp:include>
. Или это еще хуже, содержат ли они необработанный код Java с определенным кодом, который вы хотели бы использовать повторно? Если это так, то вам следует использовать простые классы Java и, если необходимо, теги для этого.
Edit 2: как вы прокомментировали:
Но теперь нам нужен способ, чтобы использовать эти страницы JSP (которые магазин находится в памяти, кстати), как макеты для всех страниц JSP что пользователь по запросу
Просто хранить файлы JSP на файловой системы на диске внутри WebContent веб-приложение (в ServletContext#getRealPath()
может прийти в помощь здесь) и направить запрос на свой собственный основной файл JSP, который включает в себя два файла JSP, используя для экзамена PLE:
<jsp:include page="${page1}" />
<jsp:include page="${page2}" />
Edit 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 (или любой другой хост/contextname вы используете), и вы увидите
We are in first jsp
We are in second jsp
Чтобы сделать его более эффективным, я бы кэшировать все ресурсы и использовать File#exists()
для проверьте, сохранена ли конкретная страница на диске.
У меня была аналогичная проблема, и «самое легкое» решение, которое я нашел, это переключение всего проекта на Velocity (или другой механизм шаблонов), где такие задачи тривиальны. Похоже, вы уже слишком далеко в разработке, чтобы делать такие изменения, но просто говорите ... – serg