如何使用JSP将文件上传到服务器文件夹

11

我正在尝试使用servlet/jsp将一些图片上传到位于我的服务器上的文件夹。

以下是我的代码,它在我的本地机器上可以正常工作:

 import java.io.*;
 import java.util.*;

 import javax.servlet.ServletConfig;
 import javax.servlet.ServletException;
  import javax.servlet.http.HttpServlet;
  import javax.servlet.http.HttpServletRequest;
  import javax.servlet.http.HttpServletResponse;

   import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUploadException;
   import org.apache.commons.fileupload.disk.DiskFileItemFactory;
   import org.apache.commons.fileupload.servlet.ServletFileUpload;
     import org.apache.commons.io.output.*;

      public class UploadServlet extends HttpServlet {

  private boolean isMultipart;
   private String filePath;
  private int maxFileSize = 1000 * 1024;
   private int maxMemSize = 1000 * 1024;
   private File file ;

    public void init( ){
  // Get the file location where it would be stored.
  filePath = 
         getServletContext().getInitParameter("file-upload"); 
   }
    public void doPost(HttpServletRequest request, 
           HttpServletResponse response)
          throws ServletException, java.io.IOException {
  // Check that we have a file upload request
     isMultipart = ServletFileUpload.isMultipartContent(request);
     response.setContentType("text/html");
     java.io.PrintWriter out = response.getWriter( );
      if( !isMultipart ){
     out.println("<html>");
     out.println("<head>");
     out.println("<title>Servlet upload</title>");  
     out.println("</head>");
     out.println("<body>");
     out.println("<p>No file uploaded</p>"); 
     out.println("</body>");
     out.println("</html>");
     return;
     }
     DiskFileItemFactory factory = new DiskFileItemFactory();
  // maximum size that will be stored in memory
     factory.setSizeThreshold(maxMemSize);
  // Location to save data that is larger than maxMemSize.
     factory.setRepository(new File(" C:/Users/puneet verma/Downloads/"));  

  // Create a new file upload handler
      ServletFileUpload upload = new ServletFileUpload(factory);
  // maximum file size to be uploaded.
     upload.setSizeMax( maxFileSize );

     try{ 
  // Parse the request to get file items.
     List fileItems = upload.parseRequest(request);

  // Process the uploaded file items
      Iterator i = fileItems.iterator();

     out.println("<html>");
     out.println("<head>");
     out.println("<title>Servlet upload</title>");  
     out.println("</head>");
     out.println("<body>");
     while ( i.hasNext () ) 
     {
       FileItem fi = (FileItem)i.next();
     if ( !fi.isFormField () )  
     {
        // Get the uploaded file parameters
        String fieldName = fi.getFieldName();
        String fileName = fi.getName();
        String contentType = fi.getContentType();
        boolean isInMemory = fi.isInMemory();
        long sizeInBytes = fi.getSize();
        // Write the file
        if( fileName.lastIndexOf("\\") >= 0 ){
           file = new File( filePath + 
           fileName.substring( fileName.lastIndexOf("\\"))) ;
        }else{
           file = new File( filePath + 
           fileName.substring(fileName.lastIndexOf("\\")+1)) ;
        }
        fi.write( file ) ;
        out.println("Uploaded Filename: " + fileName + "<br>");
     }
      }
     out.println("</body>");
          out.println("</html>");
     }catch(Exception ex) {
     System.out.println(ex);
     }
       }
           public void doGet(HttpServletRequest request, 
                   HttpServletResponse response)
          throws ServletException, java.io.IOException {

           throw new ServletException("GET method used with " +
            getClass( ).getName( )+": POST method required.");
           } 
            }

现在是我的JSP代码,用于上传文件:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd">
   <html>
  <head>
      <title>File Uploading Form</title>
     </head>
       <body>
        <h3>File Upload:</h3>
      Select a file to upload: <br />
       <form action="UploadServlet" method="post"
                    enctype="multipart/form-data">
      <input type="file" name="file" size="50" />
       <br />
    <input type="submit" value="Upload File" />
       </form>
      </body>
        </html>
在我的web.xml文件中,我已经包含了如下路径:
      <context-param>
<description>Location to store uploaded file</description>
<param-name>file-upload</param-name>
<param-value>
    C:\Users\puneet verma\Downloads\
 </param-value>
     </context-param>

我已经使用了我的服务器路径http://grand-shopping.com/<"some folder">,但在这里完全不起作用。

我正在使用以下库:

  1. commons-fileupload-1.3.jar
  2. commons-io-2.2.jar

请问有人能建议我如何准确地定义我的服务器路径,以成功上传图片吗?


这里有一个很好的答案 - https://dev59.com/9HE95IYBdhLWcg3wKq2q?rq=1 - आनंद
5个回答

18

以下代码在我的生产服务器和本地电脑上都能正常运行。

注意:

请在WebContent中创建data文件夹,并放入任意单个图片或任何文件(jsp或html文件)。

添加jar文件:

commons-collections-3.1.jar
commons-fileupload-1.2.2.jar
commons-io-2.1.jar
commons-logging-1.0.4.jar

upload.jsp

    <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
       pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>File Upload</title>
</head>
<body>
<form method="post" action="UploadServlet" enctype="multipart/form-data">
Select file to upload:
<input type="file" name="dataFile" id="fileChooser"/><br/><br/>
<input type="submit" value="Upload" />
</form>
</body>
</html>

UploadServlet.java

package com.servlet;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

/**
 * Servlet implementation class UploadServlet
 */
