1. 程式人生 > >SpringBoot實現檔案上傳和訪問

SpringBoot實現檔案上傳和訪問

用springboot實現檔案的上傳和訪問。檔案的上傳首先會用到相關的工具類,Jar包,

Maven專案需要jar包:

<!-- https://mvnrepository.com/artifact/commons-io/commons-io    IO 檔案流需要的包-->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.2</version> 
</dependency>
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload   檔案上傳需要的包-->
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.3</version>
</dependency>

如果放入專案中pom.xml 檔案有錯誤,可以根據自己需要的版本去新增 :

maven官網地址:https://mvnrepository.com

在spring boot專案打成jar包後,上傳檔案的路徑會有問題,或者可以成功上傳但是伺服器上找不到上傳成功的檔案。這時候我們需要為上傳檔案設定絕對路徑。

上傳工具類:

public class FileUploadController {

    
    /**
     * 圖片上傳
     * @param myfiles
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("/upload")
    public static  Object uploadApk(MultipartFile myfiles, HttpServletRequest request,
            HttpServletResponse response) {

        Map<String, Object> resMap = new HashMap<String, Object>();
        if(myfiles.getSize()>1024*1024*5){
        resMap.put("code", 500);
        resMap.put("msg", "檔案過大,請上傳5M以內的圖片");
        System.out.println("檔案上傳失敗");
        return resMap;
        }
        String path = request.getContextPath();
        String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path;
        Date dt = new Date();
        Long time = dt.getTime();
        if (myfiles != null) {
            String realPath ="d://uploadFiles/";  // 獲取儲存的路徑,本地磁碟中的一個資料夾
        if (myfiles.isEmpty()) {
                // 未選擇檔案
                resMap.put("code", 400);
                resMap.put("msg", "未選擇檔案");
            } else {
                // 檔案原名稱
                String originFileName = "";
                // 上傳檔案重新命名
                String originalFilename = time.toString().substring(time.toString().length() - 8,
                        time.toString().length());
                originalFilename = originalFilename.concat(".");
                originalFilename = originalFilename.concat(myfiles.getOriginalFilename().toString()
                        .substring(myfiles.getOriginalFilename().toString().indexOf(".") + 1));
                try {
                    // 這裡使用Apache的FileUtils方法來進行儲存
                    FileUtils.copyInputStreamToFile(myfiles.getInputStream(), new File(realPath, originalFilename));
                    resMap.put("code", 200);
                    resMap.put("msg", "上傳成功");
                    resMap.put("filename", originalFilename);
                    resMap.put("path", basePath + "/static/image/"+originalFilename );

                } catch (IOException e) {
                    resMap.put("code", 500);
                    System.out.println("檔案上傳失敗");
                    resMap.put("msg", "檔案上傳失敗");
                    e.printStackTrace();
                }
            }

        }
        
        String  param= JSON.toJSONString(resMap);
        System.out.println(param);
        return resMap;
    }
    }

此工具類將上傳的檔案會有一次重新命名,特別要注意的是。檔案上傳的儲存的路徑,我們需要將上傳的檔案儲存在本地的磁碟中,然後通過配置檔案中配置的路徑去訪問。如果不將檔案存在本地,專案打成Jar包後,  檔案可以上傳, 但訪問不成功, 導致 訪問的圖片都載入不到.

上傳介面

@RequestMapping("/updateheader")
    public ResultModel updatehead(MultipartFile myfiles, String token, HttpServletRequest request,
            HttpServletResponse response, Member mm) {
        Map<String, Object> map = (Map<String, Object>) FileUploadController.uploadApk(myfiles, request, response);//呼叫工具類,將檔案上傳。特別要注意的是  引數中的第一個引數。MultipartFile myfiles,    myfiles 的名稱要和頁面中 <input type="file" name="myfiles" /> 中的name名稱保持一致,否則獲取不到你上傳的檔案,檔案上傳成功後會返回一個MAP集合。
        mm.setM_logo(map.get("path").toString()); 
        int bool = userService.updatemember(mm);
        if (bool > 0) {
            ResultModel model = new ResultModel();
            model.setCode(200);
            model.setDetail(map.get("path").toString());
            model.setMsg("更換成功");
            return model;
        } else {
            return error(500, "系統異常");
        }
    }

關於頁面的提交,可以用form表單提交,也可以使用相關的前端上傳檔案的外掛上傳,例如:ajaxfileload  ,bootstrap 中的fileinput

都可以進行上傳檔案。根據需要自由選擇,我使用的是表單提交。

這是還沒有上傳頭像

 

控制檯會列印返回的資訊:

{"msg":"上傳成功","path":"http://192.168.1.179:8080/static/image/91492957.jpg","code":200,"filename":"91492957.jpg"}

http://192.168.1.179:8080/static/image/91492957.jpg  這就是檔案上傳返回的絕對路徑,如果你沒有配置通過虛擬路徑訪問的配置,即使你上傳成功了,通過這個路徑也訪問不到。

如果你上傳圖片之後,顯示還是這樣子,上傳的圖片的路徑也正確,就是訪問不到,關鍵時刻到了,缺少相關配置,

下面是配置資訊:

首先是需要一個類

一:UploadFilePathConfig配置類

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

/**
 * 設定虛擬路徑,訪問絕對路徑下資源
 * @author Administrator
 *
 */
@Configuration
public class UploadFilePathConfig implements WebMvcConfigurer{
    @Value("${file.staticAccessPath}")
    private String staticAccessPath;
    @Value("${file.uploadFolder}")
    private String uploadFolder;

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler(staticAccessPath).addResourceLocations("file:" + uploadFolder);
    }

}

這是設定虛擬的路徑,通過虛擬的路徑訪問絕對路徑下的檔案。

二:在application.properties  中進行配置

#jsp靜態資源配置
spring.mvc.view.prefix=/admin/
spring.mvc.view.suffix=.jsp
#配置靜態資源訪問路徑
spring.mvc.static-path-pattern=/webapp/**


#靜態資源對外暴露的訪問路徑
file.staticAccessPath=/static/image/**
#檔案上傳目錄(注意Linux和Windows上的目錄結構不同)
#file.uploadFolder=/root/uploadFiles/
file.uploadFolder=d://uploadFiles/   #特別要注意此位置

配置完成之後,專案重新啟動。重新進行上傳。

上傳之後的,會立即顯示出來。

同時請注意檢視你的磁碟中檔案是否儲存進去,

此時就成功上傳儲存了檔案。 有問題可以評論,幫助解決,如果有更好的方案,可以進行探討。謝謝