我正在创建一个gcloud http云函数,它必须接收一个带有"medias“字段的” form -data“表单,该字段最多可以包含3个文件,下面是基本代码:
gcloud Java函数:
package functions;
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import java.io.BufferedWriter;
import java.io.IOException;
public class HelloWorld implements HttpFunction {
@Override
public void service(HttpRequest request, HttpResponse response)
throws IOException {
var parts = request.getParts();
parts.forEach(
(e1, e2) -> {
System.out.println(e1);
System.out.println(e2.getFileName().get());
});
}
}我的简单要求是:
curl --location --request POST 'http://localhost:8080/' \
--form 'medias=@"/file1.jpeg"' \
--form 'medias=@"/file2.jpeg"'奇怪的是,"request.getParts();"返回一个"Map<String, HttpPart>",因此我不知道如何检索同一个提交参数的多个文件。在调试过程中,我得到了一个不错的结果:
“com.google.cloud.functions.invoker.http.HttpRequestImpl$HttpPartImpl@49e848cf :重复的关键媒体(尝试合并值java.lang.IllegalStateException)
和
( com.google.cloud.functions.invoker.http .HttpRequestImpl$HttpPartImpl@6d5d7015)“
通过将"Springboot“指定为参数,相同的查询可以正常工作:
@RequestParam(value = "medias", required = false) MultipartFile[] medias那么你认为这是一个有这种依赖性的bug吗?
<dependency>
<groupId>com.google.cloud.functions</groupId>
<artifactId>functions-framework-api</artifactId>
<version>1.0.4</version>
<scope>provided</scope>
</dependency>发布于 2022-01-26 16:46:54
正如这个GCP 文档中所提到的,您可以使用下面的示例代码来处理多部分/表单数据内容类型的数据。
for (HttpRequest.HttpPart httpPart : request.getParts().values()) {
String filename = httpPart.getFileName().orElse(null);
if (filename == null) {
continue;
}
//do something here
}我使用您的场景进行了一些测试,并尝试使用java.util.stream.Collectors操作getParts()方法,以想出类似于Map<String, List<HttpPart>>的解决方案,但失败了。似乎不可能对每个表单数据使用相同的参数键。
我还检查了HttpRequest.getParts()方法的源代码,发现它有自己的方式从表单收集流--当每个数据只有一个键时,表单数据失败,如下所示:
public Map<String, HttpRequest.HttpPart> getParts() {
String contentType = this.request.getContentType();
if (contentType == null || this.request.getContentType().startsWith("multipart/form-data"))
throw new IllegalStateException("Content-Type must be multipart/form-data: " + contentType);
try {
return (Map<String, HttpRequest.HttpPart>)this.request.getParts().stream().collect(Collectors.toMap(Part::getName, x -> new HttpPartImpl(x)));
} catch (IOException e) {
throw new UncheckedIOException(e);
} catch (ServletException e) {
throw new RuntimeException(e.getMessage(), e);
}
}最后,我的建议是对每个表单数据使用“唯一”参数键。
curl --location --request POST 'http://localhost:8080/' --form 'medias[item]=@file1.jpeg' --form 'medias[item1]=@file2.jpeg'
https://stackoverflow.com/questions/70826326
复制相似问题