如何从泽西岛的多部分表单中读取多个具有相同名称的(文件)输入?
我已成功开发了一项服务,其中我读取在泽西岛以多部分形式上传的文件。以下是我一直在做的一个非常简化的版本:
@POST
@Path("FileCollection")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException {
//handle the file
}
这工作得很好,但我得到了一个新的要求。除了我要上传的文件之外,我还必须处理任意数量的资源。让我们假设这些是图像文件。
我想我只是向客户端提供一个表单,其中包含一个文件输入,一个用于第一个图像的输入和一个按钮,以允许向表单添加更多输入(使用AJAX或简单的纯JavaScript)。
<form action="blahblahblah" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="file" name="image" />
<input type="button" value="add another image" />
<input type="submit" />
</form>
因此,用户可以在表单中附加更多图像输入,如下所示:
<form action="blahblahblah" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="file" name="image" />
<input type="file" name="image" />
<input type="file" name="image" />
<input type="button" value="add another image" />
<input type="submit" />
</form>
我希望它足够简单,可以读取与集合同名的字段。我已经在MVC .NET中成功地完成了文本输入,我认为在泽西岛不会更难。事实证明我错了。
在没有找到有关该主题的教程后,我开始尝试。
为了了解如何做到这一点,我将问题归结为简单的文本输入。
<form action="blahblabhblah" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Multiple inputs with the same name</legend>
<input type="text" name="test" />
<input type="text" name="test" />
<input type="text" name="test" />
<input type="text" name="test" />
<input type="submit" value="Upload It" />
</fieldset>
</form>
显然,我需要有某种集合作为我的方法的参数。以下是我尝试过的内容,按集合类型分组。
数组
起初,我检查了泽西岛是否足够聪明,可以处理一个简单的数组:
@POST
@Path("FileCollection")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@FormDataParam("test") String[] inputs) {
//handle the request
}
但数组未按预期注入。
多值地图
在惨败之后,我想起了可以开箱即用地处理对象。MultiValuedMap
@POST
@Path("FileCollection")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(MultiValuedMap<String, String> formData) {
//handle the request
}
但它也不起作用。这次,我遇到了一个例外
SEVERE: A message body reader for Java class javax.ws.rs.core.MultivaluedMap,
and Java type javax.ws.rs.core.MultivaluedMap<java.lang.String, java.lang.String>,
and MIME media type multipart/form-data;
boundary=----WebKitFormBoundaryxgxeXiWk62fcLALU was not found.
我被告知可以通过包含库来消除此异常,因此我在pom中添加了以下依赖项:mimepull
<dependency>
<groupId>org.jvnet</groupId>
<artifactId>mimepull</artifactId>
<version>1.3</version>
</dependency>
不幸的是,问题仍然存在。这可能是选择正确的正文阅读器并为泛型使用不同参数的问题。我不知道该怎么做。我想同时使用文件和文本输入,以及其他一些输入(主要是值和自定义参数类)。Long
FormDataMultipart
经过进一步的研究,我发现了FormDataMultiPart类。我已成功使用它从表单中提取字符串值
@POST
@Path("upload2")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadMultipart(FormDataMultiPart multiPart){
List<FormDataBodyPart> fields = multiPart.getFields("test");
System.out.println("Name\tValue");
for(FormDataBodyPart field : fields){
System.out.println(field.getName() + "\t" + field.getValue());
//handle the values
}
//prepare the response
}
问题是,这是我的问题的简化版本的解决方案。虽然我知道Jersey注入的每个参数都是通过在某个时候解析字符串创建的(难怪,毕竟它是HTTP),并且我有一些编写自己的参数类的经验,但我并没有真正如何将这些字段转换为或实例以进行进一步处理。InputStream
File
因此,在深入研究泽西岛源代码以了解这些对象是如何创建的之前,我决定在这里询问是否有更简单的方法来读取一组(未知大小)的文件。你知道如何解决这个难题吗?