2012-03-11 30 views
5

Tôi cố gắng để đọc kết quả của FreemarkerView rendering:Reading ServletOutputStream để String

View view = viewResolver.resolveViewName(viewName, locale); 
view.render(model, request, mockResponse); 

Để đọc kết quả, tôi đã tạo mockResponse, và tóm tắt các HttpServletResponse:

public class HttpServletResponseEx extends HttpServletResponseWrapper { 

    ServletOutputStream outputStream; 

    public HttpServletResponseEx(HttpServletResponse response) throws IOException { 
     super(response); 
     outputStream = new ServletOutputStreamEx(); 
    } 

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

    @Override 
    public PrintWriter getWriter() throws IOException { 
     return new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8")); 
    } 
} 

Và cũng của tôi ServletOutputStream, tạo Chuỗi bằng StringBuilder:

public class ServletOutputStreamEx extends ServletOutputStream { 

    StringBuilder stringBuilder; 

    public ServletOutputStreamEx() { 
     this.stringBuilder = new StringBuilder(); 
    } 

    @Override 
    public void write(int b) throws IOException { 
    } 

    @Override 
    public void write(byte b[], int off, int len) throws IOException { 
     stringBuilder.append(new String(b, "UTF-8")); 
    } 

    @Override 
    public String toString() { 
     return stringBuilder.toString(); 
    } 
} 

Với những người tôi có thể dễ dàng đọc phản ứng với phương pháp ServletOutputStreamEx.toString.

Vấn đề của tôi là phương pháp ghi không được gọi đúng thứ tự và cuối cùng chuỗi cuối cùng là hỗn hợp và không đúng thứ tự. Điều này có thể do đồng thời gây ra trong Freemarker, nhưng tôi không biết cách sửa nó.

+1

Tôi chắc chắn rằng các phương thức ghi được gọi theo thứ tự đúng bởi Freemarker trong giai đoạn hiển thị, nếu không nó sẽ tạo ra kết quả xổ số. Hơn nữa, Freemarker không được thực hiện đồng thời. Tôi nghĩ rằng vấn đề là trong việc bạn thực hiện 'ServletOutputStreamEx'. Bạn đã không ghi đè tất cả các phương thức ghi và phương thức của siêu của nó. Tôi không thấy bạn gọi 'super.write (int b)', nó sẽ đơn giản là không làm gì nếu phương thức này được gọi. – gigadot

+1

Tôi không chắc chắn vấn đề của bạn là gì, nhưng nếu bạn nhận được hai kết quả 'Chuỗi' của 'ServletOutputStreamEx.write()' được trộn lẫn với nhau. bằng cách sử dụng 'StringBuffer' thay vì' StringBuilder' sẽ sửa lỗi này - vì 'StringBuffer' được đồng bộ hoá - –

+1

Tôi không thể đồng ý, StringBuffer là một thứ không được dùng nữa (như được mô tả trong Java hiệu quả, 2nd Edition), và sử dụng StringBuilder tốt, bởi vì hầu hết thời gian một yêu cầu duy nhất (và do đó một phản ứng đơn) được xử lý bằng một luồng. –

Trả lời

4

Cảm ơn bạn đã trả lời: write(int b) không được triển khai vì không bao giờ được gọi. Vấn đề cuối cùng là mảng byte, cũng chứa chuỗi trước đó. Vì vậy, chuỗi cần phải được tạo thành String(b, off, len, "UTF-8").