Como saída de um documento binário com base em um documento HTML usando filtros em Java
-
20-08-2019 - |
Pergunta
Isto pode ser um pouco confuso, mas eu tendo alguns problemas. Meu objetivo é levar um documento de entrada HTML e, em seguida, processar esse documento e usar os dados HTML para a saída de um documento de imagem. Por exemplo, um usuário irá solicitar uma URL, com alguma ação = png na querystring e, em seguida, o filtro vai ser invocado para o documento de imagem de saída URL e.
Eu tentei tudo, mas no meu ambiente (Websphere), eu sou apenas capaz de saída de um tipo. Se o tipo de entrada é text / html, então eu só posso saída de um documento de texto, eu não consigo emitir um documento binário. Por quê? Porque eu recebo uma exceção estatal ilegal cada vez.
[1/29/09 17: 59: 57: 576 EST] 00000020 SystemErr R java.lang.IllegalStateException: SRVE0209E: escritor já obtido [1/29/09 17: 59: 57: 576 EST] 00000020 SystemErr R na com.ibm.ws.webcontainer.srt.SRTServletResponse.getOutputStream (SRTServletResponse.java:505)
Eu estou usando o código pseudo não revelar tudo do meu código:
<filter>
<filter-name>TestFilter</filter-name>
<filter-class>
com.util.TestFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/index_test2.html</url-pattern>
</filter-mapping>
O código Wrapper Class é essencialmente esta:
public class ContentCaptureServletResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream contentBuffer;
private PrintWriter writer;
public PrintWriter getWriter() throws IOException {
if (writer == null) {
contentBuffer = new ByteArrayOutputStream();
writer = new PrintWriter(contentBuffer);
}
return writer;
}
public String getContent(){
try {
writer = getWriter();
} catch (IOException e) {
e.printStackTrace();
}
writer.flush();
String xhtmlContent = new String(contentBuffer.toByteArray());
System.out.println(xhtmlContent);
return xhtmlContent;
}
}
E o código do filtro é este:
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
final String renderType = request.getParameter("R");
final String renderClassName = request.getParameter("C");
if ((renderType != null) && (renderClassName != null)) {
try {
this.setFilterChain(filterChain);
response.setContentType("image/png");
PrintWriter out = response.getWriter();
// I call getWriter but not BOTH!
//response.getOutputStream();
response.getWriter();
// Build up the HTML document into a string.
CaptureResponse capContent = new CaptureResponse(response);
this.mainFilterChain.doFilter(req, );
String myString = capHtmlContent.getContent();
// What I really want to do here is output an output stream
// so I can write a binary image
processStr(myString);
response.getOutputStream();
response.write(binaryimage)
} catch (Exception e) {
e.printStackTrace();
}
// No data will be output to the user.
} else {
filterChain.doFilter(request, response);
} // End of if-else
} // End of the method.
O código funciona se eu quiser levar algum documento de texto de entrada html. Estou assumindo por causa do fluxo de PrintWriter aberto. Mas eu estou tendo problemas para ir a um formato diferente. Basicamente, porque eu não posso chamar response.getOutputStream ()
Solução
O problema parece ser que você está abrindo o Escritor resposta antes de embalar a resposta.
Parece que você deve ser capaz de fazer:
this.setFilterChain(filterChain);
CaptureContent capContent = new CaptureResponse(response);
doFilter()
process();
response.setContentType("image/png");
response.getOutputStream().write(imagedata);
Você definitivamente não pode abrir com segurança tanto o escritor eo OutputStream
Outras dicas
Eu não tenho nenhuma experiência com Websphere, mas um problema comum é que você tentar manipular o cabeçalho HTTP depois que você já se comprometeu a enviar o corpo - uma vez que o servidor começou a entregar o conteúdo, você não pode atualizar os cabeçalhos mais uma vez eles já foram enviados.
Talvez você precisa rever a documentação e exemplos. Por exemplo, eu não vejo por que você chama * response.get () sem realmente olhando para o resultado. Tem certeza que isso é necessário ou é porque você aparado seu código?
Cheers, Volker