zoukankan      html  css  js  c++  java
  • MultipartFile的使用小结

    Multipartfile转File?File转MultipartFile?可千万别转晕了。

    题图:from Google

    1. MultipartFile类型转File类型

    想要将MultipartFile类型转为File类型可以使用MultipartFile提供的方法:
    void MultipartFile.transferTo(File dest) throws IOException, IllegalStateException

    1
    2
    3
    4
    5
    6
    File destFile = new File("tmp/source/destFile");
    if (!fileSourcePath.exists()) {
    fileSourcePath.mkdirs();
    }
    // 将MultipartFile存到临时文件中
    mulFileSource.transferTo(destFile);

    2. File类型转Multipartfile

    MultipartFile接口有两个常用实现类,MockMultipartFile和CommonsMultipartFile。

    • 使用MockMultipartFile
      看名字就知道MockMultipartFile主要用于测试用途,但是相对CommonsMultipartFile来说,创建相当简便。

      1
      2
      3
      4
      5
      6
      7
      File file = new File("/Users/coderec/Desktop/haha.jpg");
      MultipartFile mulFile = new MockMultipartFile(
      "haha.jpg", //文件名
      "haha.jpg", //originalName 相当于上传文件在客户机上的文件名
      ContentType.APPLICATION_OCTET_STREAM.toString(), //文件类型
      new FileInputStream(file) //文件流
      );
    • 使用CommonsMultipartFile
      与MockMultipartFile相比,CommonsMultipartFile仅仅有一个构造方法:
      CommonsMultipartFile(FileItem fileItem)
      因此,若要使用CommonsMultipartFile来创建MultipartFile就一定要使用FileItem。通过FileItem将File转化为MultipartFile的过程如下伪代码所示:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      File file = new File("temp/fileItem/haha.jpg");
      if (!file.exists()) {
      file.mkdirs();
      }
      // 创建fileItem,具体方法参见第三节
      FileItem fileItem = new ...;
      // 将File内容写入fileItem,使用org.apache.commons.io.IOUtils
      IOUtils.copy(new FileInputStream(file), fileItem.getOutputStream());
      // 创建multipartfile
      MultipartFile multipartFile = new CommonsMultipartFile(fileItem);

    3. 如何创建FileItem?

    FileItem接口只有一个实现类:DiskFileItem

    • 直接使用DiskFileItem创建

      1
      2
      3
      4
      5
      6
      7
      8
      9
      // 创建fileItem
      FileItem fileItem = new DiskFileItem(
      "file", // 表单参数名
      ContentType.APPLICATION_OCTET_STREAM.toString(), // 文件类型
      false, // 是否为表单格式
      RandomKeyUtils.genRandomKey() + ".jpg", // 文件名
      10240, // 超过多少byte存在磁盘上
      new file("tmp/fileItem/") // 文件存储位置
      );
    • 使用DiskFileItemFactory创建

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      // 小于5M文件都在内存中,否则存入硬盘
      final int tmpFileSize = 5242880;
      // 设置临时文件大小以及临时文件存储路径
      DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(tmpFileSize, new file("tmp/fileItem/"));
      // 创建fileItem
      FileItem fileItem = fileItemFactory.createItem(
      "file", // 表单参数名
      ContentType.APPLICATION_OCTET_STREAM.toString(), // 文件类型
      false, // 是否为表单格式
      RandomKeyUtils.genRandomKey() + ".jpg" // 文件名
      );

    4. DiskFileItem产生的临时文件处理

    • 使用内存存储,不写入硬盘
      在创建FileItem时,可以设定一个较大的文件大小,使文件不被写入硬盘,就不会产生临时文件的问题。不过这不是一个正确的解决问题的方式。而且,也会受到内存大小限制。
    • 使用FileCleaningTracker
      在使用DiskFileItemFactory时,应该会发现其有一个void setFileCleaningTracker(FileCleaningTracker pTracker)方法,此方法就是为临时文件设置监听线程,一旦发现临时文件被垃圾回收,就会清除临时文件。
      我们可以通过FileCleanerCleanup监听器以及ServletContext获得监听线程FileCleaningTracker。

    为FileItem设置监听的过程如下:

    1
    2
    3
    4
    5
    FileCleaningTracker fileCleaningTracker
    = FileCleanerCleanup.getFileCleaningTracker(servletContext);
    DiskFileItemFactory factory
    = new DiskFileItemFactory(10240, File("tmp/fileItem/");
    factory.setFileCleaningTracker(fileCleaningTracker);

    在不需要监听线程FileCleaningTracker时,应该将其停止。可以在web.xml中进行如下配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    <web-app>
    ...
    <listener>
    <listener-class>
    org.apache.commons.fileupload.servlet.FileCleanerCleanup
    </listener-class>
    </listener>
    ...
    </web-app>
    • 获取ServletContext方法
      1. 普通Servlet中
        使用HttpServletRequest
        request.getSession().getServletContext()
      2. SpringMVC的Controller中
        使用SpringMVC提供的方法
        1
        2
        WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
        ServletContext servletContext = webApplicationContext.getServletContext();
  • 相关阅读:
    微信小程序支付【前端】
    CSS主题切换
    利用Proxy写了个存储管理
    前端存储cookie操作
    canvas电子签名和播放划线
    【原创】[Ext.ux.UploadDialog] 控件使用说明及在Ext 3.x下问题解决
    【原创】分享一组VC++底层图像处理函数
    【转发】SQL Server数据库被质疑解决方案
    SVN 解决update失败出现乱码提示或工作副本已经锁定
    Qt 外部子模块的3种使用方法,以QtXlsx为例
  • 原文地址:https://www.cnblogs.com/qiumingcheng/p/7460731.html
Copyright © 2011-2022 走看看