溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Springboot文件上傳功能怎么實現(xiàn)

發(fā)布時間:2023-04-12 11:29:46 來源:億速云 閱讀:108 作者:iii 欄目:開發(fā)技術

這篇文章主要介紹了Springboot文件上傳功能怎么實現(xiàn)的相關知識,內容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇Springboot文件上傳功能怎么實現(xiàn)文章都會有所收獲,下面我們一起來看看吧。

1.新建文件上傳頁面

在static目錄中新建upload-test.html,上傳頁面代碼如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>springboot文件上傳測試</title>
</head>
<body>
<form action="/uploadFile" method="post" enctype="multipart/form-data">
    <input type="file" name="file" />
    <input type="submit" value="文件上傳" />
</form>
</body>
</html>

其中后端處理文件上傳的請求地址為/uploadFile,請求方法為POST。在文件上傳時需要設置form表單的enctype屬性為“multipart/form-data”。
效果圖如下:

Springboot文件上傳功能怎么實現(xiàn)

2.新建文件上傳處理Controller類

在controller包下新建UploadController類并編寫實際的文件上傳邏輯代碼,如下所示:

package ltd.newbee.mall.controller;

import ltd.newbee.mall.util.PageResult;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
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.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

@Controller
public class UploadController {
    //文件保存路徑為在D盤下的upload文件夾,可以按照自己的習慣修改
    private final static String FILE_UPLOAD_PATH = "D:\\upload\\";
    @RequestMapping(value = "/uploadFile",method = RequestMethod.POST)
    @ResponseBody
    public String uploadFile(@RequestParam("file") MultipartFile file){
        if (file.isEmpty()){
            return "文件上傳失敗";
        }
        String fileName = file.getOriginalFilename();
        String suffixName = fileName.substring(fileName.lastIndexOf("."));
        //生成文件名稱通用方法
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
        Random r = new Random();
        StringBuilder tempName = new StringBuilder();
        tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
        String newFileName = tempName.toString();
        try {
            //保存文件
            byte[] bytes = file.getBytes();
            Path path = Paths.get(FILE_UPLOAD_PATH+newFileName);
            Files.write(path,bytes);
        }catch (IOException e){
            e.printStackTrace();
        }
        return "上傳成功";
    }
}

由于Spring Boot已經自動配置了StandardServletMultipartResolver類來處理文件上傳請求,因此能夠直接在控制器方法中使用MultipartFile讀取文件信息。 @RequestParam中文件名稱屬性需要與前端頁面中input文件輸入框設置的name屬性一致。如果文件為空則返回上傳失敗,如果不為空則根據日期生成一個新的文件名,讀取文件流程并寫入指定的路徑中,最后返回上傳成功的提示信息。
需要注意的是文件上傳路徑的設置。在上述代碼中設置的文件保存路徑為D:\upload\,即在D盤下的upload文件夾。如果項目部署在Linux系統(tǒng)中的話,寫法與此不同。比如想要把文件上傳到/opt/newbee/upload目錄下,就需要把路徑設置的代碼改為private final static String FILE_UPLOAD_PATH = “/opt/newbee/upload/”。這一點需要注意,兩種系統(tǒng)的寫法存在一些差異。如果文件存儲目錄還沒有創(chuàng)建的話,首先需要創(chuàng)建該目錄,然后啟動項目進行文件上傳測試。

3.文件上傳功能測試

在編碼完成后,啟動Spring Boot項目。在啟動成功后,打開瀏覽器并輸入測試頁面地址:

http://localhost:8080/upload-test.html

打開后選擇上傳的文件,然后上傳,顯示成功。

Springboot文件上傳功能怎么實現(xiàn)

檢查本機upload目錄下是否有改文件(注意這里需要在對應的位置建立好upload文件夾)

Springboot文件上傳功能怎么實現(xiàn)

另外,在Spring Boot項目中支持單個文件的最大值默認為1MB,支持單個請求最大值默認10 MB。如果選擇了大于默認值的文件進行上傳,比如一個1.2MB的文件或者一個11MB的請求,就會報錯。

4.文件上傳路徑回顯

Spring Boot項目與普通Spring項目的目錄結構不同,并沒有webapp目錄,因此無法與普通的Java Web項目一樣,上傳文件到webapp目錄中并直接根據目錄進行訪問。Spring Boot項目中通常使用自定義靜態(tài)資源映射目錄,以此來實現(xiàn)文件上傳整個流程的閉環(huán)。比如在前文文件上傳案例中,在文件上傳到upload目錄后,會增加一個自定義靜態(tài)資源映射配置,使得在upload下的靜態(tài)資源可以通過該映射地址被訪問到。
新建config包并在config包中新增SpringBootWebMvcConfigurer類,實現(xiàn)代碼如下所示:

