Нужна помощь в создании кастомного HttpServletResponse - PullRequest
4 голосов
/ 17 января 2011

Внезапно застрял при генерации пользовательского ответа сервлета. Я хочу заменить ответ сервлета предопределенным:

public class MyCustomResponse extends HttpServletResponseWrapper {
  private String customOutput;
  public MyCustomResponse(String customOutput, HttpServletResponse response) {
    super(response);
    // PrintWriter and Outputstream should stream this variable as output
    this.customOutput = customOutput;
  }

  //
  // Below I need to override something
  //
}

и код фильтра отсекается следующим образом:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  //
  //
  MyCustomResponse customResponse = new MyCustomResponse("Hello world!", (HttpServletResponse) response);
  chain.doFilter(request, customResponse);
}

Позор мне, но я действительно застрял в написании этой простой задачи :(

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

UPDATE:

Все, что я хочу, - это реализовать пользовательскую оболочку ответа, которая, будучи помещенной в цепочку фильтров, всегда отвечала бы некоторым предопределенным текстом. Я знаю, как писать собственные данные из метода doFilter (), но я хочу, чтобы за это отвечала MyCustomResponse - просто создайте экземпляр и поместите в цепочку. Любые аргументированные ответы «Вы не можете сделать это, потому что ...» также приветствуются.

Ответы [ 4 ]

2 голосов
/ 17 января 2011

Как указано в одном из ваших комментариев:

"Я хочу, чтобы мой пользовательский ответ возвращал строка в ответ на getWriter или Вызов метода getOutputStream "

Для этого вы должны предоставить собственную реализацию getWriter () и getOutputStream (), переопределив их.

//---

    private PrintWriter printWriter = null;
    private ServletOutputStream outputStream = null;

    public PrintWriter getWriter( ) throws IOException {

        if (this.outputStream != null) {
            throw new IllegalStateException(
                    "Cannot call getWriter( ) after getOutputStream( )");
        }

        if (this.printWriter == null) {
            // initialize printWriter
        }
        return this.printWriter;
    }

    public ServletOutputStream getOutputStream( ) throws IOException {

        if (this.printWriter != null) {
            throw new IllegalStateException(
                "Cannot call getOutputStream( ) after getWriter( )");
        }

        if (this.outputStream == null) {
            // initialize outputStream
        }
        return this.outputStream;
    }

//---
1 голос
/ 17 января 2011

Ваша оболочка ответа бесполезна, поскольку в ней хранится только строка в Java-объекте, используемая для моделирования фактического HTTP-ответа.

Фактический HTTP-ответ, который получает клиент, является потоком байтов (соответственно символов), отправленных через выходной поток (соответственно модуль записи) объекта HttpServletResponse (и заголовки, файлы cookie и т. Д., Хранящиеся в объекте HttpServletResponse) , Если вы хотите отправить пользовательскую строку вывода клиенту, просто используйте response.getWriter (). Print ("Hello worlds!").

Передача ответа остальной части цепочки фильтров сомнительна, поскольку остальная часть цепочки, вероятно, захочет добавить свои собственные данные в поток ответов.

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

private ServletOutputStream fakeOutputStream = 
    new ServletOutputStream() {

        @Override
        public void write(int b) throws IOException {
            // do nothing. Everything written to this stream is ignored
        }
    }

private PrintWriter fakeWriter = new PrintWriter(fakeOutputStream);

public MyCustomResponse(String customOutput, HttpServletResponse response) {
    super(response);
    response.getWriter().print(customOutput);
}

@Override
public ServletOutputStream getOutputStream() {
    return fakeOutputStream;
}

@Override
public PrintWriter getWriter() {
    return fakeWriter;
}
1 голос
/ 17 января 2011

Извините, но

  1. не понятно, какой у тебя проблема. У вас код написан, так? Это не работает? что именно не работает?
  2. Почему ты хочешь это сделать? «Правильным» решением является передача информации в качестве атрибута сеанса.
  3. Я не верю, что это может работать. Действительно, вы не вызываете непосредственно следующий фильтр в цепочке. Вы любезно спрашиваете приложение. Сервер для этого. И вы не должны заменять запрос / ответ сервлета своим собственным. Используйте метод, описанный выше (# 2)
0 голосов
/ 17 января 2011

Я не вижу причины того, что вы хотите сделать, но если вы хотите использовать свою обертку, мое предложение будет:

Создайте свой собственный сервлет, который использует вашу обертку, и зарегистрируйте его в web.xml, примерно так:

  • Расширить javax.servlet.GenericServlet и переопределить метод service(ServletRequest, ServletResponse). Затем вы используете шаблон Template Method для создания service(ServletRequest, ServletResponseWrapper). OR
  • Расширить javax.servlet.HttpServlet и переопределить service(HttpServletRequest, HttpServletResponse) метод. Используйте шаблон Template Method для создания service(HttpServletRequest, HttpServletResponseWrapper). Для этого потребуется, чтобы вы не использовали методы doGet, doPost, doPut, doTrace, уже предоставленные HttpServlet, а вместо этого создали свой собственный, который использует вашу оболочку.

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

...