当使用enctype=multipart/form-data: java servlet时,无法获取表单字段的值



我写这是为了在指定的文件夹中上传图像并将路径存储在数据库中,但是当我点击添加时显示空白页面,我已经创建了webcontent中的所有文件夹。我使用tomcat服务器:

我的upload.jsp代码看起来像这样:

        <form action="Add" method=post enctype="multipart/form-data">
            <p>Book name:  <input type="text" name="bname" required/></p>
            <p>Price:<input type="text" name="bprice" required/></p>
            <p>Quantity:<input type="text" name="bqty" required/></p>
            <p>Image: <input type="file" name="file" required/></p>
            <p>Course: <select name="course">
            <option>course 1</option>
            <option>course 2</option> <!-- Some more options-->
            <input type="submit" value="Add" name="Submit"/></p>
        </form>
Add.java servlet代码为:
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    response.setContentType("text/html");
    PrintWriter out=response.getWriter();
    String bname=request.getParameter("bname");
    String bprice=request.getParameter("bprice");
    String bqty=request.getParameter("bqty");
    String path="images";
    String file=request.getParameter("file");
    String course=request.getParameter("course");
    if(course.equals("course 1"))
    {
        path="images/folder1";
    }
    else if(course.equals("course 2"))
    {
        path="images/folder2";
    }
    else
    {
        path="images";
    }
    MultipartRequest m=new MultipartRequest(request,path);
    try
    {
        Class.forName("com.mysql.jdbc.Driver");
       Connection con=DriverManager.getConnection("",user,pass);
        PreparedStatement ps=con.prepareStatement("insert into product(bname,course,price,qty,path) values (?,?,?,?,?)");
        ps.setString(1,bname);      
        ps.setString(2,course);
        ps.setString(3,bprice); 
        ps.setString(4,bqty);   
        ps.setString(5,path+file);
        ps.executeUpdate();
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    out.print("<p>Product added!</p>");
    RequestDispatcher rd=request.getRequestDispatcher("upload.jsp");
    rd.include(request, response);
}

得到NullPointer异常。我在什么地方读到过request.getParameter ()我应该使用m.getParameter ()

我这样做了,它工作了,但这并不能解决我的问题,因为我的代码根据course的值来确定路径。

我还需要得到上传文件的文件名,现在我这样做:字符串文件= request.getParameter("文件");

我正在尝试一些示例代码,当我使用m.getParameter()时,我设法获得除文件以外的所有字段的值(我想要,因为我想在DB中存储img路径)。当我不使用enctype=multipart/form-data一切工作正常(我也得到文件名)除了错误的内容是多部分(这是显而易见的我知道)。

ServletRequest#getParameter仅适用于application/x-www-form-urlencoded数据(如果您没有在表单上指定enctype属性,则默认使用此编码)。你可以在这里阅读更多关于表单内容类型的信息。

行开始
MultipartRequest m=new MultipartRequest(request,path);

我假设您正在使用com.oreilly.servlet库。

在这种情况下,使用MultipartRequest#getParameter是获得字段值的正确方法。为了获得上传文件的名称,您可以使用MultipartRequest#getFilesystemName .

我的代码根据表单

的值来确定路径

恐怕您无法用com.oreilly.servlet库以一种清晰的方式做到这一点。你可以自己移动文件,像这样:

m.getFile("file").renameTo(new File("newPath"));

或者,您可以考虑使用其他库来处理多部分数据,例如Apache Commons FileUpload。

您可以使用cos-multipart.jar获取表单字段和文件。

下面的方法对我有用:

public class FileUploadHandler extends HttpServlet {
    private final String UPLOAD_DIRECTORY = "/home/mario/Downloads";
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    //fix max file size 500 Mb
    int maxFileSize = 500000 * 1024;
    int maxMemSize = maxFileSize;
    //getting form fields (both text as well as file) (enctype=multipart/form-data)
    MultipartRequest mreq = new MultipartRequest(request, UPLOAD_DIRECTORY, maxFileSize);
    String uname = mreq.getParameter("username");  //give 'id' in html accordingly
    String dateofupload = mreq.getParameter("uploaddate"); 
    //System.out.println(uname);
    String NEW_UPLOAD_DIRECTORY = UPLOAD_DIRECTORY;
  //get actual file name here  //name field in html tag has to be given accordingly
    String uploadedfilename = mreq.getFilesystemName("file");
 //renaming & moving the file to new location
   File newfileloc = new File(NEW_UPLOAD_DIRECTORY + "/" + uploadedfilename);
   Boolean uploadresult = mreq.getFile("file").renameTo(newfileloc);  //true if success
  }
}

首先将文件保存到一个位置,然后将其重命名/移动到新位置。我本可以将它保存在所需的位置,但要做到这一点,我需要文件名,它只与servlet请求一起提供。但是要访问filename,我们需要创建"Multipart"请求对象。我试图创建two这样的东西,一个访问字段,另一个保存文件。但是,cos-multipart.jar在处理这个问题时有一些错误。

您可能需要考虑使用Apache commons FileUpload。它可以帮助您处理这些类型的场景,并为您处理大多数业务逻辑。

当使用Apache Commons FileUpload时,你可以这样解析请求:

// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Configure a repository (to ensure a secure temp location is used)
ServletContext servletContext = this.getServletConfig().getServletContext();
File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
factory.setRepository(repository);
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
// Parse the request
List<FileItem> items = upload.parseRequest(request);

您可以解析所有单独的

// Process the uploaded items
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = iter.next();
    if (item.isFormField()) {
        processFormField(item);
    } else {
        processUploadedFile(item);
    }
}
try this way:

DiskFileItemFactory factory = new DiskFileItemFactory();
            factory.setSizeThreshold(MEMORY_THRESHOLD);
            factory.setRepository(new File(System.getProperty("java.io.tmpdir")));
            ServletFileUpload upload = new ServletFileUpload(factory);
            upload.setFileSizeMax(MAX_FILE_SIZE);
            upload.setSizeMax(MAX_REQUEST_SIZE); // sets maximum size of request (include file + form data)
            String uploadPath = getServletContext().getRealPath("") + File.separator + UPLOAD_DIRECTORY;
            File uploadDir = new File(uploadPath);
            if (!uploadDir.exists()) {
                uploadDir.mkdir();
            }
            List<FileItem> formItems = upload.parseRequest(request);
            if (formItems != null && formItems.size() > 0) {
                for (FileItem item : formItems) {
                    if (!item.isFormField()) {
                        //file field
                    } else {
                        other form field
                    }

最新更新