如何在Java Web应用程序中保存和检索服务器上的图像

10

在这里提出关于图片的问题(似乎比我最初预测的更加困难)。我正在开发一个基于JSF 2.0(apache myFaces)的Java Web应用程序,并希望该应用程序能够将图片上传到运行它的服务器上的目标位置。我有一个运行着mySQL数据库的Windows r2 2008服务器,但我不想将图像存储在数据库中,而是宁愿将其存储在服务器上的某个位置,然后只将路径保存为字符串在数据库中。

有人告诉我这是最好的方法,但我似乎找不到如何在服务器上保存它的示例。我将应用程序作为WAR文件在Apache Tomcat服务器上运行,所以我不知道是否必须将文件保存到服务器驱动器上的路径(例如C:\images)或项目本身中的特殊文件夹(包括java、html文件)。非常感谢任何帮助。我完全迷失了方向,一整天都在试图解决这个问题。

我用来上传图像到Java类的代码是这样的(由CodyS提供):

InputStream is = uploadedFile.getInputStream();  
byte[] buffer = new byte[(int) uploadedFile.getSize()];
is.read(buffer); 
File f = new File("C:\\temp\\" + this.patient.getPk() + ".jpeg");   
f.createNewFile();  
FileOutputStream fos = new FileOutputStream(f);  
fos.write(buffer);  //This is where I write it to the C Drive
fos.close();
is.close(); 

我不想将图片写入C盘,而是在服务器上运行程序,但是我应该将图片存储在哪里以便稍后在XHTML文件中检索和显示?希望我的需求表述清晰,如果有误,请告诉我,我会尝试用其他方式解释。


https://dev59.com/iVXTa4cB1Zd3GeqP25Jk - stacker
3个回答

13

我不打算将图片写入我的C盘,而是在服务器上运行它,但是我应该把它存储在哪里以后可以检索并在xhtml文件中显示?

这取决于您对服务器配置的控制程度。理想情况下,应该配置一个固定路径,位于Tomcat webapps文件夹之外。例如,/var/webapp/upload。您可以将此路径设置为VM参数或环境变量,这样您的webapp就可以在不需要更改代码的情况下以编程方式检索它。

例如,当作为VM参数指定-Dupload.location=/var/webapp/upload时,您可以完成上传如下:

Path folder = Paths.get(System.getProperty("upload.location"));
String filename = FilenameUtils.getBaseName(uploadedFile.getName()); 
String extension = FilenameUtils.getExtension(uploadedFile.getName());
Path file = Files.createTempFile(folder, filename + "-", "." + extension);

try (InputStream input = uploadedFile.getInputStream()) {
    Files.copy(input, file, StandardCopyOption.REPLACE_EXISTING);
}

String uploadedFileName = file.getFileName().toString();
// Now store it in DB.

关于将文件返回,最理想的方法是将上传位置作为独立的<Context>添加到Tomcat中。例如:

<Context docBase="/var/webapp/upload" path="/uploads" />

如果你有控制服务器的能力,那么可以通过以下方式直接访问: http://example.com/uploads/foo-123456.ext

如果你无法配置服务器,那么把文件存储在数据库中或者发送到Amazon S3这样的第三方主机是最好的选择。

另请参见:


这是随机的,没错。你可以自由选择。Unix风格的路径/var/webapp/upload在运行在c:\上的Windows服务器上翻译为C:\var\webapp\upload。至于指定VM参数,可以编辑Tomcat的startup.bat或Tomcat的窗口服务属性,或将其添加为JAVA_OPTS环境变量。 - BalusC
<Context docBase="C:\uploads" path="/uploads" /> 添加到 Tomcat 的 /conf/server.xml 中,并使用 <img src="/uploads/image01.jpg">。这样,Tomcat 自己的 DefaultServlet 将会提供服务。请参阅我的答案底部的“可靠数据服务”链接。 - BalusC
1
对于像我这样不知道在server.xml文件中创建<Context>元素的其他人 - 您必须在<Host>标记内创建它。 - coding_idiot
@XCoder:如果您正在编辑server.xml而不是创建context.xml,那么在Tomcat文档中确实是这样解释的。 - BalusC
@BalusC 如果我这样做,我需要使用什么URL来访问这些图像,以便我可以在ImageView中显示它们? - KJEjava48
显示剩余7条评论

2
我会考虑允许用户直接上传到Amazon S3。Amazon提供了这样的服务。使用该服务,客户端将直接向S3提交带有文件的表单。一旦文件到达那里,Amazon将重定向客户端到您的一个端点,以确认数据已到达,并传递相关详细信息。
好处如下:
  1. 您的服务器不需要花费大量时间接收大型文件。您可以将CPU周期用于更有趣的事情。
  2. 通过将其存储在S3上,所保证的可用性可能比您将其存储在自己的Windows框中获得的要好。
  3. 它具有可伸缩性。在某个时刻,您的文件系统将耗尽空间。(或者您达到了可以存储在一个文件夹内的限制。)

-3
我建议您将图像保存在应用程序的WEB-INF文件夹中的子文件夹中。请记住,当您使用Tomcat时,您的WAR文件将自动解压缩。这种方法还具有一个优点,即您可以随时将应用程序迁移到另一台服务器,您只需要在数据库中保存相对于WEB-INF文件夹的路径即可。

9
不好的建议。每当Tomcat重新部署WAR文件时,所有这些文件都会丢失。 - BalusC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接