【问题标题】:Issue with multipart/form-data多部分/表单数据问题
【发布时间】:2009-10-09 19:48:42
【问题描述】:

当我的表单包含多部分/表单数据时,我无法从 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);

【问题讨论】:

    标签: java servlets file-upload


    【解决方案1】:

    使用multipart/form-data 时,request.getParameter() 可以使用普通输入字段值,因为 3.0 版之前的标准 Servlet API 没有内置工具来解析它们。这正是 Apache Commons FileUpload 存在的原因。您需要检查FileItem#isFormField() 是否返回true,然后从FileItem 中收集它们。

    现在您忽略了代码中的这些值。诚然,FileItem 是一个误导性的名称,如果是我,我会称它为 MultipartItem 或只是 Part 代表 multipart/form-data 正文的一部分,其中包含上传的字段和普通参数。

    这是一个启动示例,您应该如何正确解析 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 表单 (stackoverflow.com/questions/18759688/…) 返回 null。
    • 您应该使用 Struts 提供的文件上传工具。阅读它的文档。
    • 你的意思是FormFile类吗?我有一个以 json 格式编码的动态表单,所以我“手动”处理请求。
    • @Cricket:我不做 Struts,所以不能详细介绍。我只知道它有内置的文件上传功能。注意:HTTP 请求只能解析一次。如果你得到一个空的 body,那么 Struts 很可能已经事先隐式地解析了它。您可能希望将其关闭。再次,阅读它的文档。否则只需按右上角的“”按钮,而不是为此劫持别人的问题。
    • 感谢您的建议。
    【解决方案2】:

    过去我也遇到过类似的问题。我能找到解决问题的唯一方法是将文件上传到它自己的形式。

    【讨论】:

    • 是的,如果可能的话,我需要将其设为 1 种形式。我相信它必须与 servlet 有关,因为我可以将值发布到 url 字符串并且它们看起来正确但 servlet 将值获取为 null
    猜你喜欢
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-18
    • 2012-10-11
    • 1970-01-01
    • 2014-02-14
    • 2019-03-29
    • 1970-01-01
    相关资源
    最近更新 更多