2

I'm doing a simple file upload in jsp. And i seem to have been stopped by this simple path issue. I'm developing on windows but will propably deploy on a linux machine. so i have the tmpdir and the finaldir under mywebsite/tempfiledir and mywebsite/finalfiledir

so i use this code (snippet of the servlet)

public class SyncManagerServlet extends HttpServlet {
 private static final String TMP_DIR_PATH = "/tempfiledir";
 private File tempDir;
 private static final String DESTINATION = "/finalfiledir";
 private File destinationDir;

 public void init(ServletConfig config){
    try {
        super.init(config);

        tempDir = new File(getAbsolute(TMP_DIR_PATH));

        if(!tempDir.isDirectory()){
            throw new ServletException(TMP_DIR_PATH + " is not a Directory");
        }

        destinationDir = new File(getAbsolute(DESTINATION));
        if(!destinationDir.isDirectory()){ 
            throw new ServletException(DESTINATION + " is not a Directory");
        }

    } catch (ServletException ex) {
        Logger.getLogger(OrliteSyncManagerServlet.class.getName()).log(Level.SEVERE, null, ex);
    }
}


protected void processRequest(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    response.setContentType("text/html;charset=UTF-8");
    PrintWriter out = response.getWriter();
    String email = request.getParameter("email");
    String path = request.getContextPath();
    DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();

    fileItemFactory.setRepository(tempDir);
    ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);


    try {


        List items = uploadHandler.parseRequest(request);
        Iterator itr = items.iterator();
        while(itr.hasNext()){
            FileItem item = (FileItem) itr.next();

            if( item.isFormField() && item != null ){

                out.println("<html>");
                out.println("<head>");
                out.println("<body>");
                out.println("your email: " + item.getString() + " has been submited and context path is "+ request.getContextPath() );
                out.println("</body>");
                out.println("</head>");
                out.println("</html>");

            } else {
                out.println("the uploaded file name is  : " + item.getName());
                out.println("content type  is  : " + item.getContentType());
                out.println("Size  is  : " + item.getSize());
                File file = new File(destinationDir, FilenameUtils.getName(item.getName()));

                item.write(file);
            }

public String getAbsolute(String relativepath){
    return getServletContext().getRealPath(relativepath);
}


//......
}

i'm having this exception

java.io.FileNotFoundException: D:\WORK\java\netbeansProject\Projects\mywebsite-webapp\target\mywebsite\finalfiledir (Access is denied)

i can't figure out why the relative path is failing. I've noticed in a lot of samples online people uses full path for the tempdir. So in my case where i have to worry about linux on deployment, what's the workaround?But first i'ld like to understand why the path i've given is wrong.

Thanks for reading this! so 2 issues here

1 how to solve this path immediate issue?

2 how to do it in a more portable way (with linux privileges in mind)?

thanks!

black sensei
  • 6,528
  • 22
  • 109
  • 188

2 Answers2

1

1 how to solve this path immediate issue?

Paths which starts with a leading slash are not relative to the current working directory. They are absolute and would only in Windows point to the current working disk (where the server is running on and is dependent on how the server is been started).

In your case, the "/tempfiledir" would in Windows point to C:\tempfiledir when Windows and the server is installed on C:\, and in Linux to /tempfiledir. You need to add another check in init() method which does a File#exists() check as well to spot the absence of the folder timely.

2 how to do it in a more portable way (with linux privileges in mind)?

As long as you don't use Windows-specific disk labels like C:\ and use / as path separator, you don't need to worry about this.

If you really insist in writing the files to the webcontent, then you need to keep two things in mind: 1) When deploying as WAR, it only works when the WAR is expanded by servletcontainer. 2) When redeploying the WAR, everything (all uploaded files) will be erased.

This is how you can convert relative web paths to absolute disk file system paths so that you can use it further in File and consorts:

String relativeWebPath = "/tempfiledir";
String absoluteDiskPath = getServletContext().getRealPath(relativeWebPath);
File file = new File(absoluteDiskPath, filename);

Unrelated to the problem: the item.getName() would return the full client side path in certain webbrowsers (specifically: the MSIE family). As per the Commons Fileupload FAQ you need to call FilenameUtils#getName() on it before using as filename in new File(), otherwise it will cause havoc there as well.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hey thanks for the hands.i've updated my post and it seem, i'm still having the file not found exception (FNFE) with (access denied). i can't really tell why there is permission issue here. is the access denied the cause of FNFE ? – black sensei Nov 23 '10 at 19:11
  • The file is there, but the user account associated with webserver is not authorized to access it. This is to be configured at operating system level. – BalusC Nov 23 '10 at 19:20
  • my bad , my bad it's unrelated.i've not been choosing the to upload itself.thanks for this huge hand you gave me.i really appreaciate it – black sensei Nov 23 '10 at 19:40
0

I think that the best place to save temporary files is the system temp dir that can be retrieved from system property java.io.tmpdir. I have never seen environment where user cannot write to this directory.

AlexR
  • 114,158
  • 16
  • 130
  • 208