Spring Boot与Vue:实现图片的上传

news/2024/4/24 21:47:27/文章来源:https://blog.csdn.net/weixin_47678542/article/details/129185208

文章目录

  • 1. 项目场景
  • 2. 问题描述
  • 3. 实现方案
    • 3.1 方案一:上传图片,转换成 Base64 编码并返回
      • 3.1.1 前端页面组件
      • 3.1.2 前端 JS 函数
      • 3.1.3 后端 Controller
    • 3.2 方案二:上传图片,并返回图片路径
      • 3.2.1 前端页面组件
      • 3.2.1 前端 JS 函数
      • 3.2.3 后端 Controller
      • 3.2.4 后端设置静态资源映射
      • 3.2.5 编译器设置
  • 4. 总结

1. 项目场景

本项目基于 Vue 与 SSM 框架,为前后端分开的项目。


2. 问题描述

在前端页面选择本地图片并实现上传至后端服务器。


3. 实现方案

3.1 方案一:上传图片,转换成 Base64 编码并返回

3.1.1 前端页面组件

使用 el-upload 辅助上传。

<el-uploadclass="upload-demo"ref="upload"action="":http-request="upload"multiple="":auto-upload="false"><el-button slot="trigger" size="small" type="primary">选取文件</el-button><el-button style="margin-left: 10px" size="small" type="success" @click="submitUpload">上传到服务器</el-button><div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>

3.1.2 前端 JS 函数

methods: {submitUpload () {this.$refs.upload.submit()},// 通过onchanne触发方法获得文件列表handleChange (file, fileList) {this.fileList = fileListconsole.log(fileList)},handlePreview (file) {console.log(file)},upload (file) {const _this = thislet formdata = new FormData()// 上传图片并转成Base64编码formdata.append('files', file.file)console.log(formdata)this.$axios.post('/uploadImage', formdata).then((resp) => {if (resp.status === 200) {console.log(resp.data)// 设置图片回显_this.form.logo = resp.data_this.$message({type: 'success', message: '图片上传成功!'})}}).catch(() => {this.$message({type: 'info', message: '图片太大或格式有误,上传失败,请重新上传!'})})}
}

3.1.3 后端 Controller

    @ResponseBody@RequestMapping(value = "/api/uploadImage", method = RequestMethod.POST)public String uploadImage(@RequestParam("files") MultipartFile file) throws IllegalStateException, IOException {System.out.println(file.getOriginalFilename() + "图片已传入!!");byte[] b = file.getBytes();String str = Base64.getEncoder().encodeToString(b);return "data:image/jpeg;base64," + str;}

vue上传文件到后端,前端接收到后端传来的图片并显示

3.2 方案二:上传图片,并返回图片路径

该方案使用普通上传的方式,即将前端页面所选择的本地图片文件直接上传至服务器,并保存在后端静态文件夹下。

上传成功则返回图片在服务器中的路径,使所上传的图片回显至前端页面。

3.2.1 前端页面组件

这里和 3.1 一样。

3.2.1 前端 JS 函数

methods: {submitUpload () {this.$refs.upload.submit()},// 通过onchanne触发方法获得文件列表handleChange (file, fileList) {this.fileList = fileListconsole.log(fileList)},handlePreview (file) {console.log(file)},upload (file) {const _this = thislet formdata = new FormData()// 上传图片并返回路径formdata.append('image', file.file)this.$axios.post('/uploadImage', formdata, {headers: {'Content-Type': 'multipart/form-data'}}).then((resp) => {if (resp.status === 200) {console.log(resp.data)// 设置图片回显_this.form.f_logo = resp.data_this.$message({type: 'success', message: '图片上传成功!'})}}).catch(() => {this.$message({type: 'info', message: '图片太大或格式有误,上传失败,请重新上传!'})})}
}

3.2.3 后端 Controller

