Я пытаюсь прочитать результат рендеринга FreemarkerView:
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"));
}
}
А также мой ServletOutputStream, который строит String с помощью 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();
}
}
С ними я могу легко прочитать ответ с помощью метода ServletOutputStreamEx.toString
.
Моя проблема в том, что метод записи вызывается не в правильном порядке, и в конце конечная строка оказывается перемешанной и не в правильном порядке. Вероятно, это вызвано параллелизмом в Freemarker, но я понятия не имею, как это исправить.
ServletOutputStreamEx
. Вы не переопределили все методы записи и суперметоды. Я не вижу, чтобы вы вызывалиsuper.write(int b)
, он просто ничего не сделает, если этот метод будет вызван. - person gigadot   schedule 11.03.2012String
в результатеServletOutputStreamEx.write()
вызовов, смешанных вместе. использованиеStringBuffer
вместоStringBuilder
исправит это, посколькуStringBuffer
синхронизировано- - person Ahmad Y. Saleh   schedule 11.03.2012Environment
. ОбъектWriter
, куда FreeMarker записывает выходные данные, является частью объектаEnvironment
и предоставляется вызывающей стороной FreeMarker. Таким образом, в принципе можно передать один и тот же объектWriter
FreeMarker в несколько потоков, но я не могу себе представить, зачем это делать. - person ddekany   schedule 12.03.2012