

SpringBoot+Vue+token实现(表单+图片)上传、图片地址保存到数据库。上传图片保存位...
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 前端文件上传部分
只给出文件上传部分、其余的就是正常的表单

<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 查看返回给前端的图片地址



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

2.5 查看存储到数据库中的图片资源地址
这里存放的不是图片在磁盘中的绝对路径、需要做图片资源映射使用的

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

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、要放行图片资源。否则拦截

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>
成功达到效果后、感觉也不太难。就是一看就会、一试就废。难的是自己在解决过程中、遇到问题了,这个解决问题的过程是真的不好受呐、还是自己太菜了撒
挑战自我、学无止境。。。。。。
下一篇、优化以下代码,将图片存储到项目中的静态资源下。其实是和存放到本地没有啥差别。就是一个路径的问题。
Recommend
-
92
项目中需要上传图片可谓是经常遇到的需求,本文将介绍 3 种不同的图片上传方式,在这总结分享一下,有什么建议或者意见,请大家踊跃提出来。 没有业务场景的功能都是耍流氓,那么我们先来模拟一个需要实现的业务场景。假设我们要做一个后台系统添加商品的页面,有...
-
25
简单记录一下在Springboot中上传文件到AWS S3存储服务的代码。 在 application . xml 中添加aws相关配置: custom: aw...
-
18
在 Flask 程序中实现 CKEditor 图片上传和 CSRF 保护 1条回复 《Flask Web 开发实战》第 2 个实战项目是一个博客(
-
9
typecho七牛云上传图片(复制粘贴)毕竟图片放置到自己的服务器端有点不合适,所以还是想着有什么好办法能够直接放到七牛云吧实现流程大概如下获取编辑器粘贴事件,获取图片base64编码上传base6...
-
5
by zhangxinxu from http://www.zhangxinxu.com/wordpress/?p=6308 本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随...
-
7
从RFC规范看如何绕过waf上传表单 上篇 阅读量 39361...
-
8
用户列表页面开发 用户列表页面开发,可以实现简单的查询,删除,修改,和添加用户信息功能。前端使用vue框架,后端使用springboot框架,一个简单的vue+springboot前后端分离小项目。 本项目主要模块及技术点如图 项目源码...
-
8
rfc2388表单上传文件NodeJS无依赖版本实现 - TheNorthMemory官方文档小分队犯了一个错误,就是试图用文本语言来表达非字符内容,整得一众开发者迷途了,社区反馈波澜滔滔。这支小分队应该每人扣一个长鹅抱宠,捐给像俺这样努力帮扶开发者的贡献者(😄)。其实rfc...
-
9
springboot项目上传存储图片到七牛云服务器 问题描述: 当图片存在本地时会出现卡顿的现象。比如一篇图文混排的文章,如果图片没有加载完,可能整个文章都显示不出来,因为它们都是用的同一个服务器...
-
11
每创建一个虚拟环境类似于重新下载了一个纯净的python解释器 但虚拟环境不要创建太多,会占用电脑硬盘空间 python项目1需要使用:django1.11 python38 项目2需要使用:django2.2...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK