Как написать фильтр ответов?

#java #servlets #jakarta-ee #servlet-filters

#java #сервлеты #джакарта-ee #сервлет-фильтры

Вопрос:

Есть ли способ обрабатывать только ответ в фильтре.

Правильный ли приведенный ниже код?

   public void doFilter(request , response , chain) {
        //code to handle request 
          chain.doFilter(request, response);
        //code to handle response .
  }
  

Ответ №1:

Это зависит от того, что вы хотите. В общем, ваш пример неверен. После chain.doFilter возврата становится слишком поздно что-либо делать с ответом. На данный момент весь ответ уже отправлен клиенту, и ваш код не имеет к нему доступа.

Что вам нужно сделать, это обернуть request и / или response в ваши собственные классы, передать эти оболочки в doFilter метод и обрабатывать любую обработку в ваших оболочках.

Чтобы упростить задачу, в servlet api уже доступны оболочки: см. HttpServletRequestWrapper и HttpServletResponseWrapper классы. Если вы хотите обрабатывать выходные данные, которые фактически отправляются клиенту, вам также необходимо написать пользовательские обертки OutputStream или Writer и возвращать их из вашей обертки HttpServletResponse. Да, много переноса 🙂

Некоторые более простые фильтры могут работать без переноса запроса или ответа: например, перед вызовом doFilter вы уже можете получить доступ к заголовкам запроса или отправить пользовательский ответ без вызова doFilter . Но если вы хотите обработать тело запроса, вы не можете просто прочитать его, иначе оно будет недоступно остальной части цепочки. В этом случае вам нужно снова использовать технику переноса.

Ответ №2:

Показанный вами код не совсем корректен, но с необходимым упрощением терминологии — это так. Вы можете «обработать» запрос даже после chain.doFilter(..) (и ответ перед ним).

Что chain.doFilter(..) означает, что процесс передается желаемой цели, и когда метод возвращается, цель завершила свой вывод.

Итак, чтобы быть более точным — это «до» и «после» обработки запроса и генерации ответа.

Ответ №3:

Ваш код, кажется, в порядке.

Если вы хотите обрабатывать только ответ, вы можете просто поместить свой код в //Code to handle response . раздел и делать все, что вам нравится.

Если вы хотите что-то сделать с выводом, вам придется предоставить специальную оболочку ответа, которая обрабатывает outputstream в ответе, куда может записываться сервлет (и другие фильтры).

Ответ №4:

Запрос и ответы доступны только для чтения.Таким образом, у них нет методов настройки для изменения содержимого этого.Но, используя классы «HttpServletRequestWrapper и HttpServletResponseWrapper», которые предоставляются встроенными в java, мы можем изменять его содержимое.Мы инкапсулируем исходные объекты запроса и ответа объектами-оболочками, изменяя объекты-оболочки, мы действительно можем модифицировать исходные объекты запроса и ответа.

Ответ №5:

Я отфильтровал ответ, используя приведенный ниже набор кода :

 public void doFilter(request , response , chain) {
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            CharResponseWrapper responseWrapper = new CharResponseWrapper(httpServletResponse);
            ServletResponse newResponse = response;
            if (request instanceof HttpServletRequest) {
              newResponse = new CharResponseWrapper((HttpServletResponse) response);
            }
            chain.doFilter(request, newResponse);
            if (newResponse instanceof CharResponseWrapper) {
                String responseString = newResponse.toString();
                if(StringUtils.isNotBlank(walletResponseString)) {
                    //code to handle response by converting to object
                }
            }
}