【问题标题】:java.io.FileNotFoundException when writing uploaded file to disk via getRealPath()通过 getRealPath() 将上传的文件写入磁盘时出现 java.io.FileNotFoundException
【发布时间】:2013-02-12 23:12:48
【问题描述】:

Glassfish 似乎也为我想保存图像文件的路径添加了额外内容,有没有办法只使用我的 servlet 获得的绝对路径

String appPath = request.getServletContext().getRealPath("");?

我花了几天时间尝试不同的方法来上传图像文件并让 servlet 将其保存到磁盘。

我用了这个例子: http://www.codejava.net/java-ee/servlet/how-to-write-upload-file-servlet-with-servlet-30-api

使用调试我可以看到正确收集了文件名和路径信息,但代码在 `part.write(savePath + File.separator + fileName); 处失败;``

glassfish 的异常报告是:

exception

java.io.FileNotFoundException: C:\Program Files\glassfish-3.1.2.2\glassfish\domains\domain1\generated\jsp\com.onemore_onemore-web_war_1.0-SNAPSHOT\D:\Dropbox\Git\Brian_JEE\onemore\onemore\onemore-web\target\onemore-web-1.0-SNAPSHOT\image\screengrab_all_products.jpg (The filename, directory name, or volume label syntax is incorrect)

我可以看到作为此异常的一部分的正确路径D:\Dropbox\Git\Brian_JEE\onemore\onemore\onemore-web\target\onemore-web-1.0-SNAPSHOT\image\screengrab_all_products.jpg

JSP

<form action="${pageContext.request.contextPath}/imageupload" method="post" enctype="multipart/form-data" name="productForm" id="productForm">
<input type="file" name="file" id="file">
<input type="submit" name="Submit" value="Submit"></td>
</form>

小服务程序

@WebServlet(name = "UploadImageServlet", urlPatterns = {"/imageupload"})
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB 
maxFileSize = 1024 * 1024 * 10, // 10MB
maxRequestSize = 1024 * 1024 * 50)   // 50MB
public class UploadImageServlet extends HttpServlet {

    /**
     * Name of the directory where uploaded files will be saved, relative to the
     * web application directory.
     */
    private static final String SAVE_DIR = "image";

    /**
     * handles file upload
     */
    @Override
    protected void doPost(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
      // gets absolute path of the web application
        String appPath = request.getServletContext().getRealPath("");
        // constructs path of the directory to save uploaded file
        String savePath = appPath + File.separator + SAVE_DIR;

        // creates the save directory if it does not exists
        File fileSaveDir = new File(savePath);
        if (!fileSaveDir.exists()) {
            fileSaveDir.mkdir();
        }

        for (Part part : request.getParts()) {
            String fileName = extractFileName(part);
            part.write(savePath + File.separator + fileName);
        }

        request.setAttribute("message", "Upload has been done successfully!");
        getServletContext().getRequestDispatcher("/WEB-INF/jsp/newproduct.jsp").forward(
                request, response);
    }

    /**
     * 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 "";
    }
}

【问题讨论】:

    标签: servlets file-upload filenotfoundexception realpath


    【解决方案1】:

    永远不要使用 getRealPath()

    您不应将上传的文件保存在部署文件夹中。我之前已经解释过很多次了。可以在以下答案中找到其中一种解释:Uploaded image only available after refreshing the page

    在使用getRealPath() 方法的博客/文章中发现的任何JSP/Servlet 代码sn-p 都应该用一大袋盐来处理。它的质量和作者的知识应该受到强烈质疑。 There is namely no sensible real world use case for that method.

    将上传的文件保存在部署文件夹之外的固定路径中。另见How do I set the folder for storing file uploads using Commons FileUpload

    【讨论】:

    • 感谢您的回答。我已经阅读了您的许多帖子,现在我将图像放在部署文件夹之外,并在glassfish-web.xml 中设置了一个新属性alternatedocroot_1,它可以正确映射图像以供显示。不幸的是,无论我输入什么路径,我的part.write 都坚持将文件写入错误的文件夹。您能否告诉我如何让write.part 将文件保存到我设置的文件夹中。谢谢
    • 确保路径以斜杠开头:part.write("/path/to/filename.ext")
    • 谢谢。在阅读了@MultipartConfig 注释后,我发现我可以使用location="****" 设置路径。文件成功上传到我想要的文件夹,然后 glassfish 报告异常(文件访问被拒绝)。虽然至少该文件会被送到正确的位置。
    • 表示文件大于文件上传内存配置可以容纳的临时存储文件夹,绝对不打算作为永久存储位置。它将定期清洁。它默认为System.getProperty("java.io.tmpdir"),在大多数情况下应该很好。你还是走错了路。请不要忽视我的建议,并使用绝对磁盘文件系统路径将其写入所需位置您自己,如已回答。
    • 感谢您的所有帮助。经过两周的 14 小时工作后,我再也没有时间和精力来做这件事了。考试迫在眉睫,这只是一门课程的一部分。我的队友们告诉我,只要能做到这一点。我尝试在路径上放置一个前导斜杠,但最终返回旧错误(系统找不到指定的路径)。我们在这个项目上没有得到任何支持,每一步都是一场斗争。没有像你这样的人,我们会完蛋的。
    【解决方案2】:

    使用以下代码。我使用这些代码解决了这个错误。将它写入你的 doPost 方法中。

    Part filePart = request.getPart("file");
    String fileName = 
    Paths.get(filePart.getSubmittedFileName()).getFileName().toString(); 
    InputStream inputStream = filePart.getInputStream();
    String uploadPath = getServletContext().getRealPath("") + File.separator + "uploaded_file";
    File uploadDir = new File(uploadPath);
    if (!uploadDir.exists()) {
                uploadDir.mkdir();
            }
    FileOutputStream outputStream = new FileOutputStream(uploadPath + 
    File.separator + fileName);
            int read = 0;
            final byte[] bytes = new byte[1024];
            while ((read = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, read);
            }
    

    \\

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-13
      • 2012-08-18
      • 1970-01-01
      • 2018-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多