spring 上传文件和下载文件

1. 上传文件

  • 借助multipart形式可以比较轻松的上传文件
  • 代码实现
    可以使用MultipartFile和Part两种方法去操作上传的文件

MultipartFile的两个实现类(ctrl+alt+b)
1.CommonsMultipartFile(非servlet3.0以上的服务)
2.StandardMultipartFile


MultipartFile.java

Part实现类ApplicationPart(一般使用注解@RequestPart("xxx)Part xxx)
多了一个delete的方法


part.java
  • 使用配置
@Configuration
public class MultipartConfig {
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        //  单个数据大小
        factory.setMaxFileSize(DataSize.parse("102400KB"));
        /// 总上传数据大小
        factory.setMaxRequestSize(DataSize.parse("102400KB"));
        //设置文件路径
        factory.setLocation("/app/temp/");
        //默认值是0 ,就是不管文件大小,都会将文件保存到磁盘中
        //factory.setFileSizeThreshold(DataSize.parse("0B"));
        return factory.createMultipartConfig();
    }
}
  • 上传单文件到指定路径中 这种可以自己指定文件的保存路径,配置中factory.setLocation("/app/temp/");这句代码不需要
 @RequestMapping("/uploadFile")
    public Object uploadFile(@RequestParam("file") MultipartFile file,
                             @Validated @Size(min = 3, max = 50, message = "文件描述长度不符合规范") @RequestParam("description") String description) throws IOException {
        if (file.isEmpty()) {
            return "文件为空,请重新上传";
        }

        String realPath1 = ResourceUtils.getURL("classpath:").getPath();
        String filePath = realPath1 + "/images/" + file.getOriginalFilename();
        File dest = new File(filePath);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdir();
       }
        file.transferTo(dest);
        return "保存成功";
    }
  • 上传到服务的临时目录中
  1. 如果配置了factory.setLocation("/app/temp/");这句话,文件的保存路径会为
    C:\Users\lrh\AppData\Local\Temp\tomcat.5166651053557888915.8080\work\Tomcat\localhost\ROOT\app\temp\微信图片_20190630233947.jpg

2.如果不配置,会保存在服务器运行时的一个临时文件夹中,这种相对比较简单
C:\Users\lrh\AppData\Local\Temp\tomcat.245320015338601087.8080\work\Tomcat\localhost\ROOT\微信图片_20190630233947.jpg

 @RequestMapping("/uploadFile")
    public Object uploadFile(@RequestParam("file") MultipartFile file,
                             @Validated @Size(min = 3, max = 50, message = "文件描述长度不符合规范") @RequestParam("description") String description) throws IOException {
        if (file.isEmpty()) {
            return "文件为空,请重新上传";
        }
        File dest = new File(file.getOriginalFilename());
        file.transferTo(dest);
        return "保存成功";
    }
  • 上传多个文件,不同点在于参数时数组,其他一样
 @RequestMapping("/uploadFiles")
    public Object uploadFile(@RequestParam("files") MultipartFile[] files,
                             @Validated @Size(min = 3, max = 50, message = "文件描述长度不符合规范") @RequestParam("description") String description) throws IOException {
        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                return "文件为空,请重新上传";
            }
            File dest = new File(file.getOriginalFilename());
            file.transferTo(dest);
        }
        return "保存成功";
    }
  • 为什么可以不设置文件的保存文件夹
    因为文件在保存的时候会先判断,是否有绝对路径file.isAbsolute(),如果没有绝对路径,就会从MultipartConfigElement中的Location中获取路径,这个路径一般时服务在运行时的一个路径
StandardMultipartFile.java
@Override
        public void transferTo(File dest) throws IOException, IllegalStateException {
            this.part.write(dest.getPath());
            if (dest.isAbsolute() && !dest.exists()) {
                // Servlet 3.0 Part.write is not guaranteed to support absolute file paths:
                // may translate the given path to a relative location within a temp dir
                // (e.g. on Jetty whereas Tomcat and Undertow detect absolute paths).
                // At least we offloaded the file from memory storage; it'll get deleted
                // from the temp dir eventually in any case. And for our user's purposes,
                // we can manually copy it to the requested location as a fallback.
                FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest.toPath()));
            }
        }

ApplicationPart.java
 @Override
    public void write(String fileName) throws IOException {
        File file = new File(fileName);
        if (!file.isAbsolute()) {
            file = new File(location, fileName);
        }
        try {
            fileItem.write(file);
        } catch (Exception e) {
            throw new IOException(e);
        }
    }

2. 下载文件

下载文件时需要设置响应的header

 @RequestMapping("/downLoadImage")
    public Object downLoadImage(@Validated @NotEmpty String fileName, HttpServletResponse response) throws FileNotFoundException {

        String fileRealPath = ResourceUtils.getURL("classpath:").getPath() + "/images/" + fileName;
        File file = new File(fileRealPath);
        if (!file.exists()) {
            return "文件不存在";
        }
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        try {
            response.setHeader("Content-Disposition", "attachment;filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
        } catch (UnsupportedEncodingException e2) {
            e2.printStackTrace();
        }
        byte[] buff = new byte[1024];
        BufferedInputStream bis = null;
        OutputStream os = null;
        try {
            os = response.getOutputStream();
            bis = new BufferedInputStream(new FileInputStream(file));
            while (bis.read(buff) != -1) {
                os.write(buff, 0, buff.length);
                os.flush();
            }
        } catch (FileNotFoundException e1) {
            return "系统找不到指定的文件";
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "success";
    }

你可能感兴趣的:(spring 上传文件和下载文件)