天天看點

SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語

1、大緻思路

以下是基于先處理圖檔、後端傳回圖檔位址進行的

==存資料==

1、将圖檔資訊送出到後端

2、後端處理

3、後端傳回前端圖檔的通路位址

4、前端将圖檔位址存入要送出的表單中

5、将整個表單送出到後端、将資料存入資料庫

==取資料==

1、前端擷取後端傳回的資訊(包含圖檔的通路路徑)

2、将通路圖檔的資源放到對應的标簽或者元件中、按照自己的方式進行展示。(如果後端沒有做圖檔資源的位址映射、會顯示找不到對應的資源)

<hr>

2、将圖檔和表單資料儲存的資料庫

2.1 前端檔案上傳部分

隻給出檔案上傳部分、其餘的就是正常的表單

SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語
<el-form-item label="上傳檔案">
                      <input
                        @change="upload"
                        @click="clearFile"
                        multiple="multiple"
                        type="file"
                        ref="file"
                      />
                    </el-form-item>
           

這裡可以選擇使用上傳多個檔案、是以使用集合的形式。<為了後期擴充多檔案上傳、暫時保留、也可以選擇 不适用集合形式。隻上傳一個檔案>。這裡使用==FormData==來傳輸、然後要在請求頭中加上

'Content-Type': 'multipart/form-data'

我這裡對axios進行了二次封裝、請求方式有所不同。你們按照自己的方式正常發送接口請求就可以。

//檔案上傳
    upload: function () {
      let files = this.$refs.file.files;
      const _this = this;
      for (let i = 0; i < files.length; i++) {
        let formData = new FormData();
        formData.append("file", files[i]);
        this.$axios.uploadFile(formData).then((res) => {
          if (res.code == 200) {
            _this.$message("檔案上傳成功");
            console.log(res.data.fileName);
            this.GoodsInfoForm.fileName = res.data.fileName;
            console.log(this.GoodsInfoForm.fileName);
          } else {
            _this.$message("error", res.data.msg);
          }
        });
      }
    },
           

==友情提示:以下兩個點可以忽略不看,對axios二次封裝的一些小記錄==

我這裡進行了axios的二次封裝、是以調用接口的方式有所不同。你們按照自己的配置正常發送接口請求就行

/**
     * 檔案上傳
     */
    uploadFile: (params) => {
        return Post('http://localhost:8282/goodsInfo/upload', params);
    }
           

這個也是進行的axios的二次封裝、可以忽略。重要的一點是請求頭中加上

'Content-Type': 'multipart/form-data'

const instance = axios.create({
    baseURL: 'http://localhost:8282',
    timeout: 3000,
    headers: {
        post: {
            'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' ,
             'Content-Type': 'multipart/form-data'
        }

    }
})
           

2.2 後端處理檔案的接口部分

2.2.1使用工具類操作

在pom檔案中引入操作File的工具依賴。使用工具類操作還是很簡潔友善的。

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.7</version>
        </dependency>
           
import cn.hutool.core.io.FileUtil;//需要引入這個、引入不對、無法使用對應的方法


/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/11 21:32
 */
@RestController
public class GoodsfileInfoController {
    @Autowired
    GoodsFileInfoMapper gfMapper;

    private static final String ABSOLUTE_FILE_PATH = "E:\\Lenovo\\Documents\\upload\\images\\";

    /**
     * 檔案上傳 絕對
     * @param file
     * @return
     */
    @RequestMapping(value = "/goodsInfo/upload",method = RequestMethod.POST)
    public Result upload(MultipartFile file, HttpServletRequest request) throws IOException {
        String originName = file.getOriginalFilename();
        // 1、檔案名加個時間戳
        String fileName = FileUtil.mainName(originName) + System.currentTimeMillis() + "." + FileUtil.extName(originName);
        // 2、檔案存放的絕對路徑 存放名稱
        String storageName = ABSOLUTE_FILE_PATH + fileName;
        // 3. 檔案上傳
        FileUtil.writeBytes(file.getBytes(),storageName );
        String final_fileName ="http://localhost:8282/images/" + fileName;
        return Result.ok().data("fileName",final_fileName);

    }
}


           

<hr>

2.2.2 一般的操作

2.2.1 和 2.2.2 可以自行選擇使用、實作的效果是一樣的

一般的檔案寫入操作、這個對檔案名的處理還是使用的工具類。自己也可以根據自己的要求、自行處理檔案名

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/11 21:32
 */
@RestController
public class GoodsfileInfoController {
    @Autowired
    GoodsFileInfoMapper gfMapper;


