This is the situation:
We have some binary files (PDFs, PPTs, ZIPz, etc.) stored in a server different from where our application is. We need to make them available for the users in our app. But files have extremely sensitive information that can not be read by anyone else but the user that has access to them which means that we need to validate the user that is trying to access the file before s/he can download it.
This is how we solve it:
- We get the file from the remote server, store it in a non public location.
- We read the file into a byte array, then we delete the file.
- We write the file through a JSP using the response’s outputStream. (We can not flush it through the servlet because we are using a proprietary MVC that we cannot modify, so all outputs are JSPs, so we get a java.lang.IllegalStateException but it works).
I’m concerned by 3 aspects of this solution; The file size will impact the heap size dramatically, the file size is limited to a max of byte[Integer.MAXSIZE] and finally we get an java.lang.IllegalStateException every time someone downloads a file because we are calling the response.getOutputStream(), so our log is growing a lot.(We can not flush it through the servlet because we are using a proprietary MVC that we cannot modify or extend)
I’m pretty sure there is a more elegant way to do this.
Any ideas?
Indeed just don’t store it locally. You’re getting it as an
InputStreamfrom somewhere else, right? Just write it immediately to theOutputStreamof the response. Then there’s no need to get hold of it in Java’s memory nor local disk file system. This means that you should put the logic for obtaining the file in the JSP file. Bad, bad, but since this is apparently a proprietary framework…Then the
IllegalStateExceptionpart, you just need to ensure that there is no whitespace outside the scriptlets, including newlines. It will all implicitly be written throughresponse.getWriter(), but this isn’t possible because you already calledresponse.getOutputStream()for the file. Remove everything outside<% %>in the JSP. Glue if necessary multiple scriptlets together. Don’t forget to remove the last newline at the bottom of the file.E.g. not so:
But more so:
Good luck with this webapp.