我有一些由我的应用程序的用户上传的图像,并且只能由他们访问。如何以缩略图或其他方式显示它们。我将图像存储在文件系统(webapp外部)中,并且只将它们的路径存储在数据库中。
我发现的一个选项是配置tomcat以通过server.xml中的更改来公开该目录。
<Context path="/images" docBase="/home/app/basedir" />
然后通过
访问图像localhost:8080/context/images/b1sd2e09102.jpg
等。 (我正在使用UUID生成随机图像名称,以便无法猜到)
然而,这对我来说不是一个理想的解决方案,因为网址(如果其他用户以某种方式知道)仍然是公开的。 目前我可以通过以下弹簧控制器下载它们:
@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();
....
}
有没有办法在浏览器上呈现这些图像?
答案 0 :(得分:1)
你离完整的解决方案并不遥远。我目前在你的例子中使用了一些东西。我只需添加一个Content-Length
标头,并使用我上传文件时存储在数据库中的Image/xxx
内容类型。如果它不存在,我使用原始名称的扩展名。
所以它看起来像:
@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();
....
}
现在,您只需将图像标记放在您希望浏览器插入图像的位置
<img src="/appContext/dowload?id=key"/>
但你应该把尺寸和最终的类型放在图片标签中。