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!

4

2 回答 2

1

1 如何解决这条路径的即时问题?

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

在您的情况下,"/tempfiledir"Windows 中的 will 指向C:\tempfiledirWindows 和服务器安装C:\/tempfiledir. 您需要添加另一种签入init()方法,该方法File#exists()也会进行检查以及时发现文件夹的缺失。

2 如何以更便携的方式进行(考虑到 linux 权限)?

只要您不使用特定于 Windows 的磁盘标签(如C:\/用作路径分隔符),您就不必担心这一点。

如果你真的坚持将文件写入webcontent,那么你需要记住两点:1)当部署为WAR时,它只有在WAR被servletcontainer扩展时才有效。2) 重新部署 WAR 时,所有内容(所有上传的文件)都将被删除。

这是您可以将相对 Web 路径转换为绝对磁盘文件系统路径的方法,以便您可以进一步使用它File并与之搭配:

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

与问题无关:item.getName()将在某些网络浏览器(特别是:MSIE 系列)中返回完整的客户端路径。根据Commons Fileupload FAQ,您需要FilenameUtils#getName()在将其用作文件名之前调用它new File(),否则它也会在那里造成严重破坏。

于 2010-11-23T18:22:21.937 回答
0

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

于 2010-11-23T19:47:03.443 回答