public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    private static final String DATA_DIRECTORY = "data";
    private static final int MAX_MEMORY_SIZE = 1024 * 1024 * 2;
    private static final int MAX_REQUEST_SIZE = 1024 * 1024;

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // Check that we have a file upload request
        boolean isMultipart = ServletFileUpload.isMultipartContent(request);

        if (!isMultipart) {
            return;
        }

        // Create a factory for disk-based file items
        DiskFileItemFactory factory = new DiskFileItemFactory();

        // Sets the size threshold beyond which files are written directly to
        // disk.
        factory.setSizeThreshold(MAX_MEMORY_SIZE);

        // Sets the directory used to temporarily store files that are larger
        // than the configured size threshold. We use temporary directory for
        // java
        factory.setRepository(new File(System.getProperty("java.io.tmpdir")));

        // constructs the folder where uploaded file will be stored
        String uploadFolder = getServletContext().getRealPath("")
                + File.separator + DATA_DIRECTORY;

        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);

        // Set overall request size constraint
        upload.setSizeMax(MAX_REQUEST_SIZE);

        try {
            // Parse the request
            List items = upload.parseRequest(request);
            Iterator iter = items.iterator();
            while (iter.hasNext()) {
                FileItem item = (FileItem) iter.next();

                if (!item.isFormField()) {
                    String fileName = new File(item.getName()).getName();
                    String filePath = uploadFolder + File.separator + fileName;
                    File uploadedFile = new File(filePath);
                    System.out.println(filePath);
                    // saves the file to upload directory
                    item.write(uploadedFile);
                }
            }

            // displays done.jsp page after upload finished
            getServletContext().getRequestDispatcher("/done.jsp").forward(
                    request, response);

        } catch (FileUploadException ex) {
            throw new ServletException(ex);
        } catch (Exception ex) {
            throw new ServletException(ex);
        }

    }

}

web.xml

  <servlet>
    <description></description>
    <display-name>UploadServlet</display-name>
    <servlet-name>UploadServlet</servlet-name>
    <servlet-class>com.servlet.UploadServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>UploadServlet</servlet-name>
    <url-pattern>/UploadServlet</url-pattern>
  </servlet-mapping>

done.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
   pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Upload Done</title>
</head>
<body>
<h3>Your file has been uploaded!</h3>
</body>
</html>

问题:(1)我如何指定目标文件夹的绝对路径? (2)我想将布尔值或其他信息传递给done.jsp,其中包含true(上传成功)或false(上传失败)之类的内容; 我该怎么做? - stackoverflowuser2010
如果您在程序中使用的是绝对静态路径,则该程序无法在实时服务器或任何其他服务器上运行。以上程序非常适合于更改服务器而无需更改代码。 - Vishal Shah
  1. 你可以将布尔变量放在下面的 "item.write(uploadedFile);" 行代码中,并初始化为 false 值。这样,你就可以设置请求中的属性并从请求分派器中传递。
- Vishal Shah
@VishalShah:虽然txt、pdf、jpeg文件可以正常传输,但我无法传输xml、js、css文件。 - Shashank Vivek
我遇到了以下错误:java.lang.NoSuchMethodError: org/apache/commons/fileupload/servlet/ServletFileUpload.parseRequest。我使用的版本是commons.fileupload1.2.1.jar。这可能是问题所在吗? - Freakyuser
@Freakyuser - 这可能是由于更改了Jar文件导致的。您可以使用1.2.2以上的版本,我希望它能正常工作。 - Vishal Shah

1
public class FileUploadExample extends HttpServlet {
     protected void doPost(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);

            if (isMultipart) {
                // Create a factory for disk-based file items
                FileItemFactory factory = new DiskFileItemFactory();

                // Create a new file upload handler
                ServletFileUpload upload = new ServletFileUpload(factory);

                try {
                    // Parse the request
                    List items = upload.parseRequest(request);
                    Iterator iterator = items.iterator();
                    while (iterator.hasNext()) {
                        FileItem item = (FileItem) iterator.next();
                        if (!item.isFormField()) {
                            String fileName = item.getName();    
                            String root = getServletContext().getRealPath("/");
                            File path = new File(root + "/uploads");
                            if (!path.exists()) {
                                boolean status = path.mkdirs();
                            }

                            File uploadedFile = new File(path + "/" + fileName);
                            System.out.println(uploadedFile.getAbsolutePath());
                            item.write(uploadedFile);
                        }
                    }
                } catch (FileUploadException e) {
                    e.printStackTrace();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

}

我无法传输XML、JS和CSS文件,即使对于txt、pdf和jpeg文件也能正常工作。 - Shashank Vivek

0

你不能这样上传。

http://grand-shopping.com/<"some folder">

你需要一个与本地完全相同的物理路径

C:/Users/puneet verma/Downloads/

你可以创建一些本地路径,让你的服务器工作。这样你就可以存储和检索文件。如果你从任何网站购买了某个域名,那么就会有上传文件的路径。你可以将这些变量设置为静态常量,并根据你所使用的服务器(本地/网站)来使用它们。

0

您只能使用绝对路径http://grand-shopping.com/<"some folder">,而不是相对路径。

您可以使用应用程序内部的路径,但这样会存在漏洞,或者您可以使用服务器特定的路径,例如

windows -> C:/Users/puneet verma/Downloads/
linux -> /opt/Downloads/

0

我发现了类似的问题,并找到了解决方案,我已经写了一篇关于如何使用JSP上传文件的博客文章(链接)。在那个例子中,我使用了绝对路径。请注意,如果您想要路由到其他基于URL的位置,您可以使用像WSO2 ESB这样的ESB。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接