    private static final String ABSOLUTE_FILE_PATH = "E:\\Lenovo\\Documents\\upload\\images\\";

    /**
     * 檔案上傳 絕對
     * @param file
     * @return
     */
    @RequestMapping(value = "/goodsInfo/upload",method = RequestMethod.POST)
    public Result upload(MultipartFile file, HttpServletRequest request) throws IOException {
        System.out.println(System.getProperty("user.dir"));
        String originName = file.getOriginalFilename();
        // 1、檔案名加個時間戳
        String fileName = FileUtil.mainName(originName) + System.currentTimeMillis() + "." + FileUtil.extName(originName);
        System.out.println(fileName);

        // 2、檔案存放的絕對路徑 存放名稱
        String storageName = ABSOLUTE_FILE_PATH + fileName;

       // 3. 檔案上傳
        File dest = new File(storageName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
        }

        String final_fileName ="http://localhost:8282/images/" + fileName;
        return Result.ok().data("fileName",final_fileName);


    }
}

           

2.3 檢視傳回給前端的圖檔位址

SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語
SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語
SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語

2.4 前端儲存後端傳回的圖檔位址

SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語

2.5 檢視存儲到資料庫中的圖檔資源位址

這裡存放的不是圖檔在磁盤中的絕對路徑、需要做圖檔資源映射使用的
SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語

2.6 存到對應磁盤位置的圖檔

SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語

3、後端配置

3.1 圖檔資源映射

這裡給出使用java代碼的形式盡心資源映射、下一篇優化在配置檔案中進行配置

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/12 18:58
 */
@Configuration
public class URLConfig implements WebMvcConfigurer {
    /**
     *  * 資源映射路徑
     *  * addResourceHandler:通路映射路徑
     *  * addResourceLocations:資源絕對路徑
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**").addResourceLocations("file:"+"E:\\Lenovo\\Documents\\upload\\images\\");

    }

}

           

3.2 如果設定了token、要放行圖檔資源。否則攔截

SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語
SpringBoot+Vue+token實作(表單+圖檔)上傳、圖檔位址儲存到資料庫。上傳圖檔儲存位置自己定義、圖檔可以在前端回顯(一))1、大緻思路2、将圖檔和表單資料儲存的資料庫3、後端配置4、圖檔的回顯5、後語

3.3 如果圖檔資源帶有中文導緻的圖檔資源通路不到、配置過濾器、設定編碼格式

package com.zyz.bookshopmanage.config;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.URLDecoder;

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/12 23:04
 */
@Configuration
public class UrlFilter implements Filter {

    public final static String DEFAULT_URI_ENCODE = "UTF-8";

    private FilterConfig config = null;
    private String encode = null;

    @Override
    public void destroy() {
        config = null;
    }

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
                         FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        String uri = request.getRequestURI();
        String ch = URLDecoder.decode(uri, encode);
        if(uri.equals(ch)) {
            chain.doFilter(req, res);
            return;
        }
        ch = ch.substring(request.getContextPath().length());
        config.getServletContext().getRequestDispatcher(ch).forward(req, res);

    }

    @Override
    public void init(FilterConfig config) throws ServletException {
        this.config = config;
        this.encode = config.getInitParameter("DEFAULT_URI_ENCODE");
        if(this.encode == null) {
            this.encode = DEFAULT_URI_ENCODE;
        }
    }

}
           

4、圖檔的回顯

圖檔回顯的方式和種類蠻多、我這邊想要實作的效果、是點選按鈕來展示對應的圖檔。你也可以直接将圖檔放到表格中

在商品資訊界面、點選預覽,将對應商品的圖檔彈窗的形式展示出來

4.1 前端代碼

<el-table-column label="商品圖檔">
                    <template slot-scope="scopes">
                      <button
                        class="btn btn-primary btn-xs"
                        @click="showImage(scopes.$index, scopes.row)"
                      >
                        預覽
                      </button>
                    </template>
                  </el-table-column>
           
//檔案顯示
    showImage: function (index, row) {
      console.log(row.fileName);
      const myimgUrl = row.fileName;
      this.dialogVisibleImage = true;
      this.$nextTick(function () {
        //擷取元素
        $("#view-img").empty();
        $("#view-img").append(
          $(
            `<img  src="${myimgUrl}" style="width: 400px; margin-bottom: 5px" alt="">`
          )
        );
      });
    },
           
<el-dialog
                  title="檔案預覽"
                  :visible.sync="dialogVisibleImage"
                  width="30%"
                  :before-close="handleClose"
                >
                  <div
                    id="view-img"
                    class="modal-body"
                    style="text-align: center"
                  ></div>
                </el-dialog>
           

5、後語