2015-07-23 2 views
0

Итак, я использовал этот код, чтобы получить тело ответа (исходный код страницы, доступ к которой) для .jsp страницы
Может кто-нибудь, пожалуйста, помогите мне в том, как я извлекаю тело ответа для страницы .html.манипулировать телом ответа .html и .jsp page

public class DetailFilter implements Filter { 
    private FilterConfig config; 
    public DetailFilter() { 
     super(); 
    } 

    public void init(final FilterConfig filterConfig) throws ServletException { 
     this.config = filterConfig; 
    } 


    public void destroy() { 
     config = null; 
    } 

    public void doFilter(final ServletRequest request, final ServletResponse response, 
         final FilterChain chain) throws IOException, ServletException { 

     ServletResponse newResponse = response; 

     if (request instanceof HttpServletRequest) { 
      newResponse = new CharResponseWrapper((HttpServletResponse) response); 
     } 

     chain.doFilter(request, newResponse); 

     if (newResponse instanceof CharResponseWrapper) { 
      String text = newResponse.toString(); 

      if (text != null) { 
       response.getWriter().write(text); 
       System.out.println("text is: "+text); 
      } 
     } 
    } 
} 


public class CharResponseWrapper extends HttpServletResponseWrapper{ 
    protected CharArrayWriter charWriter; 

    protected PrintWriter writer; 

    protected boolean getOutputStreamCalled; 

    protected boolean getWriterCalled; 

    public CharResponseWrapper(HttpServletResponse response) { 
     super(response); 

     charWriter = new CharArrayWriter(); 
    } 

    public ServletOutputStream getOutputStream() throws IOException { 
     if (getWriterCalled) { 
      throw new IllegalStateException("getWriter already called"); 
     } 

     getOutputStreamCalled = true; 
     return super.getOutputStream(); 
    } 

    public PrintWriter getWriter() throws IOException { 
     if (writer != null) { 
      return writer; 
     } 
     if (getOutputStreamCalled) { 
      throw new IllegalStateException("getOutputStream already called"); 
     } 
     getWriterCalled = true; 
     writer = new PrintWriter(charWriter); 

     return writer; 
    } 

    public String toString() { 
     String s = null; 
     if (writer != null) { 
      s = charWriter.toString(); 
     } 
     System.out.println("tosting is:"+s); 
     return s; 
    } 
} 

Проблема заключается в способе .jsp страница getWriter() (в CharResponseWrapper) вызывается и значение возвращается в писателе, но и для .html страницы ServletOutputStream называется и возвращает нулевое значение.

Я также пробовал URLConnection и InputStreamReader для того же самого. Код я использовал упоминается ниже

HttpServletRequest hReq = (HttpServletRequest) request; 
StringBuffer ss=hReq.getRequestURL(); 
String u=ss.toString(); 
URL url = new URL(u); 
URLConnection con = url.openConnection(); 
System.out.println("Connection successful"); 
InputStream is =con.getInputStream(); 
System.out.println("InputStream Successful"); 
BufferedReader br = new BufferedReader(new InputStreamReader(is)); 

String line = null; 
String[] arr={}; 
while ((line = br.readLine()) != null) { 
    System.out.println(line); 
} 

Код идет хорошо, и печатает «Успешное соединение» на консоли, но затем он идет как бесконечный цикл и никогда на самом деле не выполняет «InputStream Successful». Насколько я понимаю, когда соединение создается при вызове InputStream, он отправляет запрос на тот же URL-адрес, и весь процесс повторяется снова и снова. Может быть, этот процесс работает только для определенного URL-адреса, например url = «www.abcd.com»

Я хочу извлечь тело ответа на странице .html для некоторых манипуляций с данными. любая помощь по этому плз.

EDIT

Чтобы продолжить этот вопрос, после того, как я получаю тело ответа. Я вставляю JS перед тегом. Когда я СОПЯЛ эту строку, я вижу вставленный тело ответа. До этого момента все отлично. Я преобразую его в массив байтов и напишу массив байтов в экземпляре servletoutputstream.

