• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Tim Cooke
  • Junilu Lacar
Sheriffs:
  • Paul Clapham
  • Devaka Cooray
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Frits Walraven
Bartenders:
  • Carey Brown
  • salvin francis
  • Claude Moore

Using Java Servlet to download PDF file saved in Tomcat server online to local Windows Machine  RSS feed

 
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Can't download file from tomcat server to local Windows machine.

I have called an external api to generate a PDF from my application and stored this pdf in a directory in my VPS tomcat server.
What I'm trying to do is to download the file into my local machine, but it doesn't work.
Please help..

 
Saloon Keeper
Posts: 5395
143
Android Firefox Browser Mac OS X Safari Tomcat Server VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch.

"it doesn't work" is an unhelpful error description. What happens when this code is run? Which values have all the relevant variables? Are there any exceptions? If so, post the full stack trace. In other words: TellTheDetails
 
Adam Ng
Greenhorn
Posts: 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Nothing gets downloaded and no error gets thrown.
 
Tim Moores
Saloon Keeper
Posts: 5395
143
Android Firefox Browser Mac OS X Safari Tomcat Server VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Which values have all the relevant variables?


Also: which path is taken through the code? Which lines of code are or are not being executed? How have you tried to debug this code? Again: TellTheDetails

Note that for a download you should use a GET, not a POST as this code does.
 
Saloon Keeper
Posts: 20639
122
Android Eclipse IDE Java Linux Redhat Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You have done a Very Bad Thing.

NEVER store data in your webapp directory. First, because in a "pure" J2Ee environment, the webapp is a WAR file, and therefore it's read-only (the only way in Java to update a WAR is to create a new WAR).

Secondly, because even allowing for the fact that Tomcat explodes WARs by default, thus giving "real" directories, storing data in a WAR can cause it go get lost when the app is updated (or in some other cases as well).

ALWAYS store your data outside both the WAR and outside the Tomcat server as well. For temporary files, you should use the java.io.file temporary file support features. For non-temporary files, use an absolute external file directory path. If you don't want to hard-code such a path into the webapp, you can supply it via the J2EE environmental interface and retrieve it using JNDI.

You should not have any OS-dependent code in your webapp. A properly-coded webapp is "write once/run anywhere". Mostly. Portability issues in webapps are more usually because of what server you're using, not which OS you're running. There are features in java.io.File that can prevent you from having to worry about things like slashes versus backslashes and can join and break apart path components.

To create and download a PDF from a webapp, you need two functionalities. First, create the PDF in a temporary directory. Maybe you could create it in RAM, depending on what library you're using, but it's going to eat a lot of working storage in most cases if you do. Then simply copy the PDF file from the temporary directory to the servlet response outputstream. For best results, you should include the content-length (some web clients were famous for not working if you didn't), and the content-type should be application/x-pdf.

Please note that Tomcat is not a file server. It can never write a file to a client, only send a response to a client's HTTP request. The web client cannot open a file from the Tomcat server, it can only request that Tomcat should send a response to it containing the PDF contents as part of the response output. The web client, seeing the content-type is not text/html will not attempt to display it, but will check its built-in MIME options and depending on their settings for application/x-pdf will either attempt to open and display it or open a "file save" dialog, which the web client will use to create a file and store the PDF payload into.
 
Bartender
Posts: 1661
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You certainly can create a file on your desktop or anywhere you have access to using a Servlet. Below, I'm just writing values received in the Servlet Request to a file (and to the Response):

Try a simpler example, first:



---

Then, you can call your Servlet using POSTMAN and a POST call (or you could have doGet() call doPost() for testing), with output:

File output:
data, id, path
the data, the id, the path
 
Tim Holloway
Saloon Keeper
Posts: 20639
122
Android Eclipse IDE Java Linux Redhat Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Mike London wrote:You certainly can create a file on your desktop or anywhere you have access to using a Servlet. Below, I'm just writing values received in the Servlet Request to a file (and to the Response):



I'm afraid I totally didn't understand that. Who is "you"? The Tomcat server? My server machines don't even run GUIs, much less have desktops. The client? Servlets cannot write to other people's desktops. As I said earlier, a WEB server is NOT a FILE server. It would be a horrible security problem if my Tomcat servers could just go updating other people's desktops.

The only way this works is for a client (e.g., web browser) makes an HTTP request to a server - and it doesn't matter if that server is running servlets or even running Java - and the server returns an application/x-pdf stream. What that client should do with that data stream is generally set by MIME preferences for that client program. It may or may not present a File Save dialog or simply launch a PDF viewer directly.

What the servlet can write to is any place that the userid that the Tomcat server is running under can write to. That is, files on the actual Tomcat host machine (NOT the client!) including authorized network file shares

But, again, although the Tomcat server can generally write to its own directories and directories that WARs have been exploded into, that's one place where "could" and "should" are very different things.
 
Mike London
Bartender
Posts: 1661
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I wasn't disagreeing with your posting at all.

I just created a simple Servlet that creates a file as output.

Thanks,
 
Sheriff
Posts: 24366
55
Eclipse IDE Firefox Browser MySQL Database
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, aside from Tim's advice, let's see what you're actually doing in that code.



I see this line of code near the end, along with some (rather flawed) that looks like it intends to copy the file to the servlet response. It's a good first step, but it would help if you followed up with some code which writes to that output stream.

As for the flaws:



First of all you're assuming that the file size is small enough to fit into a byte variable. Since it's a PDF that's very likely to be true, so not too much of a problem. And anyway if you read a file bigger than that into memory you could well go OutOfMemoryError.

But second you're assuming that the bstr.read method will read the whole file into that array. That isn't guaranteed by the read() method and you'll get a truncated file as your download if it doesn't happen.

People used to write code which copied the bytes over using a relatively small array, copying one array-full of bytes at a time. (Or google for it and copy it off the web.) But that code had plenty of scope for flaws too; nowadays there's a Files.copy(Path, OutputStream) method in the java.nio.file package which takes care of all the details for you and works reliably.
 
It's a pleasure to see superheros taking such an interest in science. And this tiny ad:
Create Edit Print & Convert PDF Using Free API with Java
https://coderanch.com/wiki/703735/Create-Convert-PDF-Free-Spire
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!