菜鳥的springboot項目圖片上傳及圖片路徑分析

說明

本文記錄一下springboot項目的圖片上傳的相關知識,主要解決項目打成jar包部署時的圖片路徑問題,本文會持續更新,不斷地擴充

本文僅爲記錄學習軌跡,如有侵權,聯繫刪除

一、圖片路徑分析

springboot項目在還沒打包時,很多人喜歡把圖片上傳後,保存在項目的靜態資源下,就像下面的圖片那樣
在這裏插入圖片描述
這樣好像看來沒問題,在還沒打成jar包時,在idea啓動運行正常,圖片也確實存儲到了靜態資源下的images文件夾中,但是一旦打包成jar包後,運行jar包時,發現圖片存儲路徑出錯了,圖片並不會存儲到靜態資源下的images文件夾中,而是到服務器的用戶下的路徑那裏去,如果把打包後的jar包在自己電腦運行,按照上面的代碼,圖片就會存儲到C盤下對應的電腦用戶那裏
在這裏插入圖片描述
這是因爲打包後會生成一個jar包,這個jar可以解壓,發現裏面的classes就打包有靜態資源,而且上面的代碼String path = System.getProperty("user.dir");在idea啓動運行時會獲取到項目的根路徑,所以在idea啓動運行時可以將圖片保存在項目下的images文件夾裏面,而打包成一個jar後,用java -jar jar包名稱啓動時,獲取的確是C盤下的用戶路徑,而不會獲取到jar所在的目錄,跟不會獲取到jar裏面的classes文件的路徑
在這裏插入圖片描述
這種獲取圖片路徑並存儲的方式肯定不是我想要的,我想要的效果是,即使打成jar包後,可以在jar包所在目錄下自動生成一個文件夾,上傳的圖片就保存在這個文件夾中,這樣就不論你jar包部署在哪裏,都可以獲取到jar所在根目錄,並自動生成一個文件夾保存上傳的圖片
在這裏插入圖片描述
這樣的話部署就方便多了

二、實現圖片上傳

(1)單文件上傳(非異步)

我們知道項目打包後的jar包都在target文件夾裏面,也就是說target所在文件夾纔是jar包所在的路徑,所以,圖片存儲的位置就應該在target裏面,這樣在打成jar包後,就可以獲取jar包所在目錄,實現上面分析的功能

前端代碼

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>單文件上傳</title>
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
    <script th:src="@{/js/jquery.min.js}"></script>
</head>
<body>
<div th:if="${uploadStatus}" style="color: red" th:text="${uploadStatus}">上傳成功</div>
<form th:action="@{/singleUploadFile}" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label>單文件上傳</label>
        <input class="form-control-file" type="file" name="file" required="required" />
    </div>
    <input id="submit" type="submit" value="上傳" />
</form>
</body>
</html>

後端對應控制器的代碼

    //來到單文件上傳頁面(非異步)
    @GetMapping("/toSingleUpload")
    public String singleUpload() throws FileNotFoundException {
        return "singleUpload";
    }

    //上傳圖片(非異步)
    @PostMapping("/singleUploadFile")
    public String singleUploadFile(MultipartFile file, Model model){
        String fileName=file.getOriginalFilename(); //獲取文件名以及後綴名
        //fileName= UUID.randomUUID()+"_"+fileName;//重新生成文件名(根據具體情況生成對應文件名)

        //獲取jar包所在目錄
        ApplicationHome h = new ApplicationHome(getClass());
        File jarF = h.getSource();
        //在jar包所在目錄下生成一個upload文件夾用來存儲上傳的圖片
        String dirPath = jarF.getParentFile().toString()+"/upload/";
        System.out.println(dirPath);

        File filePath=new File(dirPath);
        if(!filePath.exists()){
            filePath.mkdirs();
        }
        try{
            //將文件寫入磁盤
            file.transferTo(new File(dirPath+fileName));
            //上傳成功返回狀態信息
            model.addAttribute("uploadStatus","上傳成功");
        }catch (Exception e){
            e.printStackTrace();
            //上傳失敗,返回失敗信息
            model.addAttribute("uploadStatus","上傳失敗:"+e.getMessage());
        }
        //攜帶上傳狀態信息回調到文件上傳頁面
        return "singleUpload";
    }

