Results 1 to 5 of 5
- 08-18-2009, 03:17 PM #1
Member
- Join Date
- Aug 2009
- Posts
- 1
- Rep Power
- 0
How to get content from HttpServletResponse
Hi All
I have written a filter on top of a Servlet. After doFilter() method, I want to get the content from the response object and save it inside cache. The content in the response is set by PrintWriter.println(xmlContent).
Here is the code snippet:
Please look at this line in the code snippet:Java Code:public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { if (debug) { log("ServletContainerFilter:doFilter()"); } RequestWrapper wrappedRequest = new RequestWrapper((HttpServletRequest) request); ResponseWrapper wrappedResponse = new ResponseWrapper((HttpServletResponse) response); if (!doBeforeProcessing(wrappedRequest, wrappedResponse)) { Throwable problem = null; try { chain.doFilter(wrappedRequest, wrappedResponse); doAfterProcessing(wrappedRequest, wrappedResponse); } catch (Throwable t) { // If an exception is thrown somewhere down the filter chain, // we still want to execute our after processing, and then // rethrow the problem after that. problem = t; t.printStackTrace(); // If there was a problem, we want to rethrow it if it is // a known type, otherwise log it. if (problem != null) { if (problem instanceof ServletException) { throw (ServletException) problem; } if (problem instanceof IOException) { throw (IOException) problem; } sendProcessingError(problem, response); } } } return; } private void doAfterProcessing(HttpServletRequestWrapper request, HttpServletResponseWrapper response) throws IOException, ServletException { if (debug) { log("ServletContainerFilter:DoAfterProcessing"); } CacheManager cacheManager = CacheManager.getInstance(); String xmlContent = response.getContent(); System.out.println("XML Content just before saving in cache:\n" + xmlContent); cacheManager.save(getAbsoluteUrl(request), xmlContent); }
String xmlContent = response.getContent();
Right now, getContent() method is not available in HttpServletResponseWrapper class. But, I want a work around for this.
Thanks for showing your interest in this post.
Regards,
Sumved Shami
- 09-27-2009, 04:20 AM #2
Right, because the response will want to write things to its output stream as the stuff happens, the default HttpServletResponseWrapper doesn't do this. What I usually do for these situations is create my own response wrapper that extends the HttpServletResponseWrapper. and override the getOutputStream (and getWriter()) methods, where they instead write to my own output stream in the filter. And after a while, I made this generic one that is reuseable couple of classes.
Where I needed to wrap the ServletOutputStream (its an abstract class in servlet api),, in order to allow me to pass in any arbitrary OutputStream kind of class.Java Code:import java.io.IOException; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.lang.reflect.Constructor; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; /** * A response wrapper to be used when we want our own custom servlet output stream. * */ public class OutputStreamResponseWrapper extends HttpServletResponseWrapper { protected HttpServletResponse origResponse = null; protected OutputStream realOutputStream = null; protected ServletOutputStream stream = null; protected PrintWriter writer = null; Class<? extends OutputStream> outputStreamClass; public OutputStreamResponseWrapper(HttpServletResponse response, Class<? extends OutputStream> outputStreamClass) { super(response); origResponse = response; this.outputStreamClass = outputStreamClass; } public ServletOutputStream createOutputStream() throws IOException { try { Constructor<?> c = outputStreamClass.getConstructor(new Class[] {HttpServletResponse.class}); realOutputStream = (OutputStream) c.newInstance(origResponse); return new ServletOutputStreamWrapper(realOutputStream); } catch (Exception ex) { throw new IOException("Unable to construct servlet output stream: " + ex.getMessage(), ex); } } public void finishResponse() { try { if (writer != null) { writer.close(); } else { if (stream != null) { stream.close(); } } } catch (IOException e) {} } @Override public void flushBuffer() throws IOException { stream.flush(); } @Override public ServletOutputStream getOutputStream() throws IOException { if (writer != null) { throw new IllegalStateException("getOutputStream() has already been called!"); } if (stream == null) { stream = createOutputStream(); } return stream; } @Override public PrintWriter getWriter() throws IOException { if (writer != null) { return (writer); } if (stream != null) { throw new IllegalStateException("getOutputStream() has already been called!"); } stream = createOutputStream(); writer = new PrintWriter(new OutputStreamWriter(stream, "UTF-8")); return (writer); } @Override public void setContentLength(int length) {} /** * Gets the underlying instance of the output stream. * @return */ public OutputStream getRealOutputStream() { return realOutputStream; } }
So in your case, you would invoke this with something like :Java Code:import java.io.IOException; import java.io.OutputStream; import javax.servlet.ServletOutputStream; /** * A wrapper to provide a concrete implementation of the servlet output stream, so we can wrap other streams. * Such as in a filter wrapping a servlet response. * @author thein * */ public class ServletOutputStreamWrapper extends ServletOutputStream { OutputStream _out; boolean closed = false; public ServletOutputStreamWrapper(OutputStream realStream) { this._out = realStream; } @Override public void close() throws IOException { if (closed) { throw new IOException("This output stream has already been closed"); } _out.flush(); _out.close(); closed = true; } @Override public void flush() throws IOException { if (closed) { throw new IOException("Cannot flush a closed output stream"); } _out.flush(); } @Override public void write(int b) throws IOException { if (closed) { throw new IOException("Cannot write to a closed output stream"); } _out.write((byte) b); } @Override public void write(byte b[]) throws IOException { write(b, 0, b.length); } @Override public void write(byte b[], int off, int len) throws IOException { // System.out.println("writing..."); if (closed) { throw new IOException("Cannot write to a closed output stream"); } _out.write(b, off, len); } }
where here I just used a ByteArrayOutputStream as the buffer to capture the stuff the servlet generated.Java Code:public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { OutputStreamResponseWrapper wrappedResponse = new OutputStreamResponseWrapper((HttpServletResponse) response, ByteArrayOutputStream.class); chain.doFilter(request, wrappedResponse); ByteArrayOutputStream baos = (ByteArrayOutputStream) wrappedResponse.getRealOutputStream(); // and make use of this String content = baos.toString();
Note this only really works if the content generated from the servlet is relatively small.
and because the filter here has intercepted the entire output from the servlet it, we need to write the content (or the eventual modified by this filter post processing content) - out to the original response output stream right.Last edited by travishein; 09-27-2009 at 04:24 AM.
- 02-24-2010, 04:30 PM #3
Member
- Join Date
- Feb 2010
- Posts
- 1
- Rep Power
- 0
thx for this solution, but I have a problem with that code:
ByteArrayOutputStream has no construcotor for HttpServletResponse or ServletOutputStream
Java Code:new ByteArrayOutputStream(os); // is not working
- 08-28-2011, 10:45 PM #4
Member
- Join Date
- Aug 2011
- Posts
- 1
- Rep Power
- 0
It's not working for me...
Throws an exception from
java.io.IOException: Unable to construct servlet output stream: java.io.ByteArrayOutputStream.<init>(javax.servlet .http.HttpServletResponse)
followed by
Caused by: java.lang.NoSuchMethodException: java.io.ByteArrayOutputStream.<init>(javax.servlet .http.HttpServletResponse)
at java.lang.Class.getConstructor0(Class.java:2706)
at java.lang.Class.getConstructor(Class.java:1657)
at mynamespace.OutputStreamResponseWrapper.createOutp utStream(OutputStreamResponseWrapper.java:42)
- 02-02-2012, 04:58 AM #5
Member
- Join Date
- Nov 2010
- Posts
- 44
- Rep Power
- 0
Re: How to get content from HttpServletResponse
If i understand correctly, objective is not to send a HttpServletResponse or ServletOutputStream but a generic OutputStream to the constructor for your implementation of the HttpServletResponseWrapper. I could be wrong, but that is how i followed the reply to OP's post from TravisHein.
Thanks.
Similar Threads
-
Content type for MS files "content/unknown" with URLConnection
By serjant in forum NetworkingReplies: 2Last Post: 05-30-2009, 10:42 AM -
Can not see the content of the url
By neeraj.singh in forum Java 2DReplies: 0Last Post: 02-17-2009, 01:44 PM -
help with button content
By yahyaaa in forum New To JavaReplies: 4Last Post: 09-20-2008, 10:53 PM -
Two content panes in one GUI?
By Leprechaun in forum New To JavaReplies: 1Last Post: 01-31-2008, 04:02 AM


LinkBack URL
About LinkBacks
Reply With Quote

Bookmarks