Reputation: 1652
I have certain images that are uploaded by users of my application, and should only be accessed by them. How can I display them as thumbnails or otherwise. I store the images in filesystem (outside webapp), and only store their path in the db.
One option that I found was to configure tomcat to expose that directory via following changes in server.xml.
<Context path="/images" docBase="/home/app/basedir" />
And then access images via
localhost:8080/context/images/b1sd2e09102.jpg
etc. (I am using UUID to generate random image names so that they can not be guessed)
However, this is not an ideal solution for me as the url (if known by other users somehow) is still public. Currently I am able to download them via following in my spring controller:
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void download(Model model, @RequestParam("id") String key, HttpServletResponse response) throws Exception {
//get item from db first based on key
Item item = dbservice.get(key);
InputStream is = new FileInputStream(item.getPath());
response.setHeader("Content-Disposition", "attachment; filename=" + item.getFileName());
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
....
}
Is there a way to render these images on the browser ?
Upvotes: 0
Views: 633
Reputation: 149165
You were not far from a complete solution. I currently use something near from your example. I simply add a Content-Length
header and use an Image/xxx
content type that I store in database when the file is uploaded. If it is not present, I use the extension of the original name.
So it could look like :
@RequestMapping(value = "/download", method = RequestMethod.GET)
public void download(Model model, @RequestParam("id") String key, HttpServletResponse response) throws Exception {
//get item from db first based on key
Item item = dbservice.get(key);
InputStream is = new FileInputStream(item.getPath());
String type = item.getFileType();
if ((type == null) || (type.isEmpty())) {
String name = item.getFileName();
if (name.length > 2) {
int i = name.substring(0, name.length() - 1).lastIndexOf(".");
if (i > 0) {
type = "Image/" + name.substr(i + 1);
}
}
}
if ((type == null) || (type.isEmpty())) {
tyoe = "application/octet-stream";
}
response.setHeader("Content-Type", type);
int l = item.getFileLength();
if (l > 0) {
response.setContentLength((int) resource.contentLength());
}
response.setStatus(HttpServletResponse.SC_OK);
IOUtils.copy(is, response.getOutputStream());
response.flushBuffer();
....
}
Now, you only have to put an image tag where you want the browser to insert the image
<img src="/appContext/dowload?id=key"/>
But you should alse put the size and eventually the type in the image tag.
Upvotes: 1