javaperformancejsf-2jboss5.xjava-ee-5

Efficient way to expose generated files in the server?


I'm working on an application running on JBoss5.1, JEE5, JSF2, Spring3.0, Icefaces2.0, HTML and Jquery1.8.

I have a requirement of generating files on the fly for customers to download. When a file is generated, currently I'm streaming the file content as bytes on to the JSF page and using <ice:outputResource> to show a link to download. This works fine for smaller size files. As file size increases, this is not a good solution as I'm running into OutOfMemoryError issues because application JVM has to bear the burden of taking file content into the Heap and then funnel through the application.

What I would like to do is to provide the generated files as direct links so that they can be served by the web contained through HTTP. I have a constraint of doing this in a secure environment so that user is authenticated before he can generate and see the link. So, I plan to generate file into WEB-INF directory and delete file as soon as user downloads, effectively making WEB-INF to contain only files currently being viewed by customers. What I'm not sure is how JBoss server handles these files in terms of caching and if affects server performance. Also, I appreciate if there are any alternative approaches to my problem.

I believe I described my problem clearly, if not please let me know. Thanks in advance for your time and assistance.

PS - I can even create files outside WEB-INF and still make them secure.


Solution

  • P.S. you may still do some "scheduled" cleanup in case the generated file is never downloaded.

    Servlet serving the content (Answer to your comment)

    I do not see any problems with security when having external folder in your case. This external folder is only accessible in your application.

    Let's say you have a directory you generate files into (FilesRootDir) - /var/myapp/storage/tmp.

    1. Create the servlet in your webapp that knows the location of your FilesRootDir
    2. Let's say the servlet is mapped to the following url (/mywebapp/downloads/file)
    3. To keep it simple your servlet receives as a parameter the relative path to the generated file (path)
    4. Taking the above
      1. The app generates the file here /var/myapp/storage/tmp/dir1/document.csv
      2. and generates the link /mywebapp/downloads/file?path=/dir1/document.csv, so the user can download the file
    5. When the user decides to download the file, the request is handled by your servlet.
      1. The servlet receives the location of the requested file - /dir1/document.csv
      2. constructs the absolute path concatenating FilesRootDir and path parameter - /var/myapp/storage/tmp/dir1/document.csv
      3. Reads and outputs the content of the file to the user

    I believe you can apply the same security constraints to your servlet as you have it in your app, because it is a part of the application.