Search code examples
javajqueryajaxjquery-file-upload

java.io.FileNotFoundException (path)(Access is denied) when uploading file


I am uploading an image via AJAX, using jQuery.

Here is my HTML:

<body>
  <form id="formId">
    <input type="file" name="file">
    <input type="submit" id="btn" value="submit">
  </form>
</body>

Here is my jQuery code:

$(document).ready(function(){ 
  $("#btn").ready(function(){ 
    data1= new FormData($("#formId")[0]);

    $.ajax( {
      url: 'Sample1',
      type: 'POST',
      data :data1,
      processData: false,
      contentType: false,
      dataType:"text",
      success:function(response)
      {  
      }
    }); 
  });
});  

Here is my Java code:

ServletFileUpload sf=new ServletFileUpload(new DiskFileItemFactory());
try {
    List<FileItem> multifiles=sf.parseRequest(request);
    for(FileItem item:multifiles){
        try {
            item.write(new File("D:\\Projects\\i_seva\\WebContent\\"+item.getName()));
            System.out.println(item.getName());;
            //System.out.println(ss);
        } catch (Exception e) { 
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
} catch (FileUploadException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}  

When I click on the button the request is going to the Sample1 servlet but the following Exception is coming

java.io.FileNotFoundException: D:\Projects\i_seva\WebContent (Access is denied)
    at java.io.FileOutputStream.open0(Native Method)
    at java.io.FileOutputStream.open(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at java.io.FileOutputStream.<init>(Unknown Source)
    at org.apache.commons.fileupload.disk.DiskFileItem.write(DiskFileItem.java:394)
    at com.iseva.Servlet.Sample1.doPost(Sample1.java:35)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1519)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1475)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

If I do it without AJAX, only with the normal form action, it's uploading the image. I am not able to trace where it has gone wrong.


Solution

  • I think the reason this doesn't work when you try via ajax is because the code is running immediately when your page loads, without waiting for the user to select an image or click the button.

    If you go to this link: http://jsfiddle.net/L7n7r9q9/ and open the browser's network tab, you can see that the ajax request is made as soon as the page loads. When the button is clicked, it handles the request using the normal form action, because there's no JavaScript / jQuery code which actually handles the clicking of the button.

    The reason for this is that this line:

     $("#btn").ready(function() {
    

    isn't doing what you intend. The "ready" method is used to execute a function as soon as the page loads and the DOM is ready. The fact you attached it to "btn" makes no difference (and even if it did, it would just run once the button had rendered, which still isn't right). The jQuery documentation says on this:

    ...the selection has no bearing on the behavior of the .ready() method

    See https://api.jquery.com/ready/ for more detail.

    This means that no file is selected when the upload code runs, because the user hasn't had time to choose one. I think this in turns means that your Java code tries to save to a nonsensical / non-existent file path, because it doesn't appear to validate that the file was actually uploaded before trying to save it to disk.

    What you actually want to do is handle the button's "click" event, which runs the code only when the user clicks the button:

    $(document).ready(function(){ 
      $("#btn").click(function(event){ //note "click" instead of "ready"
        event.preventDefault(); //stop default postback behaviour so we can use ajax
        var data1 = new FormData($("#formId")[0]);
    
        $.ajax( {
          url: 'Sample1',
          type: 'POST',
          data :data1,
          processData: false,
          contentType: false,
          dataType:"text",
          success:function(response)
          {  
          }
        }); 
      });
    }); 
    

    N.B. Even if this doesn't fully fix the issue with the Access Denied (you still might not have permission, and I can't verify that or not), you certainly need to amend your code like this before the ajax upload can start working.