This week's giveaway is in the EJB and other Java EE Technologies forum. We're giving away four copies of EJB 3 in Action and have Debu Panda, Reza Rahman, Ryan Cuprak, and Michael Remijan on-line! See this thread for details.
I have been struggling with this weird problem. I pull files from a database saved in binary form (e.g. pdf, images, docs, etc) and stream them to the client's browser using ServletOutputStream. It works like a charm when I test it in a Tomcat standalone with Java Struts from the localhost. No problem. However, files larger than about 60K are truncated when they are streamed back from a remote production server that has the exact same setup as my test environment locally. I tried messing with buffers, flushing, closing, even padding the end of the files. All work well from localhost, but files get truncated (resulting in corrupted files) from the online server. I checked and the files are saved correctly in the database (they have the right length), but when they are streamed, a chunk is chopped off the end. If I use a hex editor to "glue" the chopped bytes back to the end of the corrupted files, they open fine and they are repaired. I suspect some sort of asynchronous action in buffering and sending bytes over the net, but I don't know how to fix it. I would appreciate your help or any good idea! The part of my code where I send the data to the ServletOutputStream is listed below.
Good idea, but in fact, I tried to set the buffer because the file was corrupted without it.
Joined: Jun 05, 2008
I found that when I browse from the web server directly, files are still truncated. I did this via domain name resolution, not localhost loopback (which would require stopping the server and reconfiguring). Besides distance from the server the other possibility could be using SuSe Linux Enterprise 10 which runs Tomcat and Java on the server, while the test box, where I see no problem is a Win XP environment. Could it be Tomcat environment settings? How about Java settings?
Joined: Jun 05, 2008
OK, I got it. For some reason, when I write files to the ServletOutputStream as a ByteArrayOutputStream, it does not work from a remote server (truncates the file). However if I write a bytearray directly to the SOS, it works perfectly in all environments.
This could be a good solution for others with the same problem.
Then I expect that means that some part of your code which you didn't show is causing the problem. I don't understand why you need a ByteArrayOutputStream to copy data from a file to the servlet's output stream, but my guess is that you didn't fill the ByteArrayOutputStream correctly.