在這裏插入圖片描述
在idea啓動運行,圖片保存在target下的upload,打成jar包後運行,則會在jar所在目錄下自動生成upload文件存儲上傳的圖片
在這裏插入圖片描述
實現了圖片的上傳後,如何獲取圖片,如果沒法獲取那上傳圖片就沒意思了,假設我將jar放在路徑"E:\文件上傳“,圖片就在文件夾"E:\文件上傳\upload\1.png"裏面,如果用這種方式<img src="E:\文件上傳\upload\1.png">獲取圖片是不行的,首先是訪問不了項目外的資源,其次這個路徑應該是動態的,隨着jar包的路徑變動的,爲了實現這兩點就需要做個視圖解析器
在這裏插入圖片描述
這樣訪問”/upload/“就會自動訪問到jar包下的upload文件夾,也就可以訪問圖片了

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>獲取圖片</title>
</head>
<body>
    <!--這樣訪問”/upload/“就會自動訪問到jar包下的upload文件夾,也就可以訪問圖片了-->
    <img src="/upload/1.png">

</body>
</html>

在這裏插入圖片描述
這樣不論是在idea裏運行還是打包運行,都可以完美的獲取上傳和獲取圖片

(2)單文件上傳(異步)

在(1)非異步單文件上傳的基礎,再實現異步單文件上傳
前端代碼

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>無刷文件上傳</title>
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet">
    <script th:src="@{/js/jquery.min.js}"></script>
</head>
<body>
<div th:if="${msg}" style="color: red" th:text="${msg}">上傳成功</div>


<form id="form" th:action="@{/ajaxUploadFile}" >
    <div class="form-group">
        <label>無刷文件上傳</label>
        <input type='file' style='margin: 5px;' name='files' required='required'>
        <input id="submit" type="button" value="上傳" onclick="ajaxUpload()" style="margin-top: 10px"/>
    </div>

</form>


<script type="text/javascript">
    function ajaxUpload() {
        var form=new FormData();
        //獲取選擇的文件
        $.each($('input[name="files"]'),function (index,item) {
            form.append("files",item.files[0])
        });


        //發送異步請求
        $.ajax({
            method:'post',
            url:'/ajaxUploadFile',
            data:form,
            processData: false,
            contentType:false,
            success:function (res) {
                //成功返回觸發的方法
                alert(res.msg);
            },
            //請求失敗觸發的方法
            error:function () {
                console.log("ajax請求失敗");
            }
        })
    }

</script>
</body>
</html>

後端代碼


    //來到單文件上傳頁面(異步)
    @GetMapping("/ajaxUpload")
    public String ajaxUpload(){return "ajaxUpload";}

    //文件上傳管理(異步)
    @PostMapping("/ajaxUploadFile")
    @ResponseBody
    public Map ajaxUploadFile(MultipartFile[] files){
        Map<String,Object> map=new HashMap<>();
        for(MultipartFile file:files){
            //獲取文件名以及後綴名
            String fileName=file.getOriginalFilename();

            //獲取jar包所在目錄
            ApplicationHome h = new ApplicationHome(getClass());
            File jarF = h.getSource();
            //在jar包所在目錄下生成一個upload文件夾用來存儲上傳的圖片
            String dirPath = jarF.getParentFile().toString()+"/upload/";
            System.out.println(dirPath);



            File filePath=new File(dirPath);
            if(!filePath.exists()){
                filePath.mkdirs();
            }
            try{
                //將文件寫入磁盤
                file.transferTo(new File(dirPath+fileName));
                //文件上傳成功返回狀態信息
                map.put("msg","上傳成功!");
            }catch (Exception e){
                e.printStackTrace();
                //上傳失敗,返回失敗信息
                map.put("msg","上傳失敗!");
            }
        }
        //攜帶上傳狀態信息回調到文件上傳頁面
        return map;
    }

在這裏插入圖片描述
在這裏插入圖片描述
獲取圖片的方式參考(1)單文件上傳(非異步)

三、總結

(1)圖片不能存儲在項目裏面的靜態資源裏面
(2)圖片存儲的位置在jar包所在目錄,沒打jar包時是target下的目錄位置,打jar包後是jar所在目錄(動態)
(3)圖片存儲路徑的獲取用以下代碼,獲取的路徑是target的目錄

        //獲取jar包所在目錄
        ApplicationHome h = new ApplicationHome(getClass());
        File jarF = h.getSource();
        //在jar包所在目錄下生成一個upload文件夾用來存儲上傳的圖片
        String dirPath = jarF.getParentFile().toString()+"/upload/";
        System.out.println(dirPath);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章