欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

文件的上传与下载

程序员文章站 2022-06-18 17:38:09
...

文件上传下载原理

在TCP/IP中,最早出现的文件上传机制是FTP。它是将文件由客户端发送到服务器的标准机制。

但是在jsp编程中不能使用FTP方法来上传文件,这是由jsp运行机制所决定的

文件上传原理:

通过为表单元素设置Method=“post” enctype=“multipart/form-data”属性,让表单提交的数据以二进制编码的方式提交,在接收此请求的Servlet中用二进制流来获取内容,就可以取到上传文件的内容,从而实现文件的上传。

文件下载原理:

STEP1

需要通过HttpServletResponse.setContextType方法设置Content-Type头字段的值,为浏览器无法使用某种方式或**某个程序来处理MIME类型,例如“application/octet-stream”  或 “application/x-msdownload” 等。

STEP2

需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为“attachment;filename=文件名”

STEP3

读取下载文件,通过HttpServletResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件内容。

上传具体实现代码

package com.cn.demo;

import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
@RestController
public class uploadTest {


        public static final List<String> IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png",".docx",".xlsx);

        public static String getUUID() {
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        return uuid;
        }

        public static final String HH = "HH";
        public static final String YYYY_MM_DD = "yyyy-MM-dd";
        public static final DateTimeFormatter FORMATTER_HH = DateTimeFormatter.ofPattern(HH);
        public static final DateTimeFormatter FORMATTER_YYYY_MM_DD = DateTimeFormatter.ofPattern(YYYY_MM_DD);
        public static String getHH() {
            return FORMATTER_HH.format(LocalDateTime.now());
        }
        public static String getYYYYMMDD() {
            return FORMATTER_YYYY_MM_DD.format(LocalDateTime.now());
        }


    @PostMapping("/updateImage")
    @ResponseBody
    public Map<String, String> updateImage(@RequestParam("image") MultipartFile[] multfiles)  {
        Map<String, String> result = new HashMap<>();
        //1、校验是否有图片
        if (multfiles.length == 0) {
            result.put("message", "请选择图片!");
            return result;
        }

        final String originalFileName = multfiles[0].getOriginalFilename();
//        if (StringUtils.isBlank(originalFileName)) {
//            result.put("message", "请选择图片!");
//            return result;
//        }

        //2、判断文件后缀[.jpg]
        final String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")).toLowerCase();
        if (!IMAGE_EXTENSIONS.contains(suffix)) {
            result.put("message", "图片格式错误!");
            return result;
        }
        //3、创建与拼接文件要存储的路径
        String lastFilePath;
        String newFileName = getUUID() + suffix;
        String folderName = File.separator + "temp" + File.separator;
        String relativePath = folderName + getYYYYMMDD() + File.separator + getHH();
        String filePath = "D:\\fileImg" + relativePath;
        String fileUrl = null;
        File targetFile = new File(filePath);
        if (!targetFile.exists()) {
            targetFile.mkdirs();
        }
        //4、创建输出流,去写输出流中
        FileOutputStream out = null;
        try {
            lastFilePath = filePath + File.separator + newFileName;
            out = new FileOutputStream(lastFilePath);
            out.write(multfiles[0].getBytes());
            fileUrl = "http://127.0.0.1:8080" + relativePath + File.separator + newFileName;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                try {
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        if (fileUrl == null) {
            result.put("message", "图片上传失败!");
            return result;
        }

        result.put("message", "上传成功!");
        result.put("url", fileUrl);
        return result;
    }

}

测试

1、启动springboot项目,用postman上传一个文件,进行上传测试

文件的上传与下载

点击Send发送:上传支持:".jpg", ".jpeg", ".png",".docx",".xlsx"

上传成功后返回的结果:

文件的上传与下载

具体上传文件:代码中根据File对象中真实Path进行创建一个系统时间文件下,不存在进行创建,最终展示:

文件的上传与下载

下载具体实现

package com.cn.demo;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;

@RestController
public class TestDownload {

    @RequestMapping("/download")
    public static  void downLoad(String filePath, HttpServletResponse response, boolean isOnLine) throws Exception {
             File f = new File(filePath);
             if (!f.exists()) {
                   response.sendError(404, "File not found!");
                   return;
                 }
             BufferedInputStream br = new BufferedInputStream(new FileInputStream(f));
             byte[] buf = new byte[1024];
             int len = 0;

             response.reset(); // 非常重要
             if (isOnLine) { // 在线打开方式
                   URL u = new URL("file:///" + filePath);
                   response.setContentType(u.openConnection().getContentType());
                   response.setHeader("Content-Disposition", "inline; filename=" + f.getName());
                   // 文件名应该编码成UTF-8
                 } else { // 纯下载方式
                   response.setContentType("application/x-msdownload");
                   response.setHeader("Content-Disposition", "attachment; filename=" + f.getName());
                 }
             OutputStream out = response.getOutputStream();
             while ((len = br.read(buf)) > 0)
                   out.write(buf, 0, len);
             br.close();
             out.close();
           }


}

测试

1、启动springboot项目,用postman下载一个文件,进行下载测试

选择参数为:filePath ,选好文件真实路径。如图:

文件的上传与下载

点击Send发送:

上传成功后,返回如下的文件二进制流,如下

文件的上传与下载