package ltd.newbee.mall.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class SpringBootWebMvcConfigurer implements WebMvcConfigurer {
    public void addResourceHandlers(ResourceHandlerRegistry registry){
        registry.addResourceHandler("/upload/**").addResourceLocations("file:D:\\upload\\");
    }

}

通過以上代碼配置,所有以“/upload/”開頭的靜態(tài)資源在請求時都會映射到D盤的upload目錄下。路徑的設置與前文中上傳文件的設置目錄類似,不同系統(tǒng)的文件路徑的寫法不同(比如Linux和Windows)。同時需要注意在設置靜態(tài)資源映射路徑時,路徑前需要添加“file:”前綴。
最后修改一下在文件上傳時的返回信息,把路徑拼裝好并返回到頁面上,以便于功能測試,UploadController代碼的修改如下所示:

        return "上傳成功,地址為:/upload/"+newFileName;

最后啟動項目進行測試

Springboot文件上傳功能怎么實現(xiàn)

檢查對應目錄下是否有文件

Springboot文件上傳功能怎么實現(xiàn)

上傳成功完成。

5.多文件上傳功能實現(xiàn)

首先,在static目錄中新建upload-same-file-name.html,頁面代碼如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多文件上傳測試(文件名相同)</title>
</head>
<body>
<form action="/uploadFilesBySameName" method="post" enctype="multipart/form-data">
    <input type="file" name="files"/><br><br>
    <input type="file" name="files"/><br><br>
    <input type="file" name="files"/><br><br>
    <input type="file" name="files"/><br><br>
    <input type="file" name="files"/><br><br>
    <input type="submit" value="文件上傳"/>
</form>
</body>
</html>

