【发布时间】:2020-12-28 04:26:54
【问题描述】:
我在尝试将图像上传到我的服务时,来自 Jersey 和 FormDataParam 的行为非常奇怪。我的服务在 Dropwizard 上运行。
接受图像(连同元数据对象)的方法如下所示:
@POST
@Path("/photos")
@Consumes("multipart/form-data")
fun upload(
@FormDataParam("photo") fileInputStream: FileInputStream,
@FormDataParam("metadata") metadata: PhotoMetadataV1RequestModel
) {
// do something
}
我在 Guice 模块中注册了MultipartFeature。
public class JerseyModule extends AbstractModule {
@Override
protected void configure() {
// other stuff
bind(MultiPartFeature.class).in(Scopes.SINGLETON);
}
}
我在build.gradle 中添加了一个jersey-multipart 依赖项。
// Jersey
compile "org.glassfish.jersey.core:jersey-server:$jerseyVersion"
compile "org.glassfish.jersey.media:jersey-media-multipart:$jerseyVersion"
现在是有趣的部分。
如果我尝试使用绝对路径上传文件,这实际上有效!但是,它不起作用我尝试使用相对路径上传文件。
更重要的是,当服务部署在另一台机器上时,它也不起作用(与上传图像请求的来源不同)。这很重要,因为我将服务部署到 Heroku,并且需要从其他地方上传图片!
这是有效的(photo 的绝对路径):
curl --location --request POST "http://localhost:8095/rest/v1/self/photos" \
--header "Authorization: Bearer GaKC8xQju5h" \
--form 'photo=/Users/whizzil/Desktop/nova_scripts/create_users/user-lina/photos-webp/photo-profile-1.webp' \
--form 'metadata={"photoType": "PROFILE", "position": 2};type=application/json'
但是,如果服务器的 url 不是本地主机,即使这样也不起作用,但是例如Heroku 服务器。
这是行不通的(photo 的相对路径):
curl --location --request POST "http://localhost:8095/rest/v1/self/photos" \
--header "Authorization: Bearer GaKC8xQju5h" \
--form 'photo=@./photo-profile-1.webp' \
--form 'metadata={"photoType": "PROFILE", "position": 2};type=application/json'
不工作时抛出的异常:
org.glassfish.jersey.internal.inject.ExtractorException: org.glassfish.jersey.internal.inject.ExtractorException: java.io.FileNotFoundException: Invalid file path
org.glassfish.jersey.media.multipart.FormDataParamException: HTTP 400 Bad Request
at org.glassfish.jersey.media.multipart.internal.FormDataParamValueFactoryProvider$FormDataParamValueFactory.provide(FormDataParamValueFactoryProvider.java:352)
at org.glassfish.jersey.server.spi.internal.ParamValueFactoryWithSource.provide(ParamValueFactoryWithSource.java:71)
at org.glassfish.jersey.server.spi.internal.ParameterValueHelper.getParameterValues(ParameterValueHelper.java:90)
at org.glassfish.jersey.server.model.internal.JavaResourceMethodDispatcherProvider$AbstractMethodParamInvoker.getParamValues(JavaResourceMethodDispatcherProvider.java:127)
我在这里迷路了。我尝试用谷歌搜索所有内容,但没有成功。非常感谢任何帮助!
【问题讨论】:
-
也许是一个幼稚的问题,但为什么在第二个 curl 的
photo属性中使用@字符作为相对路径的后缀?如果我是对的,是否相对路径会在两个请求之间产生差异。 -
所以也许,您可能错误地认为第一个请求有效但无效。顺便说一句,您可以尝试编写不带
./后缀的相对路径。 -
不,第一个请求肯定有效。它返回 200 OK 并且照片最终在数据库中。第二个请求返回 400 Bad Request 并且照片没有最终进入数据库。
-
每次你说“不起作用”,这意味着结果是你发布的异常?
-
@PaulSamsotha 是的,完全正确。输入流确实被读取,但由于某种原因它抛出了无效的文件路径。我知道它会被读取,因为如果我将表单参数从
photo更改为即bla,那么它会抛出InputStream是null。
标签: java http jersey multipartform-data dropwizard