完整的图片路径:src/main/resources/static/images/firms/yyyy-MM-dd/图片

    final static String PIC_PATH = "static/images/firms/"; // 图片存放的相对于项目的相对位置/***上传图片*/@PostMapping("/api/uploadImage")public String uploadImage(MultipartHttpServletRequest multiRequest, HttpServletRequest request){System.out.println("上传图片");SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); //生成日期格式String datePrefix = dateFormat.format(new Date()); //生成当前日期作为前缀String savePath = "src/main/resources/" + PIC_PATH; // 存储路径File folder = new File(savePath+datePrefix); //生成带当前日期的文件路径if(!folder.isDirectory()){folder.mkdirs();}String randomName = Objects.requireNonNull(multiRequest.getFile("image")).getOriginalFilename(); //获取图片名//生成随机数确保唯一性,并加上图片后缀assert randomName != null;String saveName = UUID.randomUUID().toString() + randomName.substring(randomName.lastIndexOf("."),randomName.length());String absolutePath = folder.getAbsolutePath(); //转换成绝对路径try {File fileToSave = new File(absolutePath + File.separator + saveName);Objects.requireNonNull(multiRequest.getFile("image")).transferTo(fileToSave); // 图片存储到服务端String returnPath = request.getScheme() + "://" + request.getServerName()+":"+request.getServerPort() + "/images/firms/" + datePrefix +"/"+ saveName;return returnPath;}catch (Exception e){e.printStackTrace();}return null;}

mavon-editor编辑器与图片上传

3.2.4 后端设置静态资源映射

其实是不建议往resources目录下直接写入业务相关的文件(尤其是存储图片)的,因为后续可能会遇到

  • 资源的实时访问问题,比如上传图片后,然后再访问,可能需要重启才能继续访问
  • jar对resources目录进行保护措施,可能读取不到上传的资源

解决Spring Boot访问resources目录下的static资源问题(详细版)

为了实现上传图片后可以完成回显,在前端实时显示图片,避免出现访问图片路径出现 404 的情况,我们要做静态资源映射。

配置类:

package com.example.spring.config;import org.springframework.boot.SpringBootConfiguration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@SpringBootConfiguration
public class MyWebConfigurer implements WebMvcConfigurer {/*** 所有请求都允许跨域,使用这种配置就不需要* 在interceptor中配置header了*/@Overridepublic void addCorsMappings(CorsRegistry corsRegistry){corsRegistry.addMapping("/**").allowCredentials(true).allowedOrigins("http://localhost:8085").allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE").allowedHeaders("*").maxAge(3600);}/*** 图片虚拟地址映射* @param registry* 设置该映射之后,外网只能访问本地的images文件内部的资源*/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/images/**").addResourceLocations("file:" + System.getProperty("user.dir")+"\\src\\main\\resources\\static\\images\\");}
}

SpringBoot实现图片上传,图片上传之后无法访问

配置文件(application.properties):

