如何获取用户图像、存储这些图像,并在以后进行渲染?

huangapple go评论85阅读模式
英文:

How to take user images, store them, and render them later?

问题

我正在尝试构建一个应用程序,该应用程序从HTML表单中获取用户图像,使用Java Servlet将该图像存储在数据库中,然后使用另一个HTML标签将图像呈现在屏幕上。用于接受图像的HTML表单如下:

<form action="../servlets/submitrequest" method="post" enctype="multipart/form-data">
    <input type="number" name="cost" placeholder="Cost" required/><br/>
    <p id="img">Image of receipt: <input type="file" name="image" required/><br/></p>
    <input type="submit" id="submit" name="submit" value="Submit" onClick="success();"/><br/>
</form>

保存文件的Servlet的相关部分如下:

Random r = new Random();
String dir = "C://tmp/reciepts/" + r.nextInt() + ".png";
for (Part part : request.getParts()) {
    if (part.getName().equalsIgnoreCase("image"))
        part.write(dir);
}

然后,Servlet将dir保存为数据库中的图像文件路径(PostgreSQL)。然而,当我尝试在Web浏览器上显示图像URL时,Chrome抛出以下错误:

Not allowed to load local resource: file:///C://tmp/images/1154006734.png

根据这里的解释,这是因为Chrome出于安全原因无法读取本地文件。因此,我开始寻找将图像保存到webcontent文件夹的方法,以便它成为Web应用程序内容的一部分。我遵循了这个示例,并将我的Servlet代码更改为:

String dir = request.getServletContext().getRealPath("/") + File.separator + "reciepts";
File fileSaveDir = new File(dir);
if (!fileSaveDir.exists()) {
    fileSaveDir.mkdir();
}
request.getPart("image").write(dir);

即使在执行了这些更改后,我仍然收到相同的错误:

Not allowed to load local resource: file:///C:/Users/Colby/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Project_1//reciepts/image.file

因此,我的问题是:我应该在哪里存储用户上传的文件,以便Web浏览器和应用程序本身都可以访问?

英文:

I'm trying to build an application that takes a user image from an html form, uses a java servlet to store said image in a database, and then renders the image onto the screen with another html tag. The HTML form to accept the image is:

&lt;form action=&quot;../servlets/submitrequest&quot; method=&quot;post&quot; enctype=&quot;multipart/form-data&quot;&gt;
	&lt;input type=&quot;number&quot; name=&quot;cost&quot; placeholder=&quot;Cost&quot; required/&gt;&lt;br/&gt;
	&lt;p id=&quot;img&quot;&gt;Image of receipt: &lt;input type=&quot;file&quot; name=&quot;image&quot; required/&gt;&lt;br/&gt;&lt;/p&gt; 
	&lt;input type=&quot;submit&quot; id=&quot;submit&quot; name=&quot;submit&quot; value=&quot;Submit&quot; onClick=&quot;success();&quot;/&gt;&lt;br/&gt;
&lt;/form&gt;

The relevent part of my servlet that saves the file is:

Random r = new Random();

String dir = &quot;C://tmp/reciepts/&quot; + r.nextInt() + &quot;.png&quot;;
		
for(Part part: request.getParts()) {
	if(part.getName().equalsIgnoreCase(&quot;image&quot;))
		part.write(dir);
}

The servlet then saves dir as the image filepath in the database (postgresql). However when I tried to take the image URL and display it on the web browser Chrome throws the following error:

Not allowed to load local resource: file:///C://tmp/images/1154006734.png

Which according to <a href="https://stackoverflow.com/questions/39007243/cannot-open-local-file-chrome-not-allowed-to-load-local-resource">this</a> is caused because chrome can't read local files because of security reasons. Fair enough. So I started looking for ways to save it to the webcontent folder, so it would be a part of the content of the web application. I followed <a href="https://stackoverflow.com/questions/50345697/getting-error-while-uploading-image-with-form-elements">this</a> example and changed my servlet's code to:

String dir = request.getServletContext().getRealPath(&quot;/&quot;) + File.separator + &quot;reciepts&quot;;
File fileSaveDir = new File(dir);
if (!fileSaveDir.exists()) {
	fileSaveDir.mkdir();
}
request.getPart(&quot;image&quot;).write(dir);

Even after doing this I still received the same error:

Not allowed to load local resource: file:///C:/Users/Colby/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps/Project_1//reciepts/image.file

So my question is this: where do I store files uploaded by the user where they can be accessed by both the web browser and the application itself?

答案1

得分: 0

你需要将servlet的doGet方法更改为以流的方式返回二进制数据。

response.setContentType("application/pdf");

try (
  ServletOutputStream output = response.getOutputStream();
  InputStream input = getServletContext().getResourceAsStream("myLocalFile.pdf");
){ 
  // 将缓冲流传输到输出流
  byte[] buffer = new byte[2048];
  int bytesRead = -1;    
  while ((bytesRead = input.read(buffer)) != -1) {
     output.write(buffer, 0, bytesRead);
  }
}

然后在你的HTML中,不要使用<img src...>指向一个文件,而是指向上述的servlet。

注意

当你的网络应用被远程用户访问时,他们无法直接了解或访问你的服务器文件系统

英文:

You have to change the doGet of a servlet to stream back the binary data.

response.setContentType(&quot;application/pdf&quot;);

try (
  ServletOutputStream output = response.getOutputStream();
  InputStream input = getServletContext().getResourceAsStream(&quot;myLocalFile.pdf&quot;);
){ 
  //transfer buffered stream to output stream
  byte[] buffer = new byte[2048];
  int bytesRead = -1;    
  while ((bytesRead = input.read(buffer)) != -1) {
     output.write(buffer, 0, bytesRead);
  }
}

Then in your HTML rather than having &lt;img src...&gt; pointing to a file have it pointing to the above servlet.

note

Of course when your web application is run from a remote user, then will have no knowledge or access to your server's file system directly.

huangapple
  • 本文由 发表于 2020年10月23日 08:19:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/64492245.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定