也不是没可能,http有一种技术:服务器推技术 Server Push可以返回多个response[每隔一定时间返回一个](不过好像IE不支持,我试过,但是Mozilla支持) 具体参见Java Serverlet programing(2nd)6.4import java.io.*; import javax.servlet.*; import javax.servlet.http.*;import com.oreilly.servlet.MultipartResponse; import com.oreilly.servlet.ServletUtils;public class Countdown extends HttpServlet { static final String LAUNCH = "/images/launch.gif"; public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ServletOutputStream out = res.getOutputStream(); // some binary output // Prepare a multipart response MultipartResponse multi = new MultipartResponse(res); // First send a countdown for (int i = 10; i > 0; i--) { multi.startResponse("text/plain"); out.println(i + "..."); multi.endResponse(); try { Thread.sleep(1000); } catch (InterruptedException e) { } } // Then send the launch image multi.startResponse("image/gif"); try { ServletUtils.returnFile(req.getRealPath(LAUNCH), out); } catch (FileNotFoundException e) { throw new ServletException("Could not find file: " + e.getMessage()); } // Don't forget to end the multipart response multi.finish(); } } // Copyright (C) 1998-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>. // All rights reserved. Use of this class is limited. // Please see the LICENSE for more information.package com.oreilly.servlet;import java.io.*; import javax.servlet.*; import javax.servlet.http.*;/** * A utility class to generate <tt>multipart/x-mixed-replace</tt> responses, * the kind of responses that implement server push. Note that Microsoft * Internet Explorer does not understand this sort of response. * <p> * To use this class, first construct a new MultipartResponse * passing to its constructor the servlet's response parameter. * MultipartResponse uses the response object to fetch the * servlet's output stream and to set the response's content type. * <p> * Then, for each page of content, begin by calling <tt>startResponse()</tt> * passing in the content type for that page. Send the content for the * page by writing to the output stream as usual. A call to * <tt>endResponse()</tt> ends the page and flushes the content so the * client can see it. At this point a <tt>sleep()</tt> or other delay * can be added until the next page is ready for sending. * <p> * The call to <tt>endResponse()</tt> is optional. The * <tt>startResponse()</tt> method knows whether the last response has * been ended, and ends it itself if necessary. However, it's wise to * call <tt>endResponse()</tt> if there's to be a delay between the * time one response ends and the next begins. It lets the client display * the latest response during the time it waits for the next one. * <p> * Finally, after each response page has been sent, a call to the * <tt>finish()</tt> method finishes the multipart response and sends a * code telling the client there will be no more responses. * <p> * For example: * <blockquote><pre> * MultipartResponse multi = new MultipartResponse(res); * * multi.startResponse("text/plain"); * out.println("On your "); * multi.endResponse(); * * try { Thread.sleep(1000); } catch (InterruptedException e) { } * * multi.startResponse("text/plain"); * out.println("Get set"); * multi.endResponse(); * * try { Thread.sleep(1000); } catch (InterruptedException e) { } * * multi.startResponse("image/gif"); * ServletUtils.returnFile(req.getRealPath("/images/go.gif"), out); * * multi.finish(); * </pre></blockquote> * * @see ServletUtils * * @author <b>Jason Hunter</b>, Copyright © 1998 * @version 1.0, 98/09/18 */ public class MultipartResponse { HttpServletResponse res; ServletOutputStream out; boolean endedLastResponse = true; /** * Constructs a new MultipartResponse to send content to the given * servlet response. * * @param response the servlet response * @exception IOException if an I/O error occurs */ public MultipartResponse(HttpServletResponse response) throws IOException { // Save the response object and output stream res = response; out = res.getOutputStream(); // Set things up res.setContentType("multipart/x-mixed-replace;boundary=End"); out.println(); out.println("--End"); } /** * Begins a single response with the specified content type. * This method knows whether the last response has been ended, and * ends it itself if necessary. * * @param contentType the content type of this response part * @exception IOException if an I/O error occurs */ public void startResponse(String contentType) throws IOException { // End the last response if necessary if (!endedLastResponse) { endResponse(); } // Start the next one out.println("Content-type: " + contentType); out.println(); endedLastResponse = false; } /** * Ends a single response. Flushes the output. * * @exception IOException if an I/O error occurs */ public void endResponse() throws IOException { // End the last response, and flush so the client sees the content out.println(); out.println("--End"); out.flush(); endedLastResponse = true; } /** * Finishes the multipart response. Sends a code telling the client * there will be no more responses and flushes the output. * * @exception IOException if an I/O error occurs */ public void finish() throws IOException { out.println("--End--"); out.flush(); } }
具体参见Java Serverlet programing(2nd)6.4import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;import com.oreilly.servlet.MultipartResponse;
import com.oreilly.servlet.ServletUtils;public class Countdown extends HttpServlet { static final String LAUNCH = "/images/launch.gif"; public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
ServletOutputStream out = res.getOutputStream(); // some binary output // Prepare a multipart response
MultipartResponse multi = new MultipartResponse(res); // First send a countdown
for (int i = 10; i > 0; i--) {
multi.startResponse("text/plain");
out.println(i + "...");
multi.endResponse();
try { Thread.sleep(1000); } catch (InterruptedException e) { }
} // Then send the launch image
multi.startResponse("image/gif");
try {
ServletUtils.returnFile(req.getRealPath(LAUNCH), out);
}
catch (FileNotFoundException e) {
throw new ServletException("Could not find file: " + e.getMessage());
} // Don't forget to end the multipart response
multi.finish();
}
}
// Copyright (C) 1998-2001 by Jason Hunter <jhunter_AT_acm_DOT_org>.
// All rights reserved. Use of this class is limited.
// Please see the LICENSE for more information.package com.oreilly.servlet;import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;/**
* A utility class to generate <tt>multipart/x-mixed-replace</tt> responses,
* the kind of responses that implement server push. Note that Microsoft
* Internet Explorer does not understand this sort of response.
* <p>
* To use this class, first construct a new MultipartResponse
* passing to its constructor the servlet's response parameter.
* MultipartResponse uses the response object to fetch the
* servlet's output stream and to set the response's content type.
* <p>
* Then, for each page of content, begin by calling <tt>startResponse()</tt>
* passing in the content type for that page. Send the content for the
* page by writing to the output stream as usual. A call to
* <tt>endResponse()</tt> ends the page and flushes the content so the
* client can see it. At this point a <tt>sleep()</tt> or other delay
* can be added until the next page is ready for sending.
* <p>
* The call to <tt>endResponse()</tt> is optional. The
* <tt>startResponse()</tt> method knows whether the last response has
* been ended, and ends it itself if necessary. However, it's wise to
* call <tt>endResponse()</tt> if there's to be a delay between the
* time one response ends and the next begins. It lets the client display
* the latest response during the time it waits for the next one.
* <p>
* Finally, after each response page has been sent, a call to the
* <tt>finish()</tt> method finishes the multipart response and sends a
* code telling the client there will be no more responses.
* <p>
* For example:
* <blockquote><pre>
* MultipartResponse multi = new MultipartResponse(res);
*
* multi.startResponse("text/plain");
* out.println("On your ");
* multi.endResponse();
*
* try { Thread.sleep(1000); } catch (InterruptedException e) { }
*
* multi.startResponse("text/plain");
* out.println("Get set");
* multi.endResponse();
*
* try { Thread.sleep(1000); } catch (InterruptedException e) { }
*
* multi.startResponse("image/gif");
* ServletUtils.returnFile(req.getRealPath("/images/go.gif"), out);
*
* multi.finish();
* </pre></blockquote>
*
* @see ServletUtils
*
* @author <b>Jason Hunter</b>, Copyright © 1998
* @version 1.0, 98/09/18
*/
public class MultipartResponse { HttpServletResponse res;
ServletOutputStream out;
boolean endedLastResponse = true; /**
* Constructs a new MultipartResponse to send content to the given
* servlet response.
*
* @param response the servlet response
* @exception IOException if an I/O error occurs
*/
public MultipartResponse(HttpServletResponse response) throws IOException {
// Save the response object and output stream
res = response;
out = res.getOutputStream(); // Set things up
res.setContentType("multipart/x-mixed-replace;boundary=End");
out.println();
out.println("--End");
} /**
* Begins a single response with the specified content type.
* This method knows whether the last response has been ended, and
* ends it itself if necessary.
*
* @param contentType the content type of this response part
* @exception IOException if an I/O error occurs
*/
public void startResponse(String contentType) throws IOException {
// End the last response if necessary
if (!endedLastResponse) {
endResponse();
}
// Start the next one
out.println("Content-type: " + contentType);
out.println();
endedLastResponse = false;
} /**
* Ends a single response. Flushes the output.
*
* @exception IOException if an I/O error occurs
*/
public void endResponse() throws IOException {
// End the last response, and flush so the client sees the content
out.println();
out.println("--End");
out.flush();
endedLastResponse = true;
} /**
* Finishes the multipart response. Sends a code telling the client
* there will be no more responses and flushes the output.
*
* @exception IOException if an I/O error occurs
*/
public void finish() throws IOException {
out.println("--End--");
out.flush();
}
}