0

I've been testing locally a java servlet and I can't figure out what is happening here. The file is uploaded correctly at the destination but I get an "Access is denied" error after the file is written correctly:

Apr 08, 2016 10:12:39 AM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [FileUploadServlet] in context with path [/FileUpload] threw exception
java.io.IOException: java.io.FileNotFoundException: C:\temp (Access is denied)
at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:121)
at FileUploadServlet.doPost(FileUploadServlet.java:63)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.FileNotFoundException: C:\temp (Access is denied)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:221)
at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
at org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.write(DiskFileItem.java:402)
at org.apache.catalina.core.ApplicationPart.write(ApplicationPart.java:119)
... 22 more

The servlet code:

/**
* Servlet implementation class FileUploadServlet
*/
@WebServlet(asyncSupported = true, urlPatterns = { "/FileUploadServlet" })
@MultipartConfig(location="c:/temp/temp")

public class FileUploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

/**
 * Default constructor. 
 */
public FileUploadServlet() {
    // TODO Auto-generated constructor stub
}

/**
 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response. getWriter();

    out.print("<!DOCTYPE html>");
    out.println("<head><title>File Upload</title><meta http-equiv='Content-Type' content='text/html charset=UTF-8'>");
    out.println("</head><body><form method='POST' action='./FileUploadServlet' enctype='multipart/form-data' >");
    out.println("File:<input type='file' name='file' id='file' /> <br/>");
    out.println("Destination:<input type='text' value='/tmp' name='destination'/>");
    out.println("</br><input type='submit' value='Upload' name='upload' id='upload' />");
    out.println("</form></body></html>");
}

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    for (Part part : request.getParts()) {
        String fileName = extractFileName(part);
        File f = new File(fileName);
        part.write("C:" + File.separator + "temp" + File.separator + f.getName());
    }
}

/**
 * Extracts file name from HTTP header content-disposition
 */
private String extractFileName(Part part) {
    String contentDisp = part.getHeader("content-disposition");
    String[] items = contentDisp.split(";");
    for (String s : items) {
        if (s.trim().startsWith("filename")) {
            return s.substring(s.indexOf("=") + 2, s.length()-1);
        }
    }
    return "";
}
}

Edit: The line giving problems in the trace is

part.write("C:" + File.separator + "temp" + File.separator + f.getName());

EDIT 2: Finally got it working (looks like the file is within a single part of the ones sent). The code:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {      
    File uploads = new File("C:/temp");
    Part filePart = request.getPart("file");
    String fileName = extractFileName(filePart);
    File f = new File(fileName);
    File file = new File(uploads, f.getName());
    try (InputStream input = filePart.getInputStream()) {
        Files.copy(input, file.toPath());
    } catch (Exception e){
        response.setContentType("text/html");
        PrintWriter out = response. getWriter();
        out.print("<body>Failed to upload file <br>" + e.getMessage());
    }
}
Aridez
  • 452
  • 5
  • 17
  • 1
    What makes you think the file is uploaded correctly? – Raedwald Apr 08 '16 at 08:31
  • I see the file at the destination folder after clicking upload on the form, I don't have much experience with this, but if working locally has nothing to do then the file is being uploaded – Aridez Apr 08 '16 at 08:35
  • @Raedwald: because of `@MultipartConfig`. OP just misunderstood `part.write()` (although that API method has admittedly a badly chosen name), as per its documentation it must be interpreted as "move/rename file to a different path/name **relative** to current @MultpartConfig(location)", e.g. `part.write("finalname.ext");` or `part.write("subfolder/finalname.ext")`. Aridez, give it a try and let us know if that indeed solves it. If still in vain, head to http://stackoverflow.com/q/18664579 – BalusC Apr 08 '16 at 09:13
  • The error persist, I'll head to the thread you linked and see if I can correct this problem. It still uploads the file correctly at the location but seems to crash at the end, it's a bit odd. – Aridez Apr 08 '16 at 10:56

2 Answers2

0

SEVERE: Servlet.service() for servlet [FileUploadServlet] in context with path [/FileUpload] threw exception java.io.IOException: java.io.FileNotFoundException: C:\temp (Access is denied)

This says that the user who executed this java deployment (in this case the user who runs the app server) do not have the permission to access the folder. The work around is, place the file in the folder created by the user who runs it or grant the corresponding permission to the folder.

Mahadev
  • 31
  • 3
  • The file is written at the destination correctly, that's what I find strange about this. Also I'm the one running the program and I have permission to create files on that folder. I don't think this is the problem in this case. – Aridez Apr 08 '16 at 09:13
0

Finally got it working (looks like the file is within a single part of the ones sent). The code:

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {      
    File uploads = new File("C:/temp");
    Part filePart = request.getPart("file");
    String fileName = extractFileName(filePart);
    File f = new File(fileName);
    File file = new File(uploads, f.getName());
    try (InputStream input = filePart.getInputStream()) {
        Files.copy(input, file.toPath());
    } catch (Exception e){
        response.setContentType("text/html");
        PrintWriter out = response. getWriter();
        out.print("<body>Failed to upload file <br>" + e.getMessage());
    }
}
Aridez
  • 452
  • 5
  • 17