java文件/图片的上传与下载以及MultipartFile详解

 更新时间:2025年02月13日 15:07:29   作者:越过难题  
文章介绍了MultipartFile类的使用,包括获取文件名、文件类型、文件大小等方法,以及如何处理多文件上传和文件大小限制,同时提供了文件上传和下载的示例代码

一、概述

MultipartFile为org.springframework.web.mutipart包下的一个类,也就是说如果想使用MultipartFile这个类就必须引入spring框架,换句话说,如果想在项目中使用MultipartFile这个类,那么项目必须要使用spring框架才可以,否则无法引入这个类。

MultipartFile翻译成中文来讲就是“多组件的文档”,不用太在乎他的中文含义,一般来讲使用MultipartFile这个类主要是来实现以表单的形式进行文件上传功能。

二、MultipartFile中的方法

getName方法

getName方法获取的是前后端约定的传入文件的参数的名称

getOriginalFileName方法

getOriginalFileName方法获取的是文件的完整名称,包括文件名称+文件拓展名。

getContentType方法

getContentType方法获取的是文件的类型,注意是文件的类型,不是文件的拓展名。

isEmpty方法

isEmpty方法用来判断传入的文件是否为空,如果为空则表示没有传入任何文件。

getSize方法

getSize方法用来获取文件的大小,单位是字节。

getBytes方法

getBytes方法用来将文件转换成一种字节数组的方式进行传输,会抛出IOException异常。

getInputStream方法

getInputStream方法用来将文件转换成输入流的形式来传输文件,会抛出IOException异常。

transferTo方法

transferTo方法用来将接收文件传输到给定目标路径

三、MultipartFile的一些使用技巧

  • (1)我们在使用MultipartFile作为参数传递的时候,可以将MultipartFile声明为一个数组,这样就能支持多文件传输,如果只需要传输一个文件,则去掉数组就好了。
  • (2)可以根据MultipartFile的getSize方法来获取到传输文件的大小,这样就能限定传输过来的文件的大小了。

四、上传代码显示

  • 业务逻辑代码:
package cn.xcy.demo.controller;

import cn.hutool.core.io.FileUtil;
import cn.xcy.demo.FlieUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;

@Slf4j
@RestController
@RequestMapping("/file")
public class FileUploadController {
    /**
     *  上传文件
     *  1、判断文件是否为空
     *  2、获取文件名、文件类型、文件大小(可以限定文件类型、以及文件大小)
     *  3、设置文件上传路径
     *  4、以流的方式将文件输出
     *  5、返回上传成功
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/upload")
    public String uploadImage(@RequestParam("file") MultipartFile file) throws Exception{
        // 判断文件是否为空
        if (file.isEmpty()) {
            return "上传失败";
        }
        //文件类型为
        String contentType = file.getContentType();
        log.info("文件类型为:" + contentType);
        if (contentType.equals("image/jpeg")){
            return "请上传正确格式的文件";
        }
        // 获取原始文件名
        String fileName = file.getOriginalFilename();
        log.info("上传的文件名为:" + fileName);
        try {
            // 将文件保存到指定位置
            byte[] bytes = file.getBytes();
            log.info("文件大小为:" + bytes.length);
            // TODO: 根据业务需求选择合适的存储方式,比如保存到本地磁盘或云存储
//            获取生成后的文件名
            String s = FlieUtils.generateRandomFileName(fileName);
//            将文件保存到指定位置
            FlieUtils.upload(file,"C:\\Users\\liguoming\\Desktop",s);
            return "上传成功";
        } catch (Exception e) {
            e.printStackTrace();
            return "上传失败";
        }
    }

}
  • FlieUtils工具类:
package cn.xcy.demo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.UUID;

@Slf4j
public class FlieUtils {
    /**
     * @param file     文件
     * @param fileName 新的随机文件名
     */
    public static void upload(MultipartFile file, String destPath, String fileName) {
        File dest = new File(destPath + File.separator + fileName);
        //判断文件父目录是否存在
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            //保存文件
            file.transferTo(dest);
        } catch (Exception e) {
            log.info("Save file exception. {}", e.getMessage());
        }

    }

    /**
     * 输出文件的后缀名
     * @param fileName
     * @return
     */
    public static String getSuffix(String fileName) {
//        fileName.substring(fileName.lastIndexOf("."))
//        是C#中的字符串操作,它的作用是从文件名字符串中截取最后一个点(.)及其后面的所有字符。这个操作可以用来获取文件的扩展名。
        return fileName.substring(fileName.lastIndexOf("."));
    }

    /**
     * 输出文件的新名称 (名字+后缀名)
     * @param fileName
     * @return
     */
    public static String generateRandomFileName(String fileName) {
        return UUID.randomUUID() + getSuffix(fileName);
    }

    /**
     * @param name
     * @Description 设置响应头部信息
     * @Throws
     * @Return java.lang.String
     * @Date 2023-08-02 13:39:15
     * @Author lgm
     */
    public static String fileContentType(String name) {
        String result = "";
        String fileType = name.toLowerCase();
        if (fileType.endsWith(".png")) {
            result = "image/png";
        } else if (fileType.endsWith(".gif")) {
            result = "image/gif";
        } else if (fileType.endsWith(".jpg") || fileType.endsWith(".jpeg")) {
            result = "image/jpeg";
        } else if (fileType.endsWith(".svg")) {
            result = "image/svg+xml";
        } else if (fileType.endsWith(".doc")) {
            result = "application/msword";
        } else if (fileType.endsWith(".xls")) {
            result = "application/x-excel";
        } else if (fileType.endsWith(".zip")) {
            result = "application/zip";
        } else if (fileType.endsWith(".pdf")) {
            result = "application/pdf";
        } else if (fileType.endsWith(".mpeg")) { //MP3
            result = "audio/mpeg";
        } else if (fileType.endsWith(".mp4")) {
            result = "video/mp4";
        } else if (fileType.endsWith(".plain")) {
            result = "text/plain";
        } else if (fileType.endsWith(".html")) {
            result = "text/html";
        } else if (fileType.endsWith(".json")) {
            result = "application/json";
        } else{
            result = "application/octet-stream";
        }
        return result;
    }
}