多文件上傳頁面與單文件上傳頁面類似,不同點是新增了4個文件輸入框,文件輸入框的name屬性統(tǒng)一命名為files,文件名完全一致。后端處理文件上傳的請求地址為/uploadFilesBySameName,請求方法為POST。
在UploadController類中新增uploadFilesBySameName()方法,用于處理在文件名相同時的多文件上傳問題,新增代碼如下所示:

    @RequestMapping(value = "/uploadFileBySameName",method = RequestMethod.POST)
    @ResponseBody
    public String uploadFileBySameName(@RequestPart MultipartFile[] files){
        if (files == null|| files.length==0){
            return "參數錯誤";
        }
        if (files.length>5){
            return "文件最多上傳5個";
        }
        String uploadResult = "上傳成功,地址為:<br>";
        for (MultipartFile file:files){
            String fileName = file.getOriginalFilename();
            if (StringUtils.isEmpty(fileName)){
                //表示無文件信息,跳出當前循環(huán)
                continue;
            }
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            //生成文件名稱的通用方法
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            Random r = new Random();
            StringBuilder tempName = new StringBuilder();
            tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
            String newFileName = tempName.toString();
            try {
                //保存文件
                byte[] bytes = file.getBytes();
                Path path = Paths.get(FILE_UPLOAD_PATH+newFileName);
                Files.write(path,bytes);
                uploadResult += "/upload/" + newFileName + "<br>";
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return uploadResult;
    }

與單文件在上傳時的uploadFile()方法相比,多文件上傳有兩處改動。
第一,文件參數在接收時的代碼改動。在多文件上傳并接收參數時使用的是@RequestPart注解,且接收的文件參數是一個數組MultipartFile。而單文件在上傳時使用的是@RequestParam注解,接收的文件是單個對象。
第二,文件在保存時增加循環(huán)邏輯。多文件保存的處理方式與單文件在上傳時比較類似,只是增加了循環(huán)邏輯,對接收的MultipartFile數組中每一個文件進行存儲操作,最后拼接文件的地址信息并返回。
另外一個需要注意的知識點,多文件上傳在接收參數時,參數名稱files需要完全對應input框中的name屬性。比如本次演示,在upload-same-file-name.html文件中所有文件輸入框的name屬性都是files;在后端處理時,uploadFilesBySameName()方法的參數名稱也定義為files,兩個名稱是對應的。如果所有文件輸入框的name屬性都改為uploadFiles,那么uploadFilesBySameName()方法的參數名稱也需要改為uploadFiles,否則接收的文件對象數組為空。
在編碼完成后,啟動Spring Boot項目。在在啟動成功后打開瀏覽器并輸入多圖上傳的測試頁面地址:

http://localhost:8080/upload-same-file-name.html

實際效果:

Springboot文件上傳功能怎么實現(xiàn)

Springboot文件上傳功能怎么實現(xiàn)

6.文件名不同時的多文件上傳處理

首先,在static目錄中新建upload-different-file-name.html,頁面代碼如下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>多文件上傳測試(文件名不同)</title>
</head>
<body>
<form action="/uploadFilesByDifferentName" method="post" enctype="multipart/form-data">
    <input type="file" name="files1"/><br><br>
    <input type="file" name="files2"/><br><br>
    <input type="file" name="files3"/><br><br>
    <input type="file" name="files4"/><br><br>
    <input type="file" name="files5"/><br><br>
    <input type="submit" value="文件上傳"/>
</form>
</body>
</html>

然后,在UploadController類中新增uploadFilesByDifferentName()方法,用于處理文件名在不相同時的多文件上傳,新增代碼如下所示:

    @RequestMapping(value = "/uploadFilesByDifferentName",method = RequestMethod.POST)
    @ResponseBody
    public String uploadFilesByDifferentName(HttpServletRequest httpServletRequest Request){
        List<MultipartFile> multipartFiles = new ArrayList<>(8);
        //如果不是文件上傳請求則不處理
        if (!standardServletMultipartResolver.isMultipart(httpServletRequest)){
            return "請選擇文件";
        }
        //將HttpServletRequest 對象轉換為MultipartHttpServletRequest對象,并讀取文件
        MultipartHttpServletRequest multiRequest =(MultipartHttpServletRequest)httpServletRequest;
        Iterator<String> iter = multiRequest.getFileNames();
        int total=0;
        while (iter.hasNext()){
            if (total>5) {
                return "最多上傳5個文件";
            }
            total+=1;
            MultipartFile file = multiRequest.getFile(iter.next());
            multipartFiles.add(file);
        }
        if (CollectionUtils.isEmpty(multipartFiles)) {
            return "請選擇文件";
        }
        if (multipartFiles != null && multipartFiles.size()>5){
            return "文件最多上傳5個";
        }
        String uploadResult = "上傳成功,地址為:<br>";
        for(int i=0;i<multipartFiles.size();i++){
            String fileName = multipartFiles.get(i).getOriginalFilename();
            if (StringUtils.isEmpty(fileName)){
                //表示無文件信息,跳出當前循環(huán)
                continue;
            }
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            //生成文件名稱的通用方法
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
            Random r = new Random();
            StringBuilder tempName = new StringBuilder();
            tempName.append(sdf.format(new Date())).append(r.nextInt(100)).append(suffixName);
            String newFileName = tempName.toString();
            try {
                //保存文件
                byte[] bytes = multipartFiles.get(i).getBytes();
                Path path = Paths.get(FILE_UPLOAD_PATH+newFileName);
                Files.write(path,bytes);
                uploadResult += "/upload/" + newFileName + "<br>";
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return uploadResult;
    }

與文件名相同時的多文件上傳的uploadFilesBySameName()方法相比,文件名不同時的改動只有一處,即文件參數在接收時的代碼做了改動。在讀取文件信息時的邏輯是自行實現(xiàn)的代碼邏輯,首先調用isMultipart()方法判斷當前請求是否為文件上傳請求,如果不是則不進行處理,如果是文件上傳請求,則HttpServletReques對象轉換為MultipartHttpServletRequest對象,并讀取文件數據,在讀取完成后再依次進行存儲。存儲文件的過程與之前的邏輯一致,最后拼接文件的地址信息并返回。
另外,需要判斷當前請求是否為文件上傳請求時要用到StandardServletMultipart Resolver類isMultipart()方法。前文中提到的StandardServletMultipartResolver類已經自動配置,所以可以直接在UploadController類中使用@Autowired注解注入,代碼如下所示:

    @Autowired
    private StandardServletMultipartResolver standardServletMultipartResolver;

測試成功

Springboot文件上傳功能怎么實現(xiàn)

關于“Springboot文件上傳功能怎么實現(xiàn)”這篇文章的內容就介紹到這里,感謝各位的閱讀!相信大家對“Springboot文件上傳功能怎么實現(xiàn)”知識都有一定的了解,大家如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI