@MultipartForm 如何获取原始文件名?

Posted

技术标签:

【中文标题】@MultipartForm 如何获取原始文件名?【英文标题】:@MultipartForm How to get the original file name? 【发布时间】:2014-12-07 14:57:08 【问题描述】:

我正在使用 jboss 的 rest-easy multipart 提供程序来导入文件。我在这里阅读了http://docs.jboss.org/resteasy/docs/1.0.0.GA/userguide/html/Content_Marshalling_Providers.html#multipartform_annotation 关于@MultipartForm 的内容,因为我可以将它与我的 POJO 精确映射。

下面是我的POJO

public class SoftwarePackageForm 

    @FormParam("softwarePackage")
    private File file;

    private String contentDisposition;

    public File getFile() 
        return file;
    

    public void setFile(File file) 
        this.file = file;
    

    public String getContentDisposition() 
        return contentDisposition;
    

    public void setContentDisposition(String contentDisposition) 
        this.contentDisposition = contentDisposition;
    

然后我得到了文件对象并打印了它的绝对路径,它返回了一个文件类型的文件名。扩展名和上传的文件名丢失。我的客户正在尝试上传存档文件(zip,tar,z)

我在服务器端需要此信息,以便我可以正确应用取消归档程序。

原始文件名在 content-disposition 标头中发送到服务器。

我怎样才能得到这些信息?或者至少我怎么能说 jboss 用上传的文件名和扩展名保存文件?它可以从我的应用程序中配置吗?

【问题讨论】:

您可以尝试将@PartType("application/zip") 添加到您的file 中,看看是否有效?完整包是org.jboss.resteasy.annotations.providers.multipart.PartType @isim 是的,我会尝试的。 tar 和 Z 文件的价值是什么? @isim 没用 :( 没用。我不明白为什么人们在不提供原始 api 提供的所有功能时包装 api。他们说可以做得更好,他们提供了 api,他们引入了更多问题,当我们知道这一点时,我们被锁定了。我从近 3 天开始就在做这个,受够了。 【参考方案1】:

在查看了包括 one 在内的 Resteasy 示例后,似乎在使用带有 @MultipartForm 注释的 POJO 类时无法检索原始文件名和扩展名信息。

到目前为止,我所看到的示例通过 HTTP POST 从提交的多部分表单数据的“文件”部分中从 Content-Disposition 标头中检索文件名,基本上看起来类似于:

Content-Disposition: form-data; name="file"; filename="your_file.zip"
Content-Type: application/zip

您必须更新您的文件上传 REST 服务类来提取此标头,如下所示:

@POST
@Path("/upload")
@Consumes("multipart/form-data")
public Response uploadFile(MultipartFormDataInput input) 

  String fileName = "";
  Map<String, List<InputPart>> formParts = input.getFormDataMap();

  List<InputPart> inPart = formParts.get("file"); // "file" should match the name attribute of your HTML file input 
  for (InputPart inputPart : inPart) 
    try 
      // Retrieve headers, read the Content-Disposition header to obtain the original name of the file
      MultivaluedMap<String, String> headers = inputPart.getHeaders();
      String[] contentDispositionHeader = headers.getFirst("Content-Disposition").split(";");
      for (String name : contentDispositionHeader) 
        if ((name.trim().startsWith("filename"))) 
          String[] tmp = name.split("=");
          fileName = tmp[1].trim().replaceAll("\"","");          
        
      

      // Handle the body of that part with an InputStream
      InputStream istream = inputPart.getBody(InputStream.class,null);

      /* ..etc.. */
       
    catch (IOException e) 
      e.printStackTrace();
    
  

  String msgOutput = "Successfully uploaded file " + filename;
  return Response.status(200).entity(msgOutput).build();

希望这会有所帮助。

【讨论】:

是的,我已经退回到这种方法。我也在他们的论坛中提出了一个问题issues.jboss.org/browse/RESTEASY-1115。感谢您的努力。【参考方案2】:

您可以使用@PartFilename,但不幸的是,这目前仅用于编写表单,而不是读取表单:RESTEASY-1069。

在解决此问题之前,您可以使用 MultipartFormDataInput 作为资源方法的参数。

【讨论】:

【参考方案3】:

如果您使用 MultipartFile 类,则可以执行以下操作:

MultipartFile multipartFile;
multipartFile.getOriginalFilename();

【讨论】:

【参考方案4】:

Isim 似乎是对的,但有一个变通方法。

在表单中创建一个隐藏字段并使用所选文件的名称更新其值。提交表单时,文件名将作为@FormParam 提交。

这是您可能需要的一些代码(需要 jquery)。

<input id="the-file" type="file" name="file">
<input id="the-filename" type="hidden" name="filename">

<script>
$('#the-file').on('change', function(e) 
    var filename = $(this).val();
    var lastIndex = filename.lastIndexOf('\\');
    if (lastIndex < 0) 
        lastIndex = filename.lastIndexOf('/');
    
    if (lastIndex >= 0) 
        filename = filename.substring(lastIndex + 1);
    
    $('#the-filename').val(filename);
);
</script>

【讨论】:

以上是关于@MultipartForm 如何获取原始文件名?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 alamofire multipartform 中发送数组参数?

使用 Undertow 的多部分表单数据示例

如何从麦克风实时获取原始音频帧或从 iOS 中保存的音频文件获取原始音频帧?

如何从原始文件夹中获取 json 文件?

如何使用 UIDocumentPickerViewController 获取原始文件名?

为什么Multipartform-data在响应Mule Dataweave时删除Nill?