5
我想讀FreemarkerView渲染的結果:閱讀ServletOutputStream的爲String
View view = viewResolver.resolveViewName(viewName, locale);
view.render(model, request, mockResponse);
要閱讀的結果,我已經創建mockResponse
,它封裝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"));
}
}
,也是我的使用StringBuilder構建字符串的ServletOutputStream:
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();
}
}
與那些我可以很容易地閱讀方法ServletOutputStreamEx.toString
的迴應。
我的問題是寫入方法沒有按正確的順序調用,最後的字符串是混合在一起,並且順序不正確。這可能是由Freemarker的併發性引起的,但我不知道如何解決它。
我相信,在渲染階段,由Freemarker按照正確的順序調用寫入方法,否則會產生一個糟糕的結果。而且,Freemarker不會同時執行。我認爲這個問題出現在你實現ServletOutputStreamEx的時候。您尚未覆蓋所有寫入方法及其超級方法。我沒有看到你調用'super.write(int b)',如果調用此方法,它將不會執行任何操作。 – gigadot 2012-03-11 15:53:10
我不確定你的問題是什麼,但是如果你得到像'ServletOutputStreamEx.write()'調用的兩個'String'混合在一起。使用'StringBuffer'而不是'StringBuilder'將修復這個 - 因爲'StringBuffer'是同步的 - – 2012-03-11 15:54:07
我不同意,StringBuffer是應該被棄用的東西(如Effective Java,2nd Edition所述),並且使用StringBuilder好,因爲大多數情況下,單個請求(以及單個響應)都是通過線程處理的。 – 2012-03-11 16:15:27