springboot关于文件的操作

309 阅读3分钟

前言

文件上传与下载

其实所有传输文件的原理都和http报文有关 举个例子 httpServletResponse.setContentType("image/png");

常见的媒体格式类型如下:

text/html : HTML格式

text/plain :纯文本格式

text/xml : XML格式

image/gif :gif图片格式

image/jpeg :jpg图片格式

image/png:png图片格式

以application开头的媒体格式类型:

application/xhtml+xml :XHTML格式

application/xml: XML数据格式

application/atom+xml :Atom XML聚合格式

application/json: JSON数据格式

当我们使用@Responsebody注解时,返回值为就是自动转换为string字符串(符合json格式的字符串)然后写入响应体

application/pdf:pdf格式

application/msword : Word文档格式

application/octet-stream : 二进制流数据(如常见的文件下载)

application/x-www-form-urlencoded :

中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)

另外一种常见的媒体格式是上传文件之时使用的: multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式

工具类

public enum ContentTypeUtil {
    HTML("text/html;charset=UTF-8"),
    PLAIN("text/plain;charset=UTF-8"),
    MP3("audio/mp3"),
    MP4("audio/mp4"),
    XML_TEXT("text/xml"),
    GIF("image/gif"),
    JPEG("image/jpeg"),
    PNG("image/png"),
    XHTML("application/xhtml+xml"),
    XML_APPLICATION("application/xml"),
    ATOMXML("application/atom+xml"),
    JSON("application/json"),
    PDF("application/pdf"),
    WORD("application/msword"),
    //二进制数据流,文件下载
    DOWLOAD("application/octet-stream"),
    X_WWW_FORM_URLENCODE("application/x-www-form-urlencoded"),
    MULTIPART_FORM_DATA("multipart/form-data");
    String contentType;
    private ContentTypeUtil(String contentType)
    {
        this.contentType=contentType;
    }
    public String getContentType()
    {
        return contentType;
    }
}

如果开发者没有提供MultipartResovler,那么默认采用的是MultipartResovler就是StandardServletMultipartResovler,因此springboot文件上传可以零配置

对图片上传的细节配置

//是否支持 multipart 上传文件,默认true
spring.servlet.multipart.enabled=true
//文件写入磁盘的阈值,默认为0
spring.servlet.multipart.file-size-threshold=0
//上传文件的临时目录
spring.servlet.multipart.location=
//最大大支持文件大小,默认为1mb
spring.servlet.multipart.max-file-size=10Mb
//多文件上传时的总大小。默认为10mb
spring.servlet.multipart.max-request-size=10Mb
//是否支持 multipart 上传文件时懒加载,是否延迟解析,默认false
spring.servlet.multipart.resolve-lazily=false

1单文件上传

先建立一个upload.html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFile" value="请选择文件" multiple>
    <input type="submit" value="上传">
</form>
</body>
</html>

对应控制器

    @PostMapping("/upload")
    public String upload(MultipartFile uploadFile, HttpServletRequest req) {
        //保存
        String realPath = req.getSession().getServletContext().getRealPath("/uploadFile/");
        System.out.println(realPath);
        String format = sdf.format(new Date());
        File folder = new File(realPath + format);
        if (!folder.isDirectory()) {
            folder.mkdirs();
        }
        //重命名
        String oldName = uploadFile.getOriginalFilename();
        String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
        try {
            //保存
            uploadFile.transferTo(new File(folder, newName));
            //返回路径
            String filePath = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/uploadFile/" + format + newName;
            return filePath;
        } catch (IOException e) {
//            e.printStackTrace();
        }
        return "上传失败!";
    }

2多文件上传

对应html就是改了个接口

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/uploads" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFile" value="请选择文件" multiple>
    <input type="submit" value="上传">
</form>
</body>
</html>

对应控制器,多了一个遍历的过程

@PostMapping("/uploads")
    public String upload(MultipartFile[] uploadFiles, HttpServletRequest req) {
        for (MultipartFile uploadFile : uploadFiles) {
            String realPath = req.getSession().getServletContext().getRealPath("/uploadFile/");
            System.out.println(realPath);
            String format = sdf.format(new Date());
            File folder = new File(realPath + format);
            if (!folder.isDirectory()) {
                folder.mkdirs();
            }
            String oldName = uploadFile.getOriginalFilename();
            String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."), oldName.length());
            try {
                uploadFile.transferTo(new File(folder, newName));
                String filePath = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/uploadFile/" + format + newName;
//            return filePath;
                System.out.println(filePath);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "上传失败!";
    }

3文件下载

 @RequestMapping("/test/download")
    public void test3(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
    {
        httpServletResponse.setContentType("application/octet-stream");
        File file = new File("C:\\Users\\10756\\Desktop\\test.doc");
        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            //如果filename带有中文应该使用URLEncoder.encode(file.getFilename(), "utf-8")
            //否则会导致名称变为下划线
            httpServletResponse.setHeader("Content-Disposition", "attachment; filename="+UUID.randomUUID().toString());
           
            IOUtils.copy(fileInputStream, httpServletResponse.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

4向前端传输一个照片

@RequestMapping("/test/jpg")
    public void test2(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse)
    {
        httpServletResponse.setContentType("image/png");
        try {
            FileInputStream fileInputStream = new FileInputStream("C:\\Users\\10756\\Desktop\\test.png");
            IOUtils.copy(fileInputStream, httpServletResponse.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }