0

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:

<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>

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

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);
}

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 this 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 this example and changed my servlet's code to:

String dir = request.getServletContext().getRealPath("/") + File.separator + "reciepts";
File fileSaveDir = new File(dir);
if (!fileSaveDir.exists()) {
    fileSaveDir.mkdir();
}
request.getPart("image").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?

Aitchbar
  • 13
  • 2

1 Answers1

0

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

response.setContentType("application/pdf");

try (
  ServletOutputStream output = response.getOutputStream();
  InputStream input = getServletContext().getResourceAsStream("myLocalFile.pdf");
){ 
  //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 <img src...> 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.

Scary Wombat
  • 44,617
  • 6
  • 35
  • 64
  • Hello thank you for your response. I tried to run the above code (of course putting in the file I wanted to read in the input stream), and I got a null pointer exception because input is null when checking the condition for the while loop. Is that because I had the wrong path on the file I put in? I double checked and the file path is correct, so Im not sure why i would be getting this error – Aitchbar Oct 23 '20 at 01:22
  • Yes, see https://stackoverflow.com/questions/16570523/getresourceasstream-returns-null. I was basically telling of the code construct, you may need to change based upon your requirements. The key thing is that you be able to open and read you file first, wherever it is. – Scary Wombat Oct 23 '20 at 01:29
  • oh my god it works thank you so much you're a lifesaver – Aitchbar Oct 23 '20 at 01:33