【问题标题】:Using CommonsMultipartResolver to parse an HTTP request with embedded multipart content使用 CommonsMultipartResolver 解析嵌入多部分内容的 HTTP 请求
【发布时间】:2016-01-12 23:23:35
【问题描述】:

我正在使用 Spring Integration 接收 HTTP 请求,该请求具有嵌套在多部分请求中的多部分内容,如下所示。当使用 CommonsMultipartResolver 作为解析器时,传递给接收服务激活器的 LinkedMultiValueMap 包含所有部分的映射,但嵌入的多部分是一个 UploadedMultipartFile包含全部内容。在示例中 boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL 是嵌入多部分的边界。

如何将嵌入的多部分解析为 LinkedMultiValueMap 以便获取版本和有效负载? CommonsMultipartResolver 是否可以执行此操作,或者是否有其他方法来解析它?

Http 请求:

POST http://xxxxx:8087/edi846InboundHTTP/1.1

内容类型:multipart/form-data;boundary=DM1-Sb0636VXPQNO3412Ygegb9suqr .......

内容长度:2787

--DM1-Sb0636VXPQNO3412Ygegb9suqr

内容配置:表单数据;名称="来自"

内容类型:text/plain;charset=ISO-8859-1 内容长度:7

gisb-确认收据

--DM1-Sb0636VXPQNO3412Ygegb9suqr

内容配置:表单数据;名称=“输入格式”内容类型: text/plain;charset=ISO-8859-1 内容长度:3

X12

--DM1-Sb0636VXPQNO3412Ygegb9suqr

内容配置:表单数据;名称=“输入数据”;文件名="TEST-DTEBS_846_3563_10142015102600.x12"

内容类型: multipart/encrypted;boundary=boundary2--extKDvsqGExTQI2WVuplHFCUQJ3XVL 协议: 应用程序/pgp 加密

boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL

内容配置:表单数据;名称="版本" 内容类型: application/pgp-encrypted Content-Length: 10

版本:1

boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL

内容配置:表单数据; name="payload" 内容类型:应用程序/八位字节流内容长度: 1118

-----BEGIN PGP MESSAGE----- 版本:BCPG v1.47

hQIOA8aa0/bci2e/EAf/fkgOBK+cooeY+44htcvjE9Sxk9RK73aOEaxDOBNqFOsV Nzw1va7cc7wzYOTlHhZV/MkpXq+IrZV316moJu1EAhscN9YmyReVDOzrkzZ1hBmq V2MlAr5/CRqS7nQEmCqy/Mz0STtAPZNg3FOh8F79dJnRws5/SdW+zvn2MoSvGTs3 0YvjmtPq2YyVkMlAvJ62f903UYNIiAcEe1k8gWDVW9LJ4tGud+8H0bsG8EFWPsSI b5rON+MKGykbWGnbSrOy9cqslJaghj91r7ZbsXXXiRn9v4rpOardfiBEnoamI5Tz jfDKESnr7CqoZgb62je+NJrB5puoAwy8LTynXx4cmQgAnf8lb6f+mIxa1U1Mu6iR KNTjrH83Cx2BjTra8E8hu0O7GvuczGfA9NiONmxbglgKK58/QVYdlsZUiGTaWkkY 4nMHiaFe9TiPQ6W2vMGutLFR3V6YSshchCskl6cP1OdaIXCYgzZKIjUWHePzd/ds zCZeNqul1N7iIQ0L5lfSGgfB2eDeeK3JKFjetrrbJQXz0+XeTZLPMSMr6W5Ggq3l PnoJVTrxUd3b2WKgR4FZB+imYRWEz5KLnB5ZVedC+fU24bECcNptrTQaZZUWnR3Z ABJqz8avBrNV0Jf9BaFRxcWkrWyr4KtxDArxXOuMHNvGVtj+hhPZcPGj3N9Xam3E 6snAGEbIiAEivZPYLVVVk0lZW2H0ISwkKkjD8qs7h8wa7Qbchp2K5IyENEzi20oe FNRoCwHyjsCY0nECHCG3WON0EXG2DZDTvA17OoyfuKnRT09FVt3OOEPTV048vUid kUoGa7uT7ud9En7uNSfmDpw+xHxB38N986BKBtoeJlGgDYISJkIgr40TIKMLE/Yc whDnmKxT68dfSGcv/DIUzYs+d/OBzSpHIWK87me5QnhmLTQ1xwfwtFoTyk6B3Vzx ljlZFD6e7PJfjo/RIhb0zMvtBvRTONRrMXKRdRY= =serM -----结束 PGP 消息-----

boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL--

--DM1-Sb0636VXPQNO3412Ygegb9suqr--

地图中的嵌入内容:

boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL

内容配置:表单数据; name="version" 内容类型:应用程序/pgp 加密内容长度: 10

版本:1

boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL

内容配置:表单数据; name="payload" 内容类型:应用程序/八位字节流内容长度: 1118

-----BEGIN PGP MESSAGE----- 版本:BCPG v1.47

