multipart/form-data问题

3

当我的表单包括multipart/form-data时,在servlet中我无法从两个文件和文本输入中获取值。我正在使用apache.commons.fileuploads来帮助上传。有什么建议吗?此外,在下面的代码中,有一些我觉得应该更有效率的事情。是否有更好的方法将这些多个文件存储在数据库中。

public void performTask(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)
    {
        boolean promo = false;
        Database db = new Database();
        Homepage hp = db.getHomePageContents();

        String part = ParamUtils.getStringParameter(request, "part", "");
        if(part.equals("verbage"))
        {
            String txtcontent = (String)request.getParameter("txtcontent");
            String promoheader = (String)request.getParameter("promoheader");
            String promosubheader = (String)request.getParameter("promosubheader");
            hp.setBodyText(txtcontent);
            hp.setPromoHeader(promoheader);
            hp.setPromoSubHeader(promosubheader);
            System.err.println(txtcontent);
        }
        else
        {

            boolean isMultipart = ServletFileUpload.isMultipartContent(request);
            if (!isMultipart) 
            {

            }
            else {
                FileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload upload = new ServletFileUpload(factory);
                List items = null;
                try {
                items = upload.parseRequest(request);
                //System.err.print(items);
                } catch (FileUploadException e) {
                e.printStackTrace();
                }

                Iterator itr = items.iterator();
                while (itr.hasNext()) {
                    FileItem item = (FileItem) itr.next();
                    if(item.getFieldName().equals("mainimg1"))
                    {
                        if(item.getName() !="") hp.setMainImg1(item.getName());
                    }
                    if(item.getFieldName().equals("mainimg2"))
                    {
                        if(item.getName() !="") hp.setMainImg2(item.getName());
                    }
                    if(item.getFieldName().equals("mainimg3"))
                    {
                        if(item.getName() !="") hp.setMainImg3(item.getName());
                    }
                    if(item.getFieldName().equals("promoimg1"))
                    {
                        promo = true;
                        if(item.getName() !="")
                        {
                            hp.setPromoImg1(item.getName());
                            try {
                                File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/promoImg1.jpg");
                                item.write(savedFile);
                                //System.err.print(items);
                            } catch (Exception e) {
                                    System.err.println(e.getMessage());
                            }
                        }
                    }
                    if(item.getFieldName().equals("promoimg2"))
                    {
                        if(item.getName() !="") 
                        {
                            hp.setPromoImg2(item.getName());
                            try {
                                File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/promoImg2.jpg");
                                item.write(savedFile);
                                //System.err.print(items);
                            } catch (Exception e) {
                                    System.err.println(e.getMessage());
                            }
                        }
                    }
                    if(item.getFieldName().equals("promoimg3"))
                    {
                        if(item.getName() !="")
                        {
                            hp.setPromoImg3(item.getName());
                            try {
                                File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/promoImg3.jpg");
                                item.write(savedFile);
                                //System.err.print(items);
                            } catch (Exception e) {
                                    System.err.println(e.getMessage());
                            }
                        }
                    }


                    System.err.println("FNAME =" + item.getFieldName() + " : " + item.getName());
                    if (item.isFormField()) {
                    } 
                    else {
                        try {
                            if(!promo)
                            {
                                String itemName = item.getName();
                                File savedFile = new File("/Library/resin-4.0.1/webapps/ROOT/images/"+itemName);
                                item.write(savedFile);
                            }
                            //System.err.print(items);
                        } catch (Exception e) {
                                System.err.println(e.getMessage());
                          }
                    }
                }
            }
        }


        db.updateHomePageContent(hp);
2个回答

10
使用 multipart/form-data 时,由于标准 Servlet API 版本在 3.0 之前没有内置的解析工具,因此 request.getParameter() 方法无法获取普通输入字段的值。这正是 Apache Commons FileUpload 的存在原因。您需要检查 FileItem#isFormField() 是否返回 true,然后从 FileItem 中收集它们。
目前,您的代码中忽略了这些值。不可否认,FileItem 是一个误导性的名称。如果是我的话,我会将其命名为代表 multipart/form-data 主体的一部分,其中包含上传字段和普通参数的MultipartItem或者只叫Part
以下是一个示例如何正确解析 multipart/form-data 请求的启动代码:
List<FileItem> items = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
for (FileItem item : items) {
    if (item.isFormField()) {
        // Process normal fields here.
        System.out.println("Field name: " + item.getFieldName());
        System.out.println("Field value: " + item.getString());
    } else {
        // Process <input type="file"> here.
        System.out.println("Field name: " + item.getFieldName());
        System.out.println("Field value (file name): " + item.getName());
    }            
}

注意,你还忽略了MSIE的一个问题,即它会发送完整的客户端路径和文件名。根据FileUpload FAQ,你需要从item.getName()中删除它:

String fileName = item.getName();
if (fileName != null) {
    filename = FilenameUtils.getName(filename);
}

我正在使用Struts 1.3和ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);处理multipart/form-data表单时返回null(https://dev59.com/NnbZa4cB1Zd3GeqPJcGQ)。 - Sefran2
你应该使用Struts提供的文件上传功能。阅读它的文档。 - BalusC
你是指FormFile类吗?我有一个动态表单以json格式编码,所以我手动处理请求。 - Sefran2
1
@Cricket:我不做Struts,所以无法深入了解。我只知道它有内置的文件上传功能。注意:HTTP请求只能被解析一次。如果你得到一个空的主体,那么Struts很可能已经在此之前隐式地解析过它。你可能想要关闭它。再次阅读它的文档。否则,不要劫持别人的问题,而是点击右上角的“提问”按钮。 - BalusC
谢谢您的建议。 - Sefran2

0

我过去也遇到过类似的问题。我找到解决方法的唯一途径是将文件上传放入它自己的表单中。


如果可能的话,我需要这个变成一个表单。我相信这与servlet有关,因为我可以将值发布到URL字符串,它们看起来是正确的,但是servlet将该值捕获为空。 - kbrin80

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