This may be a little confusing but I having some trouble. My goal is to take an input HTML document and then process that document and use the HTML data to output a image document. For example, a user will request a URL, with some action=png in the querystring and then the filter will get invoked for the URL and output image document.
I have tried everything but in my environment (Websphere), I am only able to output of one type. If the input type is text/html then I can only output a text document, I can’t seem to output a binary document. Why? Because I get an illegal state exception each time.
[1/29/09 17:59:57:576 EST] 00000020 SystemErr R java.lang.IllegalStateException: SRVE0209E: Writer already obtained [1/29/09 17:59:57:576 EST] 00000020 SystemErr R at com.ibm.ws.webcontainer.srt.SRTServletResponse.getOutputStream(SRTServletResponse.java:505)
I am using pseudo code not to reveal all of my code:
<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>
The Wrapper Class code is essentially this:
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; } }
And the filter code is this:
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.
The code works if I want to take some input html text document. I am assuming because of the open printwriter stream. But I am having trouble going to a different format. Basically, because I can’t call response.getOutputStream()
The issue does appear to be that you are opening the response Writer prior to wrapping the response.
It looks like you should be able to do:
You definitely cannot safely open both the Writer and the OutputStream