解析Servlet中传入的多部分/表单数据参数的便捷方法[重复]

Posted

技术标签:

【中文标题】解析Servlet中传入的多部分/表单数据参数的便捷方法[重复]【英文标题】:Convenient way to parse incoming multipart/form-data parameters in a Servlet [duplicate] 【发布时间】:2011-03-21 04:56:33 【问题描述】:

有什么方便的方法可以从传入的请求中读取和解析数据。

例如客户端发起 post 请求

URLConnection connection = new URL(url).openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
PrintWriter writer = null;
try 
    OutputStream output = connection.getOutputStream();
    writer = new PrintWriter(new OutputStreamWriter(output, charset), true); // true = autoFlush, important!
    // Send normal param.
    writer.println("--" + boundary);
    writer.println("Content-Disposition: form-data; name=\"param\"");
    writer.println("Content-Type: text/plain; charset=" + charset);
    writer.println();
    writer.println(param);

我无法使用 request.getParameter("paramName") 获取参数。以下代码

BufferedReader reader = new BufferedReader(new InputStreamReader(
    request.getInputStream()));
  StringBuilder sb = new StringBuilder();
  for (String line; (line = reader.readLine()) != null;) 
   System.out.println(line);

  

但是为我显示内容

-----------------------------29772313742745
Content-Disposition: form-data; name="name"
J.Doe
-----------------------------29772313742745
Content-Disposition: form-data; name="email"
abuse@spamcop.com
-----------------------------29772313742745

解析传入请求的最佳方法是什么?我不想写自己的解析器,可能有现成的解决方案。

【问题讨论】:

【参考方案1】:

在上传之前并不总是有 servlet(例如,我可以使用过滤器)。 或者可能是同一个控制器(又是一个过滤器或一个 servelt )可以提供许多操作,所以我认为依赖该 servlet 配置来使用 getPart 方法(仅适用于 Servlet API >= 3.0),我不知道,我不喜欢。

一般来说,我更喜欢独立的解决方案,能够独自生活,在这种情况下,http://commons.apache.org/proper/commons-fileupload/ 就是其中之一。

List<FileItem> multiparts = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);
    for (FileItem item : multiparts) 
        if (!item.isFormField()) 
            //your operations on file
         else 
            String name = item.getFieldName();
            String value = item.getString();
            //you operations on paramters
        

【讨论】:

它仅在您有请求对象时才有效。但是如果是流对象或任何其他对象数据呢? 流或任何其他对象数据将替换请求。因此,我会解析/读取流或其他任何内容以获取多部分表单数据。无论如何,你有什么真实的例子吗?【参考方案2】:

解决方案:

解决方案 A:

    下载http://www.servlets.com/cos/index.htmlcom.oreilly.servlet.MultipartRequest 上调用 getParameters()

解决方案 B:

    下载http://jakarta.Apache.org/commons/fileupload/ 调用 readHeaders() 在 org.apache.commons.fileupload.MultipartStream

解决方案 C:

    下载http://users.boone.net/wbrameld/multipartformdata/ 调用 getParameter on com.bigfoot.bugar.servlet.http.MultipartFormData

方案 D:

使用 Struts。 Struts 1.1 会自动处理这个问题。

参考:http://www.jguru.com/faq/view.jsp?EID=1045507

【讨论】:

请提出一些解决方案,因为此链接将来随时可能被废弃。这将吸引负面评价。【参考方案3】:

multipart/form-data 编码请求在 3.0 版之前的 Servlet API 确实默认不支持。 Servlet API 默认使用application/x-www-form-urlencoded 编码解析参数。当使用不同的编码时,request.getParameter() 调用都将返回null。如果您已经使用 Servlet 3.0(Glassfish 3、Tomcat 7 等),则可以改用 HttpServletRequest#getParts()。另请参阅this blog 了解扩展示例。

在 Servlet 3.0 之前,解析 multipart/form-data 请求的 de facto 标准将使用 Apache Commons FileUpload。只需仔细阅读其用户指南常见问题部分,了解如何使用它。我在here 之前发布了一个带有代码示例的答案(它还包含一个针对 Servlet 3.0 的示例)。

【讨论】:

小心。 apache 网站上的一些文档是错误的。例如,他们说您可以在 FileItemFactory 对象上调用 setRepository(),这是错误的,因为任何实现 FileItemFactory 的对象都只有一个方法:createItem()。因此,请确保您也阅读了 javadocs。 getParts() 始终返回零项。为什么在 Java 和 Servlet 3.0 中检索多部分表单如此困难?不敢相信! @basZero:重复问题的答案已经解释了它何时会为空。 @BalusC 你有链接吗?这个页面上有很多信息

以上是关于解析Servlet中传入的多部分/表单数据参数的便捷方法[重复]的主要内容,如果未能解决你的问题,请参考以下文章

快速“预览”传入的多部分请求

Jersey API中的多部分/表单数据出现CORS错误

使用 alamofire 的多部分/表单数据

如何检测空的多部分数据传输

传入一大串Guids

警告:第 0 行未知中的多部分/表单数据 POST 数据中缺少边界