Spring Scala MultipartEntityBuilder没有为弹簧静止点正确创建边界

Spring Scala MultipartEntityBuilder没有为弹簧静止点正确创建边界,spring,scala,post,httpclient,multipartform-data,Spring,Scala,Post,Httpclient,Multipartform Data,我有一个由多个主体部分组成的请求主体,下面是我如何使用scala中的multipartentitybuilder库在scala中处理它 val data=MultipartEntityBuilder.create() .setMode(HttpMultipartMode.BROWSER_兼容) .addPart(“实际标题”,新的StringBody(actualHeader,ContentType.APPLICATION_JSON)) .addBinaryBody(“有效负载”,请求主体) .

我有一个由多个主体部分组成的请求主体,下面是我如何使用scala中的multipartentitybuilder库在scala中处理它

val data=MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_兼容)
.addPart(“实际标题”,新的StringBody(actualHeader,ContentType.APPLICATION_JSON))
.addBinaryBody(“有效负载”,请求主体)
.build()

对于上下文,二进制体是需要发送到此post请求的avro事件的字节[]

在尝试通过httpPost将该实体发送到SpringREST端点时,我得到了以下异常响应

org.springframework.web.multipart.MultipartException:解析多部分servlet请求失败;嵌套异常为java.io.IOException:org.apache.tomcat.util.http.fileupload.FileUploadException:请求被拒绝,因为未找到多部分边界

我尝试过的:

  • 我尝试使用.setBoundary()手动添加边界,但没有帮助
  • 在网上提供的其他解决方案中还有另一条路要走。我可以去掉ContentType.Application-JSON的标题,但是在API级别删除它会失败,因为它们有对它的检查,所以这也不起作用
  • 我尝试添加二进制体作为一部分,以使其一致,这使代码看起来像这样
val data=MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_兼容)
.addPart(“事件头”,新的StringBody(eventHeader,ContentType.APPLICATION_JSON))
.addPart(“有效负载”,新的ByteArrayBody(requestBody,ContentType.DEFAULT_BINARY,null.asInstanceOf[String]))
.build()

  • 试图让multipartEntityBuilder创建textbody(用于JSON部分) 和bytearray作为有效负载部分,并使用以下代码除去内容类型
val data=MultipartEntityBuilder.create()
.边界(边界)
.addTextBody(“事件头”,eventHeader,ContentType.APPLICATION_JSON”).addBinaryBody(“有效载荷”,requestBody,ContentType.DEFAULT_BINARY,null.asInstanceOf[String])
.build()

这让我更进一步,因为它自动检测到ContentType为
多部分/表单数据
,但当我将Entity设置为post时,它没有将该信息传输到post,并且仍然没有正确地将边界指定为标题中内容类型的一部分

  • 还尝试从文件中添加头,确保两个主体在本质上与以下代码一致
val file=new文件(“eventHeader.json”)
val data=MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_兼容)
.addBinaryBody(“事件头”,文件,ContentType.APPLICATION_JSON,“eventHeader.JSON”)
.addBinaryBody(“Avro有效负载”,请求主体)
.build()

不走运

有关更多上下文和信息,下面是POST请求的其他属性

val post = new HttpPost(url);
val client: CloseableHttpClient = HttpClientBuilder.create().build();
post.setConfig(requestConfig)
post.setHeader("Content-type", "multipart/form-data")
post.setEntity(data)

val response: HttpResponse = client.execute(post)
另一条信息,当我在IntelliJ中调试实体时,它向我显示了一个创建的边界,但我在内容的任何地方都看不到它。(不确定此信息有多大帮助)

现在,引用springframework是一个例外,我一直怀疑scala在这方面做得不好。然而,我们已经成功地在scala中实现了gatling测试场景,所以实现这一点并非完全不可能


因此,我现在向社区的专业人员投降,告诉他们如何在不太具侵入性的情况下解决这一问题,因为这将是spark服务的一部分,所以我们不要忽视数据分发方面的问题

我最终通过从最初生成的数据的内容类型中简单地添加边界来使用它

下面是我如何更改我的代码以通过请求

val file=new文件(“testHeader.json”)


简单的解决方案,但有点变通,因为某种原因(我不知道),当我根本没有设置内容类型时,它没有自动检测类型。希望这能在将来的某个时候帮助像我这样的可怜虫。

非常感谢你的解决方案。在我的例子(Java+Apache Camel)中,我必须更明确地设置边界,方法是使用
builder.setBoundary(“BLA-BLA”)
setHeader(“内容类型”,“多部分/表单数据;边界=BLA-BLA”)
   val data = MultipartEntityBuilder.create()
  .setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
  .addBinaryBody("Event Header",file,ContentType.APPLICATION_JSON,"testHeader.json")
  .addBinaryBody("Avro Payload",requestBody)
  .build()
val client: CloseableHttpClient = HttpClientBuilder.create().build();

val APIUrl = url

val post = new HttpPost(APIUrl);
post.setConfig(requestConfig)
post.setHeader(data.getContentType)
post.setEntity(data)