五、下载的代码显示

  • 业务逻辑代码:
/**
     *  下载文件
     *  1、需要传入文件名称
     *  2、先将文件的存放路径+名称获取到
     *  3、设置响应头,告诉浏览器需要下载文件夹
     *  4、设置响应体,将文件读取出来,写入到响应体中
     *  5、response.getOutputStream()  输出字节流, 客户端会下载字节流并生成文件保存本地
     * @param filename
     * @param response
     * @return
     * @throws IOException
     */
    @RequestMapping("/fileload")
    public String fileload(@RequestParam("filename")String filename, HttpServletResponse response) throws IOException {
        // 文件的存放位置
        String filePath = "C:\\Users\\liguoming\\Desktop\\" + filename;
        File file = new File(filePath);
        // 设置响应头,告诉浏览器要下载文件
        // response.setContentType()是设置响应类型的 浏览器读取的是什么文件 依据文件类型,告诉浏览器接下来要做的是什么
        // application/octet-stream  告诉浏览器需要下载二进制流数据(如常见的文件下载)
        response.setContentType("application/octet-stream");
        /**
         * response.setHeader("Content-Disposition", "attachment; filename=" +new String( filename.getBytes("gb2312"), "ISO8859-1" ));
         * 在确保附件文件名都是简体中文字的情况下,那么这个办法确实是最有效的,不用让客户逐个的升级IE。
         * 如果台湾同胞用,把gb2312改成big5就行。但现在的系统通常都加入了 国际化的支持,普遍使用UTF-8。
         * 如果文件名中又有简体中文字,又有繁体中文,还有日文。那么乱码便产生了。另外,在上Firefox (v1.0-en)下载也是乱码。
         */
        response.setHeader("Content-Disposition", "attachment; filename=" +new String( filename.getBytes("gb2312"), "ISO8859-1" ));
        //response.getOutputStream()  输出字节流, 客户端会下载字节流并生成文件保存本地
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(FileUtil.readBytes(file));
        outputStream.close();
        return "success";
    }

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • JDBC连接MYSQL分步详解

    JDBC连接MYSQL分步详解

    JDBC是指Java数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,本篇文章我们来了解MySQL连接JDBC的流程方法
    2022-03-03
  • JVM内存结构相关知识解析

    JVM内存结构相关知识解析

    这篇文章主要介绍了JVM内存结构相关知识解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • Java8新特性Stream流中anyMatch和allMatch和noneMatch的区别解析

    Java8新特性Stream流中anyMatch和allMatch和noneMatch的区别解析

    这篇文章主要介绍了Java8新特性Stream流中anyMatch和allMatch和noneMatch的区别解析,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • mybatis接收以逗号分隔的字符串批量查询方式

    mybatis接收以逗号分隔的字符串批量查询方式

    这篇文章主要介绍了mybatis接收以逗号分隔的字符串批量查询方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-01-01
  • 使用Post方法模拟登陆爬取网页的实现方法

    使用Post方法模拟登陆爬取网页的实现方法

    下面小编就为大家带来一篇使用Post方法模拟登陆爬取网页的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • JAVA装饰者模式(从现实生活角度理解代码原理)

    JAVA装饰者模式(从现实生活角度理解代码原理)

    装饰者模式可以动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。这篇文章主要介绍了JAVA装饰者模式的相关资料,需要的朋友可以参考下
    2016-12-12
  • SpringBoot集成P6Spy的实现示例

    SpringBoot集成P6Spy的实现示例

    本文主要介绍了SpringBoot集成P6Spy的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-08-08
  • java正则表达式实现提取需要的字符并放入数组【ArrayList数组去重复功能】

    java正则表达式实现提取需要的字符并放入数组【ArrayList数组去重复功能】

    这篇文章主要介绍了java正则表达式实现提取需要的字符并放入数组,即基于正则的ArrayList数组去重复功能,具有一定参考借鉴价值,需要的朋友可以参考下
    2017-01-01
  • 详解@ConfigurationProperties如何装载到Spring容器中

    详解@ConfigurationProperties如何装载到Spring容器中

    这篇文章主要为大家详细介绍了@ConfigurationProperties该如何装载到Spring容器中,文中的示例代码讲解详细,需要的小伙伴可以参考一下
    2023-07-07
  • log4j使用教程详解(怎么使用log4j2)

    log4j使用教程详解(怎么使用log4j2)

    Log4j 2的好处就不和大家说了,如果你搜了2,说明你对他已经有一定的了解,并且想用它,所以这里直接就上手了
    2013-12-12

最新评论