hQIOA8aa0/bci2e/EAf/fkgOBK+cooeY+44htcvjE9Sxk9RK73aOEaxDOBNqFOsV Nzw1va7cc7wzYOTlHhZV/MkpXq+IrZV316moJu1EAhscN9YmyReVDOzrkzZ1hBmq V2MlAr5/CRqS7nQEmCqy/Mz0STtAPZNg3FOh8F79dJnRws5/SdW+zvn2MoSvGTs3 0YvjmtPq2YyVkMlAvJ62f903UYNIiAcEe1k8gWDVW9LJ4tGud+8H0bsG8EFWPsSI b5rON+MKGykbWGnbSrOy9cqslJaghj91r7ZbsXXXiRn9v4rpOardfiBEnoamI5Tz jfDKESnr7CqoZgb62je+NJrB5puoAwy8LTynXx4cmQgAnf8lb6f+mIxa1U1Mu6iR KNTjrH83Cx2BjTra8E8hu0O7GvuczGfA9NiONmxbglgKK58/QVYdlsZUiGTaWkkY 4nMHiaFe9TiPQ6W2vMGutLFR3V6YSshchCskl6cP1OdaIXCYgzZKIjUWHePzd/ds zCZeNqul1N7iIQ0L5lfSGgfB2eDeeK3JKFjetrrbJQXz0+XeTZLPMSMr6W5Ggq3l PnoJVTrxUd3b2WKgR4FZB+imYRWEz5KLnB5ZVedC+fU24bECcNptrTQaZZUWnR3Z ABJqz8avBrNV0Jf9BaFRxcWkrWyr4KtxDArxXOuMHNvGVtj+hhPZcPGj3N9Xam3E 6snAGEbIiAEivZPYLVVVk0lZW2H0ISwkKkjD8qs7h8wa7Qbchp2K5IyENEzi20oe FNRoCwHyjsCY0nECHCG3WON0EXG2DZDTvA17OoyfuKnRT09FVt3OOEPTV048vUid kUoGa7uT7ud9En7uNSfmDpw+xHxB38N986BKBtoeJlGgDYISJkIgr40TIKMLE/Yc whDnmKxT68dfSGcv/DIUzYs+d/OBzSpHIWK87me5QnhmLTQ1xwfwtFoTyk6B3Vzx ljlZFD6e7PJfjo/RIhb0zMvtBvRTONRrMXKRdRY= =serM

-----结束 PGP 消息-----

boundary2----extKDvsqGExTQI2WVuplHFCUQJ3XVL--

【问题讨论】:

    标签: spring spring-integration


    【解决方案1】:

    不确定您的意思,但我建议调试MultipartAwareFormHttpMessageConverter.readMultipart() 中的代码。那是出现UploadedMultipartFile 的地方。

    【讨论】:

      【解决方案2】:

      快速查看CommonsMultipartResolver 似乎表明它不支持嵌套多部分。

      子类化并覆盖parseRequest() 可能并不难,但您可能还需要深入研究commons-fileupload

      编辑

      关于多部分响应:

      我刚刚patched the http sample 发现,只要请求具有正确的accept 标头,只需返回一个MultiValueMap“就可以”。

      如果您需要对部件标头进行更多控制,则需要继承 AllEncompassingFormHttpMessageConverter 并覆盖 getHttpEntity() 以插入额外的标头并将网关配置为使用自定义适配器。不过,基本标头工作正常 - 这个...

      MultiValueMap<String, Object> map = new LinkedMultiValueMap<>();
      map.add("foo", "Hello");
      map.add("bar", "baz");
      map.add("fiz", "qux".getBytes());
      return map;
      

      ...结果...

      --6_zk8PXoaiUO_By2XJuUpjs5CEEnYM-wj0qE
      Content-Disposition: form-data; name="foo"
      Content-Type: text/plain;charset=ISO-8859-1
      Content-Length: 5
      
      Hello
      --6_zk8PXoaiUO_By2XJuUpjs5CEEnYM-wj0qE
      Content-Disposition: form-data; name="bar"
      Content-Type: text/plain;charset=ISO-8859-1
      Content-Length: 3
      
      baz
      --6_zk8PXoaiUO_By2XJuUpjs5CEEnYM-wj0qE
      Content-Disposition: form-data; name="fiz"
      Content-Type: application/octet-stream
      Content-Length: 3
      
      qux
      --6_zk8PXoaiUO_By2XJuUpjs5CEEnYM-wj0qE--
      

      【讨论】:

      • 谢谢加里。正如建议的那样,我将 CommonsMultipartResolver 子类化并覆盖了 parseRequest() 并且现在能够支持嵌套的多部分。
      • 作为后续,我正在使用带有自定义 multipartResolver 的 http 入站通道适配器。我需要用一个多部分来响应请求。你能推荐一种方法吗?
      • 这正是我需要的谢谢。响应将是“multipart/signed”类型,所以我创建了一个新的 MessageConverter 来处理它。但是,HttpRequestHandlingMessagingGateway 使用请求接受标头来检查转换器是否可以写入而不是我在链中覆盖的内容类型。我尝试在标题丰富器中覆盖 Accept,但这似乎不起作用。
      • 否;它使用原始请求中的accept 标头而不是回复中的值(因为它代表了客户端所说的可以接受的内容)。这就是为什么(在我的测试用例中)我必须更改客户端以在请求中正确设置接受标头;当入站接受为*/* 时,转换器不会转换。当然,在自定义转换器中,您可以选择将 true 返回到canWrite(但您相信客户端可以处理它)。
      • @GaryRussell 您如何处理/接收“fiz”部分?使用如下的多部分文件? @RequestPart("fiz") MultipartFile 文件
      猜你喜欢
      • 2023-03-18
      • 2019-06-23
      • 2011-05-24
      • 1970-01-01
      • 2016-01-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多