By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,347 Members | 2,113 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,347 IT Pros & Developers. It's quick & easy.

Need help with HttpServletResponse.flushBuffer( )

P: n/a
Greetings-

I have a web application that has a form that triggers a server process that
I would like to provide a "Searching..." page for.

My strategy was to send the browser the "top half" of a web page, including
an animated "Searching..." gif. I write the contents of this page to the
HttpServletResponse output, and then flush the buffer (which I had thought
would cause the bytes written thus-far to make their way to the client). I
then do the time-intensive operation on the server side (simulated below
with a 10 second Thread sleep), followed by streaming to the output the
"bottom half" of the web page, including a META refresh that would cause the
client to redirect to a "Results" page.

Unfortunately, what actually happens is that the client (IE 6) waits until
the entire page is sent, briefly shows the "Searching..." image, and then
immediately redirects to the "Results".

I have tried explicitely setting the bufferSize of the response to be
smaller than the length of the "top half", but this didn't seem to alter the
behavior.

I am serving from Tomcat 5.0.16, which I'm beginning to suspect might be a
culprit here, somehow micro-managing the buffer until the servlet returns
from processRequest( ), thus thwarting my flushBuffer( ) strategy.

Below is the processRequest( ) method of my Servlet. Below that are the two
halves of the web page. I have removed some domain-specific names and
modified slightly for readability.

Thanks in advance for any insight!
-Eric

void processRequest(HttpServletRequest request, HttpServletResponse
response) throws ServletException, IOException
{
response.setHeader("Expires", "Mon, 26 Jul 1997 05:00:00 GMT");
response.setHeader("Cache-Control", "no-cache, must-revalidate");
response.setHeader("Pragma", "no-cache");

BufferedInputStream inStreamA = null;
BufferedInputStream inStreamB = null;
BufferedOutputStream outStream = null;

try
{
response.setContentType("text/html");
outStream = new BufferedOutputStream(response.getOutputStream());

File fileTop = new File(FILE_TOP);
long halfFileSize= fileTop.length()/2;
response.setBufferSize(((int)halfFileSize));

inStreamA = new BufferedInputStream(new FileInputStream(fileTop));

int byteRead = inStreamA.read();
while (byteRead != -1)
{
outStream.write(byteRead);
byteRead = inStreamA.read();
}

outStream.flush();
response.flushBuffer();

try { Thread.sleep(10000); }
catch (InterruptedException ignored) { }

inStreamB = new BufferedInputStream(new
FileInputStream(FILE_BOTTOM));

byteRead = inStreamB.read();
while (byteRead != -1)
{
outStream.write(byteRead);
byteRead = inStreamB.read();
}

outStream.flush();
response.flushBuffer();

}
catch(Exception e)
{
log.log("problem : " + e);
}
finally
{
if (inStreamA != null)
{
inStreamA.close();
}
if (inStreamB != null)
{
inStreamB.close();
}

}

}
==========TOP FILE============

<html>
<head>
<title>Searching</title>
</head>

<body>

<img src="images/searching.gif" border="0">

==============================

==========BOTTOM FILE=========
<META http-equiv=refresh content="0;URL=results.html">

</body>
</html>

==============================
Jul 17 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
I should add that I'm using Apache 1.3.29 with mod_jk.

"Eric West" <ew*****@SPAMfederalresearch.com> wrote in message
news:tr********************@giganews.com...
Greetings-

I have a web application that has a form that triggers a server process that I would like to provide a "Searching..." page for.


<snipped>
Jul 17 '05 #2

P: n/a

"Eric West" <ew*****@SPAMfederalresearch.com> wrote in message
news:h8********************@giganews.com...
I should add that I'm using Apache 1.3.29 with mod_jk.

"Eric West" <ew*****@SPAMfederalresearch.com> wrote in message
news:tr********************@giganews.com...
Greetings-

I have a web application that has a form that triggers a server process

that
I would like to provide a "Searching..." page for.


<snipped>


Why do you expect the browser to render a partially received HTML page?

