天天看點

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

Java EE 目錄:https://blog.csdn.net/dkbnull/article/details/87932809

Spring Boot 專欄:https://blog.csdn.net/dkbnull/category_9278145.html

Spring Cloud 專欄:https://blog.csdn.net/dkbnull/category_9287932.html

0. 開發環境

  • IDE:IntelliJ IDEA 2017.1 x64
  • jdk:1.8.0_91
  • Spring Boot:2.1.1.RELEASE

1. 檔案下載下傳

1.1 建立服務類

import cn.wbnull.springbootdemo.boot.GlobalException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;

@Service
public class LogService {

    public void logDownload(String name, HttpServletResponse response) throws Exception {
        File file = new File("logs" + File.separator + name);

        if (!file.exists()) {
            throw new GlobalException(name + "檔案不存在");
        }
        response.setContentType("application/force-download");
        response.addHeader("Content-Disposition", "attachment;fileName=" + name);

        byte[] buffer = new byte[1024];
        try (FileInputStream fis = new FileInputStream(file);
                      BufferedInputStream bis = new BufferedInputStream(fis)) {

            OutputStream os = response.getOutputStream();

            int i = bis.read(buffer);
            while (i != -1) {
                os.write(buffer, 0, i);
                i = bis.read(buffer);
            }
        }
    }
}
           

1.2 建立控制器類

import cn.wbnull.springbootdemo.service.LogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;

@RestController
@Scope("prototype")
@RequestMapping("/log")
public class LogController {

    @Autowired
    private LogService logService;

