Захват сгенерированного динамического контента на стороне сервера - PullRequest
13 голосов
/ 26 декабря 2009

Есть ли способ, с помощью которого я могу захватить сгенерированный динамический контент на стороне сервера и передать этот файл или строковый объект того же самого в сервлет.

Мы можем генерировать динамический контент с помощью JSP, но у нас нет доступа к сгенерированному динамическому контенту на стороне сервера. Как только мы это сделаем, контейнер пересылки генерирует динамический контент и отправляет его в ответ.

Мне нужен доступ к сгенерированному динамическому контенту на стороне сервера.

Любая помощь будет оценена.

Ответы [ 4 ]

15 голосов
/ 26 декабря 2009

Если запрос идемпотентен (как, например, GET запросы), просто используйте java.net.URL, чтобы получить InputStream вывода JSP. Э.Г.

InputStream input = new URL("http://localhost/context/page.jsp").openStream();

Если запрос не идемпотентен (например, запросы POST), вам необходимо создать Filter, который обернет ServletResponse с пользовательской реализацией PrintWriter с пятью write() методами, которые были переопределены, при этом вы копируете выходные данные в некоторый буфер / компоновщик, который вы сохраняете в сеансе, или во временную папку в файловой системе локального диска, чтобы к ней можно было получить доступ впоследствии в последующих запросах. Э.Г.

package mypackage;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class CopyResponseFilter implements Filter {

    public void init(FilterConfig config) throws ServletException {
        // NOOP.
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
        throws IOException, ServletException
    {
        // Set character encoding for better world domination.
        response.setCharacterEncoding("UTF-8");

        // Create copy writer.
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        CopyWriter copyWriter = new CopyWriter(new OutputStreamWriter(
            httpResponse.getOutputStream(), httpResponse.getCharacterEncoding()));

        // Filter request with response which is wrapped with new writer.
        chain.doFilter(request, wrapResponse(httpResponse, copyWriter));

        // Store the copy writer afterwards in session so that it's available in next request.
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        httpRequest.getSession().setAttribute("copyWriter", copyWriter);
    }

    public void destroy() {
        // NOOP.
    }

    private static HttpServletResponse wrapResponse
        (final HttpServletResponse response, final PrintWriter writer)
    {
        return new HttpServletResponseWrapper(response) {
            public PrintWriter getWriter() throws IOException {
                return writer;
            }
        };
    }

}

class CopyWriter extends PrintWriter {

    StringBuilder copy = new StringBuilder();

    public CopyWriter(Writer out) {
        super(out);
    }

    public void write(int c) {
        copy.append((char) c); // It is actually a char, not an int.
        super.write(c);
        super.flush();
    }

    public void write(char[] chars) {
        copy.append(chars);
        super.write(chars);
        super.flush();
    }

    public void write(char[] chars, int offset, int length) {
        copy.append(chars, offset, length);
        super.write(chars, offset, length);
        super.flush();
    }

    public void write(String string) {
        copy.append(string);
        super.write(string);
        super.flush();
    }

    public void write(String string, int offset, int length) {
        copy.append(string, offset, length);
        super.write(string, offset, length);
        super.flush();
    }

    public String getCopy() {
        return copy.toString();
    }

}

Вы можете получить доступ к окончательному выводу в любом сервлете последующего запроса (обратите внимание, что вы не можете получить доступ к нему в любом сервлете текущего запроса, потому что это уже слишком поздно для выполнения что-то с этим), просто набрав CopyWriter в сеансе:

CopyWriter copyWriter = (CopyWriter) request.getSession().getAttribute("copyWriter");
String outputOfPreviousRequest = copyWriter.getCopy();

Обратите внимание, что вы должны сопоставить этот фильтр с url-pattern, охватывающим интересующие JSP-страницы, а не с /* или около того, иначе он будет работать на статических файлах (css, js, images и т. Д.), Которые включены в том же JSP, а также.

Также обратите внимание, что несколько запросов внутри одного сеанса переопределяют друг друга, вы должны различать эти запросы, используя правильный url-pattern или другой способ хранения его в сеансе, например, в аромате Map<URL, CopyWriter> или около того.

Надеюсь, это поможет.

2 голосов
/ 26 декабря 2009

Насколько я понимаю вашу цель, вы хотите хранить сгенерированный контент. Хотя я не могу придумать причину, чтобы сделать это, это возможно.

Вы можете использовать Filter и создать оболочку для HttpServletResponse, переопределить некоторые write методы и захватить весь контент, который будет выведен в браузер.

Редактировать: Ответ BalusC - это точное расширение, которое вам нужно, поэтому я не буду вдаваться в подробности.

0 голосов
/ 26 декабря 2009

Важно отметить, что JSP компилируются в сервлеты через JSP-компилятор (который может генерировать Java-код на полпути), поэтому все, что вы можете делать в JSP, вы можете делать с сервлетами.

Примечание по этому вопросу: вы должны знать о MVC , в общем случае сервлеты выступают в качестве контроллеров, JSP - в качестве представления, а любые структуры данных (Java-бины и тому подобное) - в качестве модели.

Для вашей проблемы вы должны сгенерировать контент / данные в сервлете - это ваш динамический контент, представленный объектами, выполнить любую необходимую вам обработку, настроить эти данные так, чтобы JSP могли получить к ним доступ (в запросе ) атрибут , например), откройте и отформатируйте его для клиента в JSP.

Для ознакомления вам следует ознакомиться с История сервлета: мгновенное учебное пособие , Учебное пособие по Java ™ EE 5 на веб-уровне .

0 голосов
/ 26 декабря 2009

Вам необходимо иметь доступ к соответствующим сервлетам на стороне сервера, или вы можете написать свой сервлет.

Здесь - это небольшое руководство по использованию сервлетов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...