Estoy tratando de leer el resultado de FreemarkerView renderizado:lectura ServletOutputStream a cadena
View view = viewResolver.resolveViewName(viewName, locale);
view.render(model, request, mockResponse);
Para leer el resultado, he creado mockResponse
, que encapsula el 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"));
}
}
Y también mi ServletOutputStream, que construye la cadena usando 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();
}
}
Con ésos puedo leer fácilmente la respuesta con el método ServletOutputStreamEx.toString
.
Mi problema es que el método de escritura no se llama en el orden correcto y al final la secuencia final es mixto y no en el orden correcto. Esto es probablemente causado por la concurrencia en Freemarker, pero no tengo idea de cómo solucionarlo.
Estoy seguro de que Freemarker llamará a los métodos de escritura en el orden correcto durante la etapa de reproducción, de lo contrario generaría un resultado confuso. Además, Freemarker no se ejecuta al mismo tiempo. Creo que el problema está en su implementación de 'ServletOutputStreamEx'. No ha anulado todos los métodos de escritura y sus métodos súper. No veo que llame a 'super.write (int b)', simplemente no hará nada si se llama a este método. – gigadot
No estoy seguro de cuál es tu problema, pero si obtienes dos 'cadenas' como resultado de llamadas' ServletOutputStreamEx.write() 'mezcladas. usar 'StringBuffer' en lugar de' StringBuilder' arreglaría esto -despuesto a que 'StringBuffer' está sincronizado- –
No estoy de acuerdo, StringBuffer es algo que debería estar en desuso (como se describe en Effective Java, 2nd Edition), y usar un StringBuilder es bueno, porque la mayoría de las veces una sola solicitud (y, por lo tanto, una respuesta única) se maneja con un hilo. –