3

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位...

 1 year ago
source link: https://blog.51cto.com/u_15740728/5816085
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1、大致思路

以下是基于先处理图片、后端返回图片地址进行的

存数据
1、将图片信息提交到后端
2、后端处理
3、后端返回前端图片的访问地址
4、前端将图片地址存入要提交的表单中
5、将整个表单提交到后端、将数据存入数据库

取数据
1、前端获取后端返回的信息(包含图片的访问路径)
2、将访问图片的资源放到对应的标签或者组件中、按照自己的方式进行展示。(如果后端没有做图片资源的地址映射、会显示找不到对应的资源)

<hr>

2、将图片和表单数据保存的数据库

2.1 前端文件上传部分

只给出文件上传部分、其余的就是正常的表单

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_文件上传
                    <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实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_插入图片_02
SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_插入图片_03
SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_vue_04

2.4 前端保存后端返回的图片地址

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_插入图片_05

2.5 查看存储到数据库中的图片资源地址

这里存放的不是图片在磁盘中的绝对路径、需要做图片资源映射使用的

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_java_06

2.6 存到对应磁盘位置的图片

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_文件上传_07

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实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_java_08

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_文件上传_09

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、图片的回显

图片回显的方式和种类蛮多、我这边想要实现的效果、是点击按钮来展示对应的图片。你也可以直接将图片放到表格中

在商品信息界面、点击预览,将对应商品的图片弹窗的形式展示出来

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位置自己定义、图片可以在前端回显(一))_插入图片_10

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>

成功达到效果后、感觉也不太难。就是一看就会、一试就废。难的是自己在解决过程中、遇到问题了,这个解决问题的过程是真的不好受呐、还是自己太菜了撒
挑战自我、学无止境。。。。。。

下一篇、优化以下代码,将图片存储到项目中的静态资源下。其实是和存放到本地没有啥差别。就是一个路径的问题。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK