В отличие от того, что Стивен C сказал, да, JSP - сервлеты и т. Д. И т. Д. (И скорость довольно хорошая и простая в использовании)
Но что такое сервлет?
Это интерфейс. Интерфейс с одним основным методом:
service(ServletRequest req, ServletResponse res)
Найдите класс JSP, приведение его в сервлет, создавать реализации ServletRequest и ServletResponse, а затем ...
String jspClassName = findJspClassForJSP("your.jsp");
Class jspClass = Class.forName(jspClassName);
Servlet jspServlet = (Servlet)jspClass.newInstance();
MyServletRequest req = new MyServletRequest();
MyServletResponse resp = new MyServletResponse();
jspServlet.init();
jspServlet.service(req, resp);
jspServlet.destroy();
String results = reps.getContent();
Будет ли это работать? Ну, после некоторой работы это будет. Очевидно, вам нужно реализовать минимальные фасады ServletRequest/Response, а также то, что вам понадобится вашим JSP. Но, скорее всего, вам, вероятно, понадобится немного больше, чем атрибуты и потоки. Если вы вернете ответ, StringWriter, вы на полпути.
Следующая часть представляет собой сервлет из JSP. Удобно, компилятор Jasper делает это для вас - игра вызывает его. Я никогда не делал этого напрямую, но это явно можно сделать, так как это делает контейнер сервлетов, а также файл JSPC/bat-файл, муравьиная задача, а также большинство контейнеров Servlet, использующих Jasper. Итак, это можно сделать. Когда вы знаете, как это вызывать, вы узнаете окончательное имя сгенерированного класса для JSP. (См. Первую строку образца.)
Я когда-нибудь это делал? Нет. Но я держал пари в течение менее чем одного дня беспорядка вокруг, вы узнаете, это выполнимо или нет. Я держу пари, что это так, особенно если вы не запуститесь в какой-либо классный загрузчик shenanigans. У вас может возникнуть проблема, если вы позволите своим пользователям изменять и восстанавливать JSP (поэтому MyEmail.jsp компилируется в MyEmail.class, MyEmail_2.class и т. Д.). Но если вы вызовете Джаспера самостоятельно, у вас, скорее всего, будет больше контроля над этим. Другая сложная часть - это определение имени класса JSP. Большинство контейнеров следуют базовому шаблону здесь, поэтому, если вы соскучитесь в сгенерированном коде из WAR, вы, скорее всего, найдете его.
Держите JSP разумно простыми (и шаблон электронной почты не должен быть слишком сложным со встроенной Java или чем-либо, что делает случайные вызовы), и это еще более хороший шанс, что он будет работать.
Ваше решение не может быть переносимым из коробки Tomcat, но вам, вероятно, все равно. Люди, с которыми я разговаривал, используют JSP для шаблонов, просто открыли сокет на свой собственный сервер и сделали запрос. Они тоже не зашли так далеко.
Но на поверхности, сохраните какой-то странный классный загрузчик черных дыр, я уверен, вы можете заставить это работать довольно быстро. Реализация всего запроса и ответа, как вам нужно, бороться несколько неработающими как JSP и JSTL вызова вещи вы не планировали, и, как говорит Сант,
поредактирует поредактируют поредактирую все!
Addenda:
Таким образом, для всех скептиков ...
public void runJsp() {
JspC jspc = new JspC();
jspc.setUriroot("/tmp/app");
jspc.setOutputDir("/tmp/dest");
jspc.setJspFiles("newjsp.jsp");
jspc.setCompile(true);
try {
jspc.execute();
Class cls = Class.forName("org.apache.jsp.newjsp_jsp");
Servlet s = (Servlet) cls.newInstance();
MyRequest req = new MyRequest();
MyResponse resp = new MyResponse();
s.init(getServletConfig());
s.service(req, resp);
s.destroy();
System.out.println(resp.getSw().toString());
} catch (JasperException ex) {
throw new RuntimeException(ex);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(ex);
} catch (InstantiationException ex) {
throw new RuntimeException(ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (ServletException ex) {
throw new RuntimeException(ex);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
Удивительно то, что исходный код и 1/2 часа в отладчике будет делать для вас.
Я создал простой JSP в /tmp/app/newjsp.jsp.
jspc.setUriroot сообщает компилятору, где находится база вашего «веб-приложения». jspc.setOutputDir сообщает jspc, куда помещать сгенерированные файлы Java и Class. jspc.setJspFiles сообщает jspc, какие файлы нужно компилировать, основываясь на корне URI. jspc.setCompile сказал, что он действительно компилирует код. Наконец, jspc.execute() выполняет действие.
По умолчанию Jasper использует пакет org.apache.jsp и создает новый класс на основе имени файла JSP. Для моего простого эксперимента я просто поместил «/ tmp/dest» в путь класса моего контейнера Glassfish, чтобы контейнер нашел сгенерированные классы.
Загрузите класс и получите экземпляр.
Наконец, я создал MyRequest, MyRequest и, в конечном счете, MySession. В моей среде IDE были созданы заглушки для соответствующих интерфейсов. В этом случае я реализовал: MyRequest.getSession(), MyResponse.setContentType(), MyResponse.setBufferSize() и MyResponse.getWriter().
public PrintWriter getWriter() throws IOException {
if (sw == null) {
sw = new StringWriter();
pw = new PrintWriter(sw);
}
return pw;
}
Очевидно, что sw и pw являются переменными экземпляра MyResponse.
MyRequest возвратил экземпляр MySession. Моя реализация MySession - ничего. Но среда выполнения требовала сеанса, она просто не использует ее сама по себе для моего очень простого JSP, и я не был мотивирован на начинку в том, что был из Servlet.
Я проверил это на Glassfish v2.1. Я просто добавил appserv_rt.jar (из glassfish/lib) в мой путь к классу сборки (чтобы он мог найти банки JspC), но я не собираю его в WAR (поскольку он уже находится в контейнере).
И, шазам, это сработало. В «реальной жизни», предполагая, что процесс, который хотел использовать JSP, был фактически получен из веб-запроса, я просто создавал HttpServletResponseWrapper и переопределял предыдущие три метода, остальное, вероятно, просто работало. Если веб-запрос вообще отсутствует на картинке, вам нужно создать собственную реализацию сеанса (неважно, просто это карта).
Я бы также использовал приватный URLClassLoader для загрузки поддельных классов JSP.Если я ПОНИМАЮ, я бы никогда не перезагрузил JSP, а просто сделал бы адрес моей директории WEB-INF/classes и предоставил бы ей собственный пакет и давал бы системе загрузить их.
Но, да, это сработало. Ничего страшного. Это просто java.
Да; Я знаю все о Velocity и FreeMarker. Это JSP, в котором я интересуюсь. – Kong
См. Также http://stackoverflow.com/questions/1075827/execute-jsp-directly-from-java – Raedwald