## 静态资源访问路径
spring.mvc.static-path-pattern=/**
## 静态资源映射路径
spring.resources.static-locations=classpath:/

看完这篇SpringBoot访问静态资源,我感觉我又会了!!!

3.2.5 编译器设置

编译器设置


4. 总结

本文记录了在 Vue 与 Spring Boot 相结合的项目中实现图片上传的两种方案,两种方案各有优缺点。

方案一:使用 Base64 直接把图片编码成字符串写入 CSS 文件

优点:

  • 能够减少一个图片的 HTTP 请求
  • 适用于极小或者极简单图片
  • 可像单独图片一样使用,比如背景图片重复使用等
  • 没有跨域问题,无需考虑缓存、文件头或者 cookies 问题

缺点:

  • 转化为 Base64 的图片大大增加了 CSS 文件的体积
    CSS 文件的体积直接影响渲染,导致用户会长时间注视空白屏幕
  • 页面解析 CSS 生成的 CSSOM 时间增加

【前端攻略】:玩转图片Base64编码

方案二:使用常规方式直接上传图片至服务器

优点:

  • 图片不会导致关键渲染路径的阻塞

缺点:

  • 对每张图片都需要发起一个 HTTP 请求
  • 需要考虑静态资源映射、文件头。跨域访问等问题,以及图片的命名方式,故后端代码较为复杂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_73145.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux网络编程-多进程实现TCP并发服务器

服务端流程步骤socket函数创建监听套接字lfdbind函数将监听套接字绑定ip和端口listen函数设置服务器为被动监听状态&#xff0c;同时创建一条未完成连接队列&#xff08;没走完tcp三次握手流程的连接&#xff09;&#xff0c;和一条已完成连接队列&#xff08;已完成tcp三次握手…

HTML Flex 布局

基本概念 采用 Flex 布局的元素&#xff0c;称为 Flex 容器&#xff08;flex container&#xff09;&#xff0c;简称“容器”。它的所有子元素自动成为容器成员&#xff0c;称为 Flex 项目&#xff08;flex item&#xff09;&#xff0c;简称“项目”。容器默认存在两根轴&am…

JavaSE之常用关键字学习

文章目录Java常用关键字学习1、static关键字学习1.1 用法一&#xff1a;修饰成员变量1.2 用法二&#xff1a;修饰成员方法1.3 用法三&#xff1a;修饰代码块1.4 用法四&#xff1a;修饰内部类类1.5 单例设计模式2、extends关键字学习2.1 继承的特点2.2 方法重写3、this、super关…

基于Comsol的花瓣形穿孔微穿孔板的吸声理论仿真

研究背景&#xff1a; 为了抑制噪声污染&#xff0c;已经开发了许多吸声材料和结构。传统的吸声材料&#xff0c;如开孔泡沫和纤维棉&#xff0c;随着时间的推移会劣化&#xff0c;因为小颗粒常常从这些多孔材料的骨架中脱落。此外&#xff0c;脱落的小颗粒可能污染建筑物内的…

立项近7年,索尼产品经理分享PS VR2开发背后的故事

备受期待的索尼PS VR2终于正式发售&#xff0c;VR爱好者们终于有机会体验到《地平线&#xff1a;山之呼唤》等PS VR2独占的VR大作。近期&#xff0c;为了解PS VR2头显诞生背后的故事&#xff0c;外媒AV Watch采访到PS VR2的开发负责人Yasuo Takahashi&#xff0c;在本次采访中&…

面试题-----JDBC单例模式(懒汉式和饿汉式)

1.单例概念 作为一种常见的设计模式&#xff0c;单例模式的设计概念是"两个私有,一个公有",即私有属性/成员变量和私有构造,以及公有方法,常用于在整个程序中仅调用一次的代码。 2.具体操作 从单例模式的描述来看,单例模式并不能用于多次频繁调用的设计中,而更适用…

剑指 Offer 55 - I. 二叉树的深度

摘要 剑指 Offer 55 - I. 二叉树的深度 一、深度优先搜索 如果我们知道了左子树和右子树的最大深度l和r&#xff0c;那么该二叉树的最大深度即为&#xff1a;max(l,r)1。 而左子树和右子树的最大深度又可以以同样的方式进行计算。因此我们可以用「深度优先搜索」的方法来计…

校园学生翻墙打架识别检测系统 yolov7

校园学生翻墙打架识别检测系统通过yolov7网络模型深度学习分析技术&#xff0c;校园学生翻墙打架识别检测算法可以对&#xff1a;打架行为、倒地行为识别、人员拥挤行为、攀高翻墙违规行为等违规行为进行实时分析检测。YOLOv7 的发展方向与当前主流的实时目标检测器不同&#x…

动手学深度学习v2—01数据操作+数据预处理

[TOC]此次用到的虚拟环境&#xff1a;pytorchmwy项目名称&#xff1a;limuAI所需框架和工具&#xff1a;pytorch&#xff0c;pandas一、创建CSV文件所需工具&#xff1a;pandas在与项目同等目录下创建一个文件夹名为data&#xff0c;其中文件名称为house_tiny.csv。代码如下&am…

随想录二刷 (双指针法) leetcode 27 26 283 844

双指针法的原理 双指针法相对于暴力解法的优点有以下几点 暴力遍历的时间复杂度会比较高双指针法利用两个指针进行遍历完成双层循环所做的事情 双指针一般有两种方法 同向指针&#xff0c;双向指针 第一题 leetcode 27 移除元素 题目描述 题目分析 采用暴力遍历可以得出结…

高效制作知识库的软件工具,这6个都很不错哦!

任何工作流程都离不开文档管理&#xff0c;因此文档管理也是企业数字化转型中的重要环节。面对复杂的业务流程、频繁的文档编辑任务和跨区域的文件共享需求&#xff0c;优秀的文档管理体系能够帮助企业实现安全的文档存储&#xff0c;高效的文档搜索&#xff0c;便捷的文档协作…

(一)Spring-Cloud源码分析之核心流程关系及springcloud与springboot包区别(新)

文章目录1. 前言2. springcloud简介3. Springcloud包简介4. Springcloud和Springboot流程关系5. Springcloud启动流程新增的功能和接口5.1 新增接口5.2 新增功能类5.2.1 spring-cloud-context包5.2.2 spring-cloud-commons包6. Springcloud实现机制带来的问题7. Springcloud和S…

深入浅出C++ ——手撕红黑树

文章目录一、红黑树的概念二、红黑树的性质三、红黑树节点的定义四、红黑树的插入操作五、红黑树的验证五、红黑树的删除六、红黑树与AVL树的比较七、红黑树的应用八、红黑树模拟实现一、红黑树的概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存…

Typecho COS插件实现网站静态资源存储到COS,降低本地存储负载

Typecho 简介Typecho 是一个简单、强大的轻量级开源博客平台&#xff0c;用于建立个人独立博客。它具有高效的性能&#xff0c;支持多种文件格式&#xff0c;并具有对设备的响应式适配功能。Typecho 相对于其他 CMS 还有一些特殊优势&#xff1a;包括可扩展性、不同数据库之间的…

(二十五)、实现评论功能(5)【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】

1&#xff0c;实现二级回复的入库操作 1.1 两个子组件&#xff08;comment-item和comment-frame&#xff09;与父组件reply之间的属性传值 comment-item&#xff1a; props: {item: {type: Object,default () {return {}}}},comment-frame&#xff1a; props: {commentObj: {…

儿童饰品发夹发卡出口美国办理什么认证?

亚马逊美国站上传新产品&#xff0c;很多时候都是需要类目审核的&#xff0c;后台给出要求提供认证&#xff0c;产品类目不同&#xff0c;所需要提供的认证证书是不一样&#xff0c;儿童产品需要提交的是CPC认证&#xff0c;玩具&#xff0c;母婴用品&#xff0c;儿童书包&…

PDF文件怎么转图片格式?转换有技巧

PDF文件有时为了更美观或者更直观的展现出效果&#xff0c;我们会把它转成图片格式&#xff0c;这样不论是归档总结还是存储起来都会更为高效。有没有合适的转换方法呢&#xff1f;这就来给你们罗列几种我个人用过体验还算不错的方式&#xff0c;大家可以拿来参考一下哈。1.用电…

Apifox = Postman + Swagger + Mock + JMeter

目录 可视化API设计 高效 & 零学习成本 可复用的“数据模型” 遵循 OpenAPI(Swagger) 规范 可导入 Swagger 等 20 数据格式 具体使用尝鲜 多项目管理 支持多环境切换 支持IDEA、浏览器、桌面应用 Idea插件 公共API hub库 如题&#xff1a;一款非常好用的API管理测…

Wi-Fi 7技术揭秘

引言 2022年4月7日&#xff0c;紫光股份旗下新华三集团全球首发企业级智原生Wi-Fi 7 AP新品 WA7638和WA7338。仅在同年的6月15日&#xff0c;在东京举行的第29届日本网络通信展览会&#xff08;Interop Tokyo 2022&#xff0c;简称Interop展&#xff09;中&#xff0c;WA7638就…

D1s RDC2022纪念版开发板开箱评测及点屏教程

作者new_bee 本文转自&#xff1a;https://bbs.aw-ol.com/topic/3005/ 目录 芯片介绍开发板介绍RT-Smart用户态系统编译使用感想引用 1. 芯片介绍 RISC-V架构由于其精简和开源的特性&#xff0c;得到业界的认可&#xff0c;近几年可谓相当热门。操作系统方面有RT-Thread&am…