开发者

How to clear the screen output of a Java HttpServletResponse

I'm wri开发者_运维知识库ting to the browser window using servletResponse.getWriter().write(String).

But how do I clear the text which was written previously by some other similar write call?


The short answer is, you cannot -- once the browser receives the response, there is no way to take it back. (Unless there is some way to abnormally stop a HTTP response to cause the client to reload the page, or something to that extent.)

Probably the last place a response can be "cleared" in a sense, is using the ServletResponse.reset method, which according to the Servlet Specification, will reset the buffer of the servlet's response.

However, this method also seems to have a catch, as it will only work if the buffer has not been committed (i.e. sent to the client) by the ServletOutputStream's flush method.


You cannot. The best thing is to write to a buffer (StringWriter / StringBuilder) and then you can replace the written data any time. Only when you know for sure what is the response you can write the buffer's content to the response.

In the same matter, and reason to write the response this way and not to use some view technology for your output such as JSP, Velocity, FreeMarker, etc.?


If you have an immediate problem that you need to solve quickly, you could work around this design problem by increasing the size of the response buffer - you'll have to read your application server's docs to see if this is possible. However, this solution will not scale as you'll soon run into out-of-memory issues if you site traffic peaks.

No view technology will protect you from this issue. You should design your application to figure out what you're going to show the user before you start writing the response. That means doing all your DB access and business logic ahead of time. This is a common issue I've seen with convoluted system designs that use proxy objects that lazily access the database. E.g. ORM with Entity relationships are bad news if accessed from your view layer! There's not much you can do about an exception that happens 3/4 of the way into a rendered page.

Thinking about it, there might be some way to inject a page redirect via AJAX. Anyone ever heard of a solution like that?

Good luck with re-architecting your design!


I know the post is pretty old, but just thought of sharing my views on this.

I suppose you could actually use a Filter and a ServletResponseWrapper to wrap the response and pass it along the chain.

That is, You can have an output stream in the wrapper class and write to it instead of writing into the original response's output stream... you can clear the wrapper's output stream as and when you please and you can finally write to the original response's output stream when you are done with your processing.

For example,

public class MyResponseWrapper extends HttpServletResponseWrapper {
    protected ByteArrayOutputStream baos = null;
    protected ServletOutputStream stream = null;
    protected PrintWriter writer = null;
    protected HttpServletResponse origResponse = null;

    public MyResponseWrapper( HttpServletResponse response ) {
      super( response );
      origResponse = response;
    }


    public ServletOutputStream getOutputStream()
      throws IOException {
      if( writer != null ) {
        throw new IllegalStateException( "getWriter() has already been " +
                                   "called for this response" );
      }

      if( stream == null ) {
        baos = new ByteArrayOutputStream();
        stream = new MyServletStream(baos);
      }

      return stream;
    }

  public PrintWriter getWriter()
    throws IOException {
      if( writer != null ) {
        return writer;
      }

      if( stream != null ) {
        throw new IllegalStateException( "getOutputStream() has already " +
                                   "been called for this response" );
      }

      baos = new ByteArrayOutputStream();
      stream = new MyServletStream(baos);
      writer = new PrintWriter( stream );

      return writer;
    }

    public void commitToResponse() {
      origResponse.getOutputStream().write(baos.toByteArray());
      origResponse.flush();
    }

    private static class MyServletStream extends ServletOutputStream {
       ByteArrayOutputStream baos;

       MyServletStream(ByteArrayOutputStream baos) {
         this.baos = baos;
       }

       public void write(int param) throws IOException {
         baos.write(param);
       }
    }
    //other methods you want to implement
  }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