    /**
     * 下載下傳日志接口
     *
     * @param name
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/download/{name}")
    public void logDownload(@PathVariable String name, HttpServletResponse response) throws Exception {
        logService.logDownload(name, response);
    }
}
           

1.3 測試

上面接口是要下載下傳logs檔案夾下日志檔案,以log_20190218.log日志檔案為例,浏覽器直接通路 http://127.0.0.1:8090/springbootdemo/log/download/log_20190218.log 即可完成下載下傳。

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳
Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

2. 單檔案上傳

2.1 建立服務類

import cn.wbnull.springbootdemo.boot.GlobalException;
import cn.wbnull.springbootdemo.model.ReturnMessage;
import com.alibaba.fastjson.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

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

@Service
public class LogService {

    public JSONObject logUpload(MultipartFile file) throws Exception {
        if (file == null || file.isEmpty()) {
            throw new GlobalException("未選擇需上傳的日志檔案");
        }

        String filePath = new File("logs_app").getAbsolutePath();
        File fileUpload = new File(filePath);
        if (!fileUpload.exists()) {
            fileUpload.mkdirs();
        }

        fileUpload = new File(filePath, file.getOriginalFilename());
        if (fileUpload.exists()) {
            throw new GlobalException("上傳的日志檔案已存在");
        }

        try {
            file.transferTo(fileUpload);

            return ReturnMessage.success();
        } catch (IOException e) {
            throw new GlobalException("上傳日志檔案到伺服器失敗:" + e.toString());
        }
    }
}
           

2.2 建立控制器類

import cn.wbnull.springbootdemo.service.LogService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;

@RestController
@Scope("prototype")
@RequestMapping("/log")
public class LogController {

    @Autowired
    private LogService logService;

    /**
     * 上傳日志接口
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/upload")
    public JSONObject logUpload(@RequestParam("file") MultipartFile file) throws Exception {
        return logService.logUpload(file);
    }
}
           

2.3 建立HTML頁面

log-upload.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>檔案上傳</title>
</head>
<body>
<form method="post" action="/log/upload" enctype="multipart/form-data">
    <input type="file" name="file">
    <br><br>
    <input type="submit" value="送出">
</form>
</body>
</html>
           

2.4 測試

浏覽器打開頁面 http://127.0.0.1:8090/springbootdemo/log-upload.html

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

點選選擇檔案打開檔案選擇頁面,選中需要上傳的檔案後,點選送出,傳回如下則為檔案上傳成功。

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

我們去logs_app檔案夾下檢視,生成了上傳的日志檔案。

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

2.5 Java用戶端上傳檔案

上面我們上傳檔案的用戶端為HTML頁面,但我們實際生産中未必是WebAPP,這時我們可以通過模拟發送浏覽器HTTP請求來實作上傳檔案。

2.5.1 引入依賴

<dependency>
            <groupId>commons-httpclient</groupId>
            <artifactId>commons-httpclient</artifactId>
            <version>3.1</version>
        </dependency>
           

2.5.2 建立Java用戶端

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.junit.Test;

import java.io.File;
import java.io.IOException;

public class LogControllerTests {

    @Test
    public void logUpload() throws Exception {
        String url = "http://127.0.0.1:8090/springbootdemo/log/upload";
        String pathname = new File("logs" + File.separator + "log_20190310.log").getCanonicalPath();
        logUpload(url, pathname);
    }

    private static void logUpload(String url, String pathname) {
        HttpClient httpClient = new HttpClient();
        PostMethod postMethod = new PostMethod(url);

        try {
            FilePart filePart = new FilePart("file", new File(pathname));
            Part[] parts = {filePart};

            MultipartRequestEntity multipartRequestEntity = new MultipartRequestEntity(parts, new HttpMethodParams());
            postMethod.setRequestEntity(multipartRequestEntity);
            httpClient.executeMethod(postMethod);
            String result = postMethod.getResponseBodyAsString();

            System.out.println(result);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            postMethod.releaseConnection();
        }
    }
}
           

這裡,以下兩行代碼表示設定多媒體參數,作用類似form表單中的enctype=“multipart/form-data”

MultipartRequestEntity multipartRequestEntity = new MultipartRequestEntity(parts, new HttpMethodParams());
postMethod.setRequestEntity(multipartRequestEntity);
           

以下兩行代碼表示設定參數名稱和值,類似form表單中的<input name="file” type=“file” />

FilePart filePart = new FilePart("file", new File(pathname));
Part[] parts = {filePart};
           

2.5.3 測試

測試類運作成功。

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

檔案上傳成功

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

3. 多檔案上傳

3.1 建立服務類

public JSONObject logUploads(HttpServletRequest request) throws Exception {
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");

        for (MultipartFile file : files) {
            logUpload(file);
        }

        return ReturnMessage.success();
    }
           

3.2 建立控制器類

/**
     * 批量上傳日志接口
     *
     * @param request
     * @return
     * @throws Exception
     */
    @PostMapping(value = "/uploads")
    public JSONObject logUploads(HttpServletRequest request) throws Exception {
        return logService.logUploads(request);
    }
           

3.3 建立HTML頁面

log-uploads.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>批量檔案上傳</title>
</head>
<body>
<form method="post" action="log/uploads" enctype="multipart/form-data">
    <input type="file" name="file"><br>
    <input type="file" name="file"><br>
    <input type="file" name="file"><br>
    <br>
    <input type="submit" value="送出">
</form>
</body>
</html>
           

3.4 測試

我們先把之前測試上傳的logs_app檔案夾整個删除,然後浏覽器打開頁面 http://127.0.0.1:8090/springbootdemo/log-uploads.html

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

選擇要上傳的檔案

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

點選送出,傳回如下則為上傳成功。

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

我們去logs_app檔案夾下檢視,生成了上傳的日志檔案。

Spring Boot實作檔案上傳與下載下傳0. 開發環境1. 檔案下載下傳2. 單檔案上傳3. 多檔案上傳

3.5 Java用戶端上傳檔案

這裡如果我們也需要Java用戶端實作多檔案上傳,可以仿照2.5實作。

GitHub:https://github.com/dkbnull/SpringBootDemo

微信:https://mp.weixin.qq.com/s/rd6yhfMjwU7Pn3c46bKj7w