vue.js+SpringBoot文件上傳下載

此文章是在Spring Boot 文件上傳與下載的基礎上修改的

一、配置文件

在application-dev.yml文件中添加如下代碼

spring:
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    default-property-inclusion: non_null

  ## MULTIPART (MultipartProperties)
  # 開啓 multipart 上傳功能
  servlet:
    multipart:
      enabled: true
      # 文件寫入磁盤的閾值
      file-size-threshold: 2KB
      # 最大文件大小
      max-file-size: 200MB
      # 最大請求大小
      max-request-size: 215MB

## 文件存儲所需參數
# 所有通過 REST APIs 上傳的文件都將存儲在此目錄下
file:
  upload-dir: ./uploads

創建FileProperties文件
在這裏插入圖片描述

/**
 * @author yejiajun
 * @date 2019/8/13  15:46
 * Version 1.0.0
 */
import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties(prefix = "file")
public class FileProperties {
    private String uploadDir;

    public String getUploadDir() {
        return uploadDir;
    }
    public void setUploadDir(String uploadDir) {
        this.uploadDir = uploadDir;
    }
}

在啓動類中添加配置

@EnableConfigurationProperties({
        FileProperties.class
})
public class TrainBooststrap {
    public static void main(String[] args) {
        new SpringApplicationBuilder(TrainBooststrap.class).web(true).run(args);    }
}

二、創建響應類

在這裏插入圖片描述

import lombok.Data;

/**
 * @author yejiajun
 * @date 2019/8/13  15:54
 * Version 1.0.0
 */
@Data
public class UploadFileResponse {
    private String fileName;
    private String fileDownloadUri;
    private String fileType;
    private long size;

    public UploadFileResponse(String fileName, String fileDownloadUri, String fileType, long size) {
        this.fileName = fileName;
        this.fileDownloadUri = fileDownloadUri;
        this.fileType = fileType;
        this.size = size;
    }
}

三、創建異常對象

在這裏插入圖片描述

/**
 * @author yejiajun
 * @date 2019/8/13  15:55
 * Version 1.0.0
 */
public class FileException extends RuntimeException{
    public FileException(String message) {
        super(message);
    }

    public FileException(String message, Throwable cause) {
        super(message, cause);
    }
}

四、提供文件服務

import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;

/**
 * @author yejiajun
 * @date 2019/8/19  10:40
 * Version 1.0.0
 */
public interface FileService {


    /**
     * 存儲文件到系統
     *
     * @param file 文件
     * @return 文件名
     */
    String storeFile(MultipartFile file);

    /**
     * 加載文件
     * @param fileName 文件名
     * @return 文件
     */
    Resource loadFileAsResource(String fileName);
}

實現這個接口

import com.capol.train.server.exception.FileException;
import com.capol.train.server.property.FileProperties;
import com.capol.train.server.server.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
/**
 * @author yejiajun
 * @date 2019/8/1215:07
 * Version 1.0.0
 */
@Service
public class FileServiceImpl implements FileService {

    /**
     * 文件在本地存儲的地址
     */
    private final Path fileStorageLocation;

    @Autowired
    public FileServiceImpl(FileProperties fileProperties) {
        this.fileStorageLocation = Paths.get(fileProperties.getUploadDir()).toAbsolutePath().normalize();
        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception ex) {
            throw new FileException("Could not create the directory where the uploaded files will be stored.", ex);
        }
    }

    /**
     * 存儲文件到系統
     *
     * @param file 文件
     * @return 文件名
     */
    @Override
    public String storeFile(MultipartFile file) {
        // Normalize FileNoticeDTO name
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());

        try {
            // Check if the FileNoticeDTO's name contains invalid characters
            if(fileName.contains("..")) {
                throw new FileException("Sorry! Filename contains invalid path sequence " + fileName);
            }

            // Copy FileNoticeDTO to the target location (Replacing existing FileNoticeDTO with the same name)
            Path targetLocation = this.fileStorageLocation.resolve(fileName);
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

            return fileName;
        } catch (IOException ex) {
            throw new FileException("Could not store FileNoticeDTO " + fileName + ". Please try again!", ex);
        }
    }

    /**
     * 加載文件
     * @param fileName 文件名
     * @return 文件
     */
    @Override
    public Resource loadFileAsResource(String fileName) {
        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if(resource.exists()) {
                return resource;
            } else {
                throw new FileException("File not found " + fileName);
            }
        } catch (MalformedURLException ex) {
            throw new FileException("File not found " + fileName, ex);
        }
    }
}