ServletOutputStream newResponse1= response.getOutputStream(); 
newResponse1.write(bArray); 
newResponse1.close(); 

где bArray - тело ответа с вставленным JS в формате массива байтов. Ответ - ServletResponse. Выход, который я получаю, странный. Страница JSP выполняется дважды. Значит, если у меня есть кнопка на странице jsp, она показывает ту же кнопку два раза, и JS выполняется. HTML-страница запускается один раз, но этот окончательный ответ - это не тот ответ, который я написал. означает данные bArray (введенные данные), которые я написал, - это не тот же ответ, который я вижу в браузере.

Я чувствую, что мне нужно переопределить метод getOutputStream, который, к сожалению, я не могу. Пожалуйста помоги. возврат если вопрос непонятный.

Я также взял ссылку из How to read and copy the HTTP servlet response output stream content for logging

+0

Как вы уверены, что для Html-страницы вывод написан через ServletOutputStream? Если бы это было так, было бы достаточно создать собственный HttpServletResponse, чтобы инкапсулировать ваш собственный ServletOutputStream (так же, как это делает CharResponseWrapper). –

+0

Я подгрузил свой код в каждой строке и обнаружил, что для jsp-страницы после того, как метод doFilter называется, элемент управления переходит к методу getWriter() и возвращает ответ, но если страница html, элемент управления переходит в условие if в servletOutputStream, а затем outputstreamcalled = true, а затем возвращает значение null. Может быть, вы можете попробовать его в своей системе, просто создайте одну html-страницу и одну страницу jsp и указанный выше фильтр. Имейте в виду, что другого сервлета нет. – Aditya

ответ

0

Вы должны перехватывать выходного доставлен нижележащего ServletOutputStream, таким же образом CharArrayWriter делает. Поэтому я рекомендую вам изменить метод getOutputStream для инкапсуляции возвращаемого объекта в свой собственный экземпляр ServletOutputStream и сохранить его как переменную экземпляра CharResponseWrapper (то же, что и CharArrayWriter). Это было бы достаточно, чтобы быть похожим на это:

public class MyServletOutputStream extends ServletOutputStream 
{ 
    private final ServletOutputStream src; 

    private final StringBuilder stb=new StringBuilder(4096); 

    public MyServletOutputStream(ServletOutputStream src) 
    { 
     super(); 
     this.src=src; 
    } 

    @Override 
    public void write(int b) 
     throws IOException 
    { 
     this.src.write(b); 
     this.stb.append((char)b); 
    } 

    public StringBuilder getStb() 
    { 
     return this.stb; 
    } 
} 

Последнее, изменить метод toString, чтобы решить, какой объект он должен получить данные от: CharArrayWriter или MyServletOutputStream.

+0

Решенный thnx santi для ur поможет использовать выходной поток сервлета. Теперь я могу зафиксировать html-ответ. Интересно, почему метод getWriter не выполняется для html-страницы. – Aditya

+0

Добро пожаловать! Почему ServletOutputStream вместо Writer на HTML-страницах? Ну, я не уверен, но я думаю, что это вопрос _encoding_: Писатели потребляют данные на основе символов, но OutputStreams потребляют двоичные данные. JSP содержит явный параметр, объявляющий его фактическую кодировку (заголовок '@page pageEncoding'), который может понять контейнер JSP. Вместо этого HTML-страница не объявляет свою фактическую кодировку так, как это понимает контейнер JSP (контейнеры JSP не обрабатывают формат HTML). Кодирование HTML-страницы ориентировано на навигатор, и поэтому оно служит двоичным. –

+0

@LittleSanti большой ответ. Возможно, вы могли бы помочь [по этому вопросу] (http://stackoverflow.com/q/42440437/3493036) тоже. – Patrick