代码之家  ›  专栏  ›  技术社区  ›  black sensei

简单JSP文件上传中如何设置临时目录相对路径?FileNotFound异常[重复]

  •  2
  • black sensei  · 技术社区  · 15 年前

    我在JSP中进行一个简单的文件上传。我似乎被这个简单的路径问题所阻止。我正在Windows上开发,但可以很好地部署在Linux机器上。所以我在mywebsite/tempfiledir和mywebsite/finalfiledir下有tmpdir和finaldir

    所以我使用这个代码(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);
    }
    
    
    //......
    }
    

    我有个例外

    JavaIO.FielOnFunExtExp:D:\Work\Java\NETBeNsStudio\Studio\MyWebWebAPP\Tave\MyBooth\FielFieldR(Access被拒绝)

    我不明白为什么相对路径会失败。 我注意到在许多在线示例中,人们使用tempdir的完整路径。 所以在我的案例中,我必须担心Linux在部署上的问题,解决方法是什么?但首先,我想知道为什么我给出的路径是错误的。

    谢谢你读这个! 所以这里有两个问题

    如何解决这条道路的紧迫性问题?

    如何以更可移植的方式(考虑到Linux的特权)?

    谢谢!

    2 回复  |  直到 15 年前
        1
  •  1
  •   BalusC    15 年前

    1如何解决这条道路的紧迫性问题?

    以前导斜杠开头的路径不是相对于当前工作目录的路径。它们是绝对的,只能在Windows中指向当前工作磁盘(服务器运行的位置,取决于服务器的启动方式)。

    在您的情况下, "/tempfiledir" 会在Windows中指向 C:\tempfiledir 当Windows和服务器安装在 C:\ 以及在Linux中 /tempfiledir . 您需要添加另一个签入 init() 方法执行 File#exists() 同时检查文件夹是否及时丢失。

    2如何以更可移植的方式进行(考虑到Linux的特权)?

    只要您不使用Windows特定的磁盘标签,例如 C: 和使用 / 作为路径分隔符,您不需要为此担心。

    如果您真的坚持要将文件写入WebContent,那么需要记住两件事:1)当部署为war时,它只在servletcontainer扩展war时工作。2)重新部署战争时,所有内容(所有上传的文件)都将被删除。

    这是如何将相对Web路径转换为绝对磁盘文件系统路径,以便在 File 和配偶:

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

    与问题无关: item.getName() 将返回特定WebBrowser(特别是msie系列)中的完整客户端路径。根据 Commons Fileupload FAQ 你需要打电话 FilenameUtils#getName() 在中用作文件名之前 new File() 否则它也会在那里造成破坏。

        2
  •  0
  •   AlexR    15 年前

    我认为保存临时文件的最佳位置是可以从系统属性java.io.tmpdir中检索到的系统temp dir。我从未见过用户无法写入此目录的环境。