五、創建controller提供服務

import com.capol.train.server.response.UploadFileResponse;
import com.capol.train.server.server.FileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author yejiajun
 * @date 2019/8/12 15:07
 * Version 1.0.0
 */
@RestController
public class FileController {

    private static final Logger logger = LoggerFactory.getLogger(FileController.class);

    @Autowired
    private FileService fileService;

    @PostMapping("/uploadFile")
    public UploadFileResponse uploadFile(@RequestParam("file") MultipartFile file) {
        String fileName = fileService.storeFile(file);
        String fileDownloadUri = ServletUriComponentsBuilder.fromCurrentContextPath()
                .path("/downloadFile/")
                .path(fileName)
                .toUriString();
         //因爲我這個項目是分佈式的,ip地址不穩定,所以我把前面ip地址給截掉 了,如果是單機可以不用下的語句
        fileDownloadUri = fileDownloadUri.substring(fileDownloadUri.indexOf("/downloadFile/"));
        return new UploadFileResponse(fileName, fileDownloadUri,
                file.getContentType(), file.getSize());
    }


    @PostMapping("/uploadMultipleFiles")
    public List<UploadFileResponse> uploadMultipleFiles(@RequestParam("files") MultipartFile[] files) {
        return Arrays.stream(files)
                .map(this::uploadFile)
                .collect(Collectors.toList());
    }

    @GetMapping("/downloadFile/{fileName:.+}")
    public void downloadFile(@PathVariable String fileName, HttpServletResponse response) {
        InputStream inputStream = null;
        OutputStream out = null;
        response.setContentType("application/x-msdownload");
        try {
            Resource resource = fileService.loadFileAsResource(fileName);
            inputStream = resource.getInputStream();
            //1.設置文件ContentType類型
            response.setContentType("application/octet-stream;charset=UTF-8");
            out = response.getOutputStream();
            //2.轉碼
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);

            int b = 0;
            byte[] buffer = new byte[2048];
            while (b != -1) {
                b = inputStream.read(buffer);
                if (b != -1) {
                    out.write(buffer, 0, b);
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                inputStream.close();
                out.close();
                out.flush();
            } catch (IOException e) {

            }
        }
    }
}

六、測試

vue.js+SpringBoot文件上傳下載 測試
下載就是直接那個下載地址就可以了。

七、前端

<el-form-item label="附件">
    <el-upload
            class="upload-demo"
           	<!-- 填自己的controller接口-->
            :action= "baseUrl+'/api/train/uploadFile?token='+token"
            :file-list="publicFileList"
            :on-change="publicHandleChange"
            :on-success="publicUploadSuccess"
            :limit="1">
        <el-button size="small" type="primary">點擊上傳</el-button>
        <div slot="tip" class="el-upload__tip">(必傳)</div>
    </el-upload>
</el-form-item>
<script>
    export default {
        name: 'documentation',
        data() {
            return {
                baseUrl: '1',
                token: '1',
        },
        components: {},
        mounted() {
            const _that = this;
            _that.baseUrl = process.env.BASE_API_ROOT;
            _that.token = _that.getToken();
        },
        methods: {
            pudownload(row){
                //前綴加後綴token,地址就按自己的來
                window.location.href = this.baseUrl + '/api/train' + row.url + '?token=' + this.token
            },
        }
</script>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章