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

news2024/9/27 5:41:22

文章目录

  • 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-upload
	class="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 = fileList
      console.log(fileList)
    },
    handlePreview (file) {
      console.log(file)
    },
    upload (file) {
      const _this = this
      let 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 = fileList
      console.log(fileList)
    },
    handlePreview (file) {
      console.log(file)
    },
    upload (file) {
      const _this = this
      let 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了
    */
    @Override
    public void addCorsMappings(CorsRegistry corsRegistry){
        corsRegistry.addMapping("/**")
                .allowCredentials(true)
                .allowedOrigins("http://localhost:8085")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .allowedHeaders("*")
                .maxAge(3600);
    }

    /**
     * 图片虚拟地址映射
     * @param registry
     * 设置该映射之后,外网只能访问本地的images文件内部的资源
     */
    @Override
    public 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.coloradmin.cn/o/367080.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

shell的函数

一、shell函数 有些脚本段间互相重复&#xff0c;如果能只写一次代码块而在任何地方都能引用那就提高了代码的可重用性。 shell 允许将一组命令集或语句形成一个可用块&#xff0c;这些块称为 shell 函数。 二、shell函数的格式 2.1.第一种格式 函数名&#xff08…

selenium自动化测试用例需要关注的几点

自动化测试设计简介注&#xff1a;参看文章地址 我们在本章提供的信息&#xff0c;对自动化测试领域的新人和经验丰富的老手都是有用的。本篇中描述最常见的自动化测试类型&#xff0c; 还描述了可以增强您的自动化测试套件可维护性和扩展性的“设计模式”。还没有使用这些技术…

Clion安装Platformio支持

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言一、系统配置二、什么是platformio三、安装配置1.安装Clion2.安装platformio插件3.安装platformio&#xff08;CLI&#xff09;4. 配置Clion环境5. 创建示例Demo…

低功耗设计:rush current

在power gating的设计中有一个rush current的概念&#xff0c;它的产生原因是switch cell上电过程相当于电容充电过程&#xff0c;会产生一个短期的大电流&#xff0c;称之为rush current。 1.rush current的危害 1&#xff09;rush current产生的压降可能会造成大的短路电流…

Python学习笔记——NumPy

一、向量数据 ①概念 向量数据是指存储一系列同类数据的有序数据结构。 ②分类 python中的列表和元组可以用来存储向量数据。 分为 一维列表&#xff0c;二维列表&#xff0c;三(多)维列表。 ③向量数据结构的理解 二、产生原因 大量的向量数据计算时&#xff0c;使用pyt…

蓝桥杯的比赛流程和必考点

蓝桥杯的比赛流程和必考点 距省赛仅1个多月&#xff01;蓝桥杯的比赛流程和必考点&#xff0c;你还不清楚&#xff1f; “巷子里的猫很自由&#xff0c;却没有归宿&#xff1b;围墙里的狗有归宿&#xff0c;终身都得低头。人生这道选择题&#xff0c;怎么选都会有遗憾。” 但不…

弹性负载均衡器类型

Hello大家好&#xff0c;在本课时&#xff0c;我们将讨论AWS不同类型的弹性负载均衡器,也就是ELB。 对于认证考试您需要了解针对不同的场景使用哪种类型的负载均衡器。 负载均衡器类型 应用程序负载均衡器 第一个是应用程序负载均衡器&#xff0c;也就是ALB&#xff0c;ALB在…

ArcGIS手动分割矢量面要素从而划分为多个面部分的方式:Cut Polygons Tool

本文介绍在ArcGIS下属ArcMap软件中&#xff0c;通过“Cut Polygons Tool”工具&#xff0c;对一个面要素矢量图层加以手动分割&#xff0c;从而将其划分为指定形状的多个部分的方法。 对于一个面要素矢量文件&#xff0c;有时我们需要对其加以划分&#xff0c;通过手动勾勒新的…

Python杂题-- 内附蓝桥题:裁纸刀

杂题 ~~不定时更新&#x1f383;&#xff0c;上次更新&#xff1a;2023/02/23 蓝桥例题1-裁纸刀&#x1f52a; 问题描述 本题为填空题&#xff0c;只需要算出结果后&#xff0c;在代码中使用输出语句将所填结果输出即可。 小蓝有一个裁纸刀&#xff0c;每次可以将一张纸沿…

高阶数据结构之LRU Cache

文章目录什么是LRU Cache&#xff1f;LRU Cache的实现JDK中自带的数据结构模拟实现LRU Cache&#xff08;双向链表哈希表&#xff09;什么是LRU Cache&#xff1f; LRU的全称是“Least Recently Used”的缩写&#xff0c;表示最近最少的使用&#xff0c;是一种Cache替换算法&am…

机器学习和深度学习综述

机器学习和深度学习综述 1. 人工智能、机器学习、深度学习的关系 近些年人工智能、机器学习和深度学习的概念十分火热&#xff0c;但很多从业者却很难说清它们之间的关系&#xff0c;外行人更是雾里看花。在研究深度学习之前&#xff0c;先从三个概念的正本清源开始。概括来说…

2022-2-23作业

一、通过操作Cortex-A7核&#xff0c;串口输入相应的命令&#xff0c;控制LED灯进行工作 1.例如在串口输入led1on,开饭led1灯点亮 2.例如在串口输入led1off,开饭led1灯熄灭 3.例如在串口输入led2on,开饭led2灯点亮 4.例如在串口输入led2off,开饭led2灯熄灭 5.例如在串口输…

关于性能测试,你不可不知的内容

目录 1、性能测试概述 2、常见的性能测试指标 2.1、并发 2.2、响应时间 2.3、事务 2.3.1、事务响应时间 2.3.2、每秒事务通过数&#xff08;TPS&#xff09; 2.4、点击率 2.5、吞吐量 2.6、资源利用率 3、性能测试分类 3.1、一般性能测试 3.2、负载测试 3.3、压力…

虹科Dimetix激光测距仪在锯切系统中的应用

HK-Dimetix激光测距仪——锯切系统应用 许多生产设施&#xff0c;例如金属服务中心&#xff0c;使用切割锯将每个客户的订单切割成一定长度。定长切割过程通常涉及卷尺和慢跑锯的传送带。但更简单的替代方法是使用虹科Dimetix非接触式激光距离传感器。 为了切断大长度的棒材&…

Day898.Join语句执行流程 -MySQL实战

Join语句执行流程 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录的是关于Join语句执行流程的内容。 在实际生产中&#xff0c;关于 join 语句使用的问题&#xff0c;一般会集中在以下两类&#xff1a; 不让使用 join&#xff0c;使用 join 有什么问题呢&#xff1f;如果有…

1+1>2 ?多数据源关联分析系列…

数据表连接的 join 操作&#xff0c;相信大家都不陌生吧&#xff1f;在数据分析时&#xff0c;经常需要对多个不同的数据源进行关联操作&#xff0c;因此各类数据库的 SQL 语言都包含了丰富的 join 语句&#xff0c;以支持批计算关联。而在金融的业务场景中&#xff0c;流数据实…

系统崩溃如何恢复数据?4步,教您快速抢救丢失的数据

电脑保存着很多个人文件和数据&#xff0c;如果碰到电脑系统崩溃&#xff0c;可能会导致文件无法访问&#xff0c;甚至我们的数据会发生丢失的情况。系统崩溃如何恢复数据&#xff1f;我们先来了解下Windows操作系统发生崩溃的常见原因&#xff1a;一次性打开太多软件&#xff…

AG9300方案替代|替代AG9300设计Type-C转VGA方案|CS5260设计原理图

AG9300方案替代|替代AG9300设计Type-C转VGA方案|CS5260设计原理图 安格 AG9300是一款实现USB TYPE-C到VGA数据的单片机解决方案转换器。ALGOLTEK AG9300支持USB Type-C显示端口交替模式&#xff0c;AG9300可以将视频和音频流从USB Type-C接口传输到VGA端口。在AG9300&#xff0…

LeetCode 707. 设计链表

LeetCode 707. 设计链表 难度&#xff1a;middle\color{orange}{middle}middle 题目描述 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性&#xff1a;valvalval 和 nextnextnext。valvalval 是当前节点的值&#xff0c;nextnextnext 是指向下…

FastCGI sent in stderr: "PHP message: PHP Fatal error

服务器php7.2卸载安装7.4之后,打开网站一直无法访问,查看nginx错误日志发现一直报这个错误:2023/02/23 11:12:55 [error] 4735#0: *21 FastCGI sent in stderr: &#xff02;PHP message: PHP Fatal error: Uncaught ReflectionException: Class translator does not exist in …