简体   繁体   中英

Problem occured when using OutputStream & (DataOutPutStream or PrintWriter)

I wrote a simple server using java socket programming and intended to make that offered 2 files for download and display some html response when the download finished. What I did is use PrintWriter.print or DataOutPutStream.writeBytes to send the string including html tags and response string to the browser, then use OutputStream.write to send the file requested. The URL I typed in the browser was like 127.0.0.1/test1.zip, relevant code fragments as following:

pout.print("<html>");
pout.print("<head>");
pout.print("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1/\">");
pout.print("<title>Response</title>");
pout.print("</head>");
pout.print("<body>");
pout.print(createResponseHeader(200, fileTypeCode));
pout.print("</body>");
pout.print("</html>");
pout.print(createResponseHeader(200, fileTypeCode));
pout.flush();

byte[] buffer = new byte[client.getSendBufferSize()];
int bytesRead = 0;
System.out.println("Sending...");
while((bytesRead = requestedFile.read(buffer))>-1)
{
    out.write(buffer,0,bytesRead);
}

The pout is a PrintWriter while out is OutputStream. The problem is when I try to use 127.0.0.1/test2.zip to download the file, it doesn't let me download, instead, print out the response string and a lot of non-sense character in the browser, eg

HTTP/1.0 200 OK

Connection: close

Server: COMP5116 Assignment Server v0

Content-Type: application/x-zip-compressed

PK‹â:Lmá^ЛàÍ test2.wmvì[y<”Ûÿ?3ÃØ—Ab¸eeË'5K"»±f_B*à Å*YÛ•¥M5h±¯u[(\·(-÷F)ß3ÏɽݺÝ×ýýñ{Íg^ÏûyžóYÏçœçyÎç¼P'>™îÝ+½Žö6A€;;ýmüH»êt©k]R#*€.G‰µÅRÏøÍLÔóZ; ´£åÑvP¹æª@õó”æÇ„‹&‡ëî9q‰Ú>LkÇÈyÖ2qãÌÆ(ãDŸã©ïÍš]Ð4iIJ0Àª3]B€ðÀ¸CôÁ`ä è1ü½¤Ã¬$ pBi

I believe it simply display the zip file as string with the response header all together. It seems once the PrintWriter is used before the code of sending the file, the whole output stream is used for sending string instead of bytes. However, if I put the part of code of sending the response AFTER the code of sending file, the download works properly but no any response message print out in the browser, just a blank page.

You've to remove your HTML code from here and send only the binary data. You can't mix them in a single servlet.

To achieve what you want to do is not easy.

I would start the download with some JavaScript code in the page, then the page will poll with Ajax for a server side servlet that will know if the download is completed for that particular session. In fact there is no download completed event in JavaScript.

To have this information the download servlet will update the session with a flag when download is completed.

When your Ajax call will return that the download is completed, you can change the text in the page or redirect to a new page.

Edit : Alternatively, if you can change your requirements, it will be much easier to show all messages that you have to show just before the download, and put target="_blank" in the download link so your page is not lost by clicking on the link.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM