ton*_*edz 23 java forms jax-rs multipart jersey
我已经成功开发了一项服务,我在其中阅读在泽西岛以多部分形式上传的文件.这是我一直在做的非常简化的版本:
@POST
@Path("FileCollection")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@FormDataParam("file") InputStream uploadedInputStream,
@FormDataParam("file") FormDataContentDisposition fileDetail) throws IOException {
//handle the file
}
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但我得到了一个新的要求.除了我上传的文件外,我还要处理任意数量的资源.我们假设这些是图像文件.
我想我只是为客户端提供一个表单,其中包含一个文件输入,一个输入用于第一个图像,一个按钮允许向表单添加更多输入(使用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>
Run Code Online (Sandbox Code Playgroud)
因此,用户可以为表单添加更多图像输入,如下所示:
<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>
Run Code Online (Sandbox Code Playgroud)
我希望阅读与集合同名的字段非常简单.我在MVC .NET中使用文本输入成功完成了它,我认为在Jersey中不会更难.事实证明我错了.
找不到关于这个主题的教程,我开始尝试.
为了看看如何做到这一点,我把问题简化为简单的文本输入.
<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>
Run Code Online (Sandbox Code Playgroud)
显然,我需要将某种集合作为我方法的参数.这是我尝试过的,按集合类型分组.
起初,我检查了Jersey是否足够智能来处理一个简单的数组:
@POST
@Path("FileCollection")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@FormDataParam("test") String[] inputs) {
//handle the request
}
Run Code Online (Sandbox Code Playgroud)
但阵列未按预期注入.
我悲惨地失败了,我记得MultiValuedMap物体可以开箱即用.
@POST
@Path("FileCollection")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(MultiValuedMap<String, String> formData) {
//handle the request
}
Run Code Online (Sandbox Code Playgroud)
但它也不起作用.这一次,我得到了一个例外
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.
Run Code Online (Sandbox Code Playgroud)
我被告知可以通过包含mimepull库来摆脱这个异常,所以我将以下依赖项添加到我的pom中:
<dependency>
<groupId>org.jvnet</groupId>
<artifactId>mimepull</artifactId>
<version>1.3</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
不幸的是问题仍然存在.这可能是选择正确的身体阅读器和使用不同参数的问题.我不知道该怎么做.我想要同时使用文件和文本输入,以及其他一些(主要是Long值和自定义参数类).
经过一些研究,我找到了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
}
Run Code Online (Sandbox Code Playgroud)
问题是,这是我的问题的简化版本的解决方案.虽然我知道,泽西注入每一个参数是通过在某个点解析字符串创建(难怪,这是HTTP毕竟),我有一些经验写我自己的参数类,我真的不如何将这些领域转化成InputStream或File进一步处理的实例.
因此,在深入了解Jersey源代码以查看这些对象是如何创建之前,我决定在这里询问是否有更简单的方法来读取一组(未知大小)的文件.你知道如何解决这个难题吗?
ton*_*edz 32
我通过以下示例找到了解决方案FormDataMultipart.事实证明我非常接近答案.
的FormDataBodyPart类提供一种方法,其允许其用户读取的值作为InputStream(或理论上,任何其他类,针对其消息体读取器存在的话).
这是最终的解决方案:
表格保持不变.我有几个同名的字段,我可以在其中放置文件.可以使用两种multiple表单输入(在从目录上载许多文件时需要这些输入)和多个共享名称的输入(灵活地从不同位置上载未指定数量的文件).也可以使用JavaScript附加包含更多输入的表单.
<form action="/files" method="post" enctype="multipart/form-data">
<fieldset>
<legend>Multiple inputs with the same name</legend>
<input type="file" name="test" multiple="multiple"/>
<input type="file" name="test" />
<input type="file" name="test" />
</fieldset>
<input type="submit" value="Upload It" />
</form>
Run Code Online (Sandbox Code Playgroud)
FormDataMultipart这是一个从多部分表单中读取文件集合的简化方法.所有具有相同的输入都分配给a,List并InputStream使用getValueAs方法将其值转换为FormDataBodyPart.一旦将这些文件作为InputStream实例,就可以轻松地对它们进行任何操作.
@POST
@Path("files")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadMultipart(FormDataMultiPart multiPart) throws IOException{
List<FormDataBodyPart> fields = multiPart.getFields("test");
for(FormDataBodyPart field : fields){
handleInputStream(field.getValueAs(InputStream.class));
}
//prepare the response
}
private void handleInputStream(InputStream is){
//read the stream any way you want
}
Run Code Online (Sandbox Code Playgroud)
小智 8
@Path("/upload/multiples")
@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces(MediaType.APPLICATION_JSON)
public Response uploadImage(@FormDataParam("image") List<FormDataBodyPart> imageDatas){
for( FormDataBodyPart imageData : imageDatas ){
// Your actual code.
imageData.getValueAs(InputStream.class);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18319 次 |
| 最近记录: |