Spring boot 实现文件上传-标准版-最强版-完美版

文件上传的各种心酸

给我启发的博客:
https://blog.csdn.net/a625013/article/details/52414470
官网上传demo,真心没看懂

这里是用spring 资源加载类 ResourceLoader实现的。不止这一种方式。

核心代码:

下面代码不要复制粘贴,代码不完整。完整版代码最下面,我自己简单封装了下。

@Controller  
    public class FileUploadController {  

        private static final Logger log = LoggerFactory.getLogger(FileUploadController.class);  

        public static final String ROOT = "upload-dir";  


        private final ResourceLoader resourceLoader;  

        @Autowired  
        public FileUploadController(ResourceLoader resourceLoader) {  
            this.resourceLoader = resourceLoader;  
        }
    //显示图片的方法关键 匹配路径像 localhost:8080/b7c76eb3-5a67-4d41-ae5c-1642af3f8746.png  
    @RequestMapping(method = RequestMethod.GET, value = "/{filename:.+}")  
    @ResponseBody  
    public ResponseEntity getFile(@PathVariable String filename) { 
        try {  
            return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get(ROOT, filename).toString()));  
        } catch (Exception e) {  
            return ResponseEntity.notFound().build();  
        }  
    } 

   @RequestMapping(method = RequestMethod.POST, value = "/")  
    public String handleFileUpload(@RequestParam("file") MultipartFile file) {  
        if (!file.isEmpty()) {  
            try {  
                //保存文件而已,自己随便怎么写都行只要保存到服务器就可以了。
                Files.copy(file.getInputStream(), Paths.get(ROOT, file.getOriginalFilename()));  
            } catch (IOException|RuntimeException e) {  
                redirectAttributes.addFlashAttribute("message", "Failued to upload " + file.getOriginalFilename() + " => " + e.getMessage());  
            }  
        } else {  
            redirectAttributes.addFlashAttribute("message", "Failed to upload " + file.getOriginalFilename() + " because it was empty");  
        }  

        return "redirect:/";  
    }  
}

重点在这里

//显示图片的方法关键 匹配路径像 localhost:8080/b7c76eb3-5a67-4d41-ae5c-1642af3f8746.png  
    @RequestMapping(method = RequestMethod.GET, value = "/{filename:.+}")  
    @ResponseBody  
    public ResponseEntity getFile(@PathVariable String filename) { 
        try {  
            return ResponseEntity.ok(resourceLoader.getResource("file:" + Paths.get(ROOT, filename).toString()));  

完整版代码开始

首先定义个接口

package com.example.demo.service;

import com.example.demo.entity.UploadResult;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.nio.file.Path;
import java.util.stream.Stream;

public interface StorageService {

    /**
     * 存储文件
     * @param file
     * @return
     */
    UploadResult store(MultipartFile file);

    Stream loadAll();

    /**
     * 获取文件 Path对象
     * @param filename
     * @return Path对象 D:/ 非 file:D:/
     */
    Path load(String filename);

    /**
     * 返回 以 file:///C:/test/demo.txt 形式的 spring  resourceLoader.getResource 对象作为实现的
     * @param filename
     * @return
     */
    Resource loadAsResource(String filename);

    //危险性太大暂时没有实现
    void deleteAll();

}

接口的实现

package com.example.demo.service;

import com.example.demo.entity.UploadResult;
import com.example.demo.utils.SystemUtil;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import java.util.stream.Stream;

@Service
public class StorageServiceImpl implements StorageService {

    private String uploadPath = Paths.get("D:", "aaa").toString();

    private final ResourceLoader resourceLoader;

    @Autowired
    public StorageServiceImpl(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public UploadResult store(MultipartFile file) {
        UploadResult uploadResult = new UploadResult();
        if (Files.notExists(Paths.get(uploadPath))) {
            try {
                Files.createDirectories(Paths.get(uploadPath));
            } catch (IOException e) {
                uploadResult.failed("创建上传目录错误!");
            }
        }
        String newFileName = UUID.randomUUID().toString() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
        Path path = Paths.get(uploadPath, newFileName);
        try {
            Files.copy(file.getInputStream(), path);
        } catch (IOException e) {
            e.printStackTrace();
            uploadResult.failed();
            return uploadResult;
        }
        uploadResult.setPath(path);
        uploadResult.successful(SystemUtil.getBasePath() + path);
        return uploadResult;
    }

    @Override
    public Stream loadAll() {
        return null;
    }

    @Override
    public Path load(String filename) {
        return Paths.get(uploadPath, filename);
    }

    @Override
    public Resource loadAsResource(String filename) {
        return resourceLoader.getResource("file:" + load(filename).toString());
    }

    @Override
    public void deleteAll() {

    }
}

公共上传Controller

package com.example.demo.controller;

import com.example.demo.entity.UploadResult;
import com.example.demo.service.StorageService;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@Controller
public class FileUploadController {

    @javax.annotation.Resource
    private StorageService storageService;

    @RequestMapping(method = RequestMethod.GET, value = "/{filename:.+}")
    @ResponseBody
    public ResponseEntity getFile(@PathVariable String filename) {
        try {
            return ResponseEntity.ok(storageService.load(filename));
        } catch (Exception e) {
            throw new StorageFileNotFoundException();
        }
    }

    @GetMapping("/downloadFile/{filename:.+}")
    @ResponseBody
    public ResponseEntity downloadFile(@PathVariable String filename) {

        Resource file = storageService.loadAsResource(filename);
        return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION,
                "attachment; filename=\"" + file.getFilename() + "\"")
                .body(file);
    }

    @PostMapping("/")
    public UploadResult handleFileUpload(@RequestParam("file") MultipartFile file) {
        return storageService.store(file);
    }


    @ExceptionHandler(StorageFileNotFoundException.class)
    public ResponseEntity handleStorageFileNotFound(StorageFileNotFoundException exc) {
        return ResponseEntity.notFound().build();
    }

    public class StorageFileNotFoundException extends RuntimeException {
        public StorageFileNotFoundException() {
            super();
        }

        public StorageFileNotFoundException(String message) {
            super(message);
        }
    }


}

上传结果类

package com.example.demo.entity;

import java.nio.file.Files;
import java.nio.file.Path;

public class UploadResult {
    private int success = 0; // 0 失败 1成功
    private String message;
    private String url;
    private Path path;

    public boolean isSuccess() {
        return (success == 1 && path != null && Files.exists(this.path));
    }

    public void successful(String url) {
        successful("上传成功!", url);
    }

    public void successful(String message, String url) {
        this.success = 1;
        this.message = message;
        this.url = url;
    }

    public void failed() {
        this.success = 0;
        this.message = "上传失败!";
    }

    public void failed(String message) {
        this.success = 0;
        this.message = message;
    }

    public void failed(String message, String url) {
        this.success = 0;
    }


    public int getSuccess() {
        return success;
    }

    public void setSuccess(int success) {
        this.success = success;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setPath(Path path) {
        this.path = path;
    }
}

使用方法:

1.可以直接使用公共上传的Controller
2.也可以直接调用 StorageService 上传类

我的使用方法就是第二种:

代码:

/**
     * 上传图片
     *
     * @param file
     * @param guid
     */
    @PostMapping("uploadImage.do")
    public UploadResult uploadImage(@RequestParam("editormd-image-file") MultipartFile file, @RequestParam("guid") String guid, HttpServletRequest request) {
        return storageService.store(file);
    }

你可能感兴趣的:(java,spring,spring,boot,spring,boot,文件上传)