A more solid approach would be to send a complete "searching..." page first
along with an onload action that does an immediate redirect to an URL that
triggers the actual thing and returns the result.

Silvio Bierman
Jul 17 '05 #3

P: n/a
I have a web application that has a form that triggers a server
process that
I would like to provide a "Searching..." page for. <snipped>

Why do you expect the browser to render a partially received HTML page?
First Silvio, thanks for your reply.

I expect the browser to render a partially received page because a browser
seems capable of it. That's the behavior I was hoping to trigger with the
call to HttpServletResponse.flushBuffer( ). A browser (obviously) has no
problem *rendering* snippets of pages. I think what you are suggesting is
that a browser won't begin to render anything until the server has
completely finished writing to the Response. In this case, I'd really like
somebody to explain what flushBuffer( ) is supposed to be for.
A more solid approach would be to send a complete "searching..." page first along with an onload action that does an immediate redirect to an URL that
triggers the actual thing and returns the result.


That is exactly what I am doing, due to the fact that I can't get the
flushBuffer( ) working. The downside to this approach is that as soon as the
"Searching..." page starts the redirect to the server, the gif stops being
animated, and stays frozen until the result is ready. It's ok, but not at
all optimal. This seems to be browser-specific behavior. My co-workers
Firebird browser shows the animation the entire time. Unfortunately, windows
IE 6 freezes the gif, and this is the browser that I need to support.

-Eric
Jul 17 '05 #4

P: n/a
"Eric West" <ew*****@SPAMfederalresearch.com> wrote in message
news:B_********************@giganews.com...

First Silvio, thanks for your reply.

I expect the browser to render a partially received page because a browser
seems capable of it. That's the behavior I was hoping to trigger with the
call to HttpServletResponse.flushBuffer( ). A browser (obviously) has no
problem *rendering* snippets of pages. I think what you are suggesting is
that a browser won't begin to render anything until the server has
completely finished writing to the Response. In this case, I'd really like
somebody to explain what flushBuffer( ) is supposed to be for.
A more solid approach would be to send a complete "searching..." page first
along with an onload action that does an immediate redirect to an URL that triggers the actual thing and returns the result.


That is exactly what I am doing, due to the fact that I can't get the
flushBuffer( ) working. The downside to this approach is that as soon as

the "Searching..." page starts the redirect to the server, the gif stops being
animated, and stays frozen until the result is ready. It's ok, but not at
all optimal. This seems to be browser-specific behavior. My co-workers
Firebird browser shows the animation the entire time. Unfortunately, windows IE 6 freezes the gif, and this is the browser that I need to support.

-Eric


Hello Eric,

Obviously browser could render partial HTML (up to some level) but the fact
is that there seems to be no agreed upon reason to so you can never be sure
the browser will do that. There has been some talk in the past about browser
implementing server-push facilities (look at O'Reilly's servlet book) but
that never quite make it into the mainstream.
If you look at the HTTP1.1 protocol you can see why a HTTP server would want
to flush its buffers, a connection can remain open to accomodate multiple
HTTP requests.

Back to your problem: I missed the part about the animated GIF so I can
understand you dislike the solution (which you already found). You can solve
this in wo ways:

You could start the time-consuming server action as soon as the first
request (that returns the "working..." page) in a separate thread and keep
returning the working-page while it is not finished (with some delayed
refresh of X seconds which can be easily done with a HTTP header) and when
the request comes in after the thread has finished you send the actual
result. That will keep your animated gif active.

The other way would be by using a scheme like XMLHTTP. Your working-page
does not perform a refresh but instead does a JS-level HTTP request that
gets the actual result. From the JS you could modify the page to show that
result. For examples look at http://jibbering.com/2002/4/httprequest.html.
This technique offers very advanced possibilities which go a lot further
than what you need here. Supported in IE and Mozilla/Netscape. Don't know
about other browsers though. An alternative for XMLHTTP could always be an
invisible applet or an invisible IFRAME.

Hope this helps,

Silvio Bierman
Jul 17 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.