当前位置: 首页 > 面试题库 >

如何从Jersey的多部分表单中读取多个具有相同名称的(文件)输入?

魏彦
2023-03-14
问题内容

我已经成功开发了一项服务,可以读取在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
}

这个工作很好,但是给了我一个新的要求。除了要上传的文件之外,我还必须处理任意数量的资源。让我们假设这些是图像文件。

我想我只是为客户提供一个表单,其中包含一个文件输入,一个输入用于第一个图像以及一个按钮,以允许向该表单添加更多输入(使用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中的文本输入成功完成了此操作,并且我认为在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>

显然,我需要某种类型的集合作为方法的参数。这是我尝试过的方法,按集合类型分组。

数组

首先,我检查了Jersey是否足够聪明以处理一个简单的数组:

@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.

有人告诉我,可以通过包含mimepull库来消除此异常,因此我在pom中添加了以下依赖项:

    <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),并且我有编写自己的参数类的经验,但我并没有真正将这些字段转换为InputStreamFile需要进一步处理的实例

因此,在探究Jersey源代码以查看如何创建这些对象之前,我决定在这里询问是否有一种更简便的方法来读取一组(未知大小)文件。你知道如何解决这个难题吗?


问题答案:

我已经通过跟随示例找到了解决方案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>

服务-使用

FormDataMultipart

这是一种简化的方法,可从多部分表单中读取文件集合。所有具有相同输入的输入都分配给a,ListInputStream使用的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
}


 类似资料:
  • 我已经成功地开发了一项服务,在该服务中,我阅读了在泽西岛以多部分形式上传的文件。以下是我所做工作的一个极其简化的版本: 这很好,但我有一个新的要求。除了上传的文件,我还需要处理任意数量的资源。假设这些是图像文件。 我想我应该为客户端提供一个表单,其中包含文件的一个输入,第一个图像的一个输入,以及允许向表单添加更多输入的按钮(使用AJAX或简单的纯JavaScript)。 因此,用户可以在表单中附加

  • 问题内容: 如果类路径中有两个JAR文件,两个文件的根中都包含一个名为“ config.properties”的资源。有没有办法检索类似于的 两个 文件?顺序不相关。 一种替代方法是,如果可能的话,在类路径中加载与某些条件匹配的每个属性文件。 问题答案: 您需要 (或静态版本)。 但是不幸的是,资源不在“目录”中存在一个已知问题。例如,可以,但是可能是一个问题。在Spring Reference中

  • 问题内容: 我有一个PHP应用程序,有时需要处理URL,其中URL中的多个参数具有相同的名称。是否有一种简单的方法来检索给定键的所有值?PHP $ _GET仅返回最后一个值。 具体来说,我的应用程序是一个OpenURL解析器,可能会获得如下URL参数: (是的,我知道这很丑陋,欢迎来到我的世界)。请注意,键“ rft_id”出现两次: 将返回just ,先前的值()已被覆盖。 我想同时访问这两个值

  • 问题内容: 给定上面的xml文件,我将如何检索标签内所有标签的列表?我想获取“名称”的所有值以及标签之间的数字值。像这样: 问题是我不知道会有多少个附加标签。可能没有,也可能有20。我需要某种方法来对它们全部进行计数,然后删除信息。 问题答案: 这是一个使用JDK执行查询的示例。它假定变量包含您的XML文档。

  • 问题内容: 是否可以获取多个具有相同名称的输入,然后从PHP访问它们?想法是这样的:我有一个表格,可以输入不确定数量的物理地址以及其他信息。如果我只是在几个条目中为每个字段赋予相同的名称,然后通过post提交该数据,PHP是否可以访问它? 举例来说,我在一个名为“ xyz”的页面上有五个输入,我想使用PHP访问它们。我可以做些什么: 如果是这样,那将使我的生活变得轻松十倍,因为我可以通过一个表单发

  • 问题内容: 我有一个像这样的excel文件: 如您所见,两列的标题具有相同的名称 -Name 2 。 我的问题是,是否可以告诉ADO引擎从哪一列中选择数据? 目前,我的选择如下所示: ADO从excel中的列下列出的列中提取数据。换句话说,它采用具有给定名称的第一列。不幸的是,我有两个具有相同名称的列,我想从column中提取数据。是否有可能? 我找不到任何通过其索引而不是名称来选择列的方法。 问