前后端图片交互的简易方式

前后端图片交互的简易方式

  • 一、交互方式说明
  • 二、前后端具体代码实现
    • 前端具体代码实现
    • 后端具体代码
    • 实现效果

测试结果

请添加图片描述

一、交互方式说明

在项目的实际开发中,难免会遇到前端需要渲染数据库中保存的图片,那咱知道图片也属于一种文件,不好保存到数据库,那怎么处理比较好呢?

这边小编采用的方式是将图片链接保存到数据库中,而实际图片保存在具体目录中。前端当使用el-image标签去渲染图片的时候,也相当于发一次Get方式的请求,这个时候后端再把具体目录的图片给它(以二进制的形式给它,然后el-image收到后会转成图片)。

测试技术栈说明
前端:vue3 + Element-plus
后端:SpringBoot

二、前后端具体代码实现

前端具体代码实现

下面是前端完成图片上传的ImageUpload组件代码。

<template>
    <el-upload
            :action="picAction"
            :limit="10"
            list-type="picture-card"
            accept=".png, .jpg"
            :on-success="sucessUpload"
            :on-error="errorUpload"
            :before-upload="beforeUpload"
    >
        <el-button size="small" type="primary"> 点击上传 </el-button>
    </el-upload>
    <el-image :src="imageAction" v-show="flag"/>
</template>

<script setup>
import {ElMessage, ElNotification} from "element-plus"
import {onBeforeUpdate, ref} from 'vue'
import Image from './Image.vue'

const picAction = ref('')// 这个可以说的保存图片发的请求,也可以去当作图片获取的请求
// 也就是说这个可以存到对应的数据库中
const imageAction = ref('')
const flag = ref(false)


function sucessUpload(){
    ElNotification({
        message: '图片上传成功',
        type: 'success',
        duration: 1500
    })
    console.log('success')
    flag.value=true
    imageAction.value = `http://localhost:8080/images?path=/test/${fileName}`
}

function errorUpload(){
    ElNotification({
        message: "图片上传失败",
        type: 'error',
        duration: 1500
    })
    console.log('error')
}
let fileName = ''
function beforeUpload(file){
    fileName = file.name
    picAction.value = `http://localhost:8080/images/test/${fileName}`
}

onBeforeUpdate(()=>{
    console.log(imageAction.value)
    console.log(666)
})

</script>

上面代码注意个细节:imageAction需要成功上传后再更改其值然后响应式,不然服务器端是没有的,一直会报文件无法找到异常。

在APP组件中使用这个ImageUpload组件做测试。在main.js文件中需要添加Element-plus一些东西,比如element-plus/dist/index.css(可以不加它,但是会好丑)。
下面是main.js代码

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App).use(ElementPlus)

app.mount('#app')

前端需要注意的点

  • 文件上传发送的请求方式是POST;
  • 可以用 before-upload 去设置一个上传前的回调函数,回调函数可以为其传递file参数,在这里可以进行事件的触发、向后端发送文件上传请求路径的设定等等操作。
  • el-upload 这个标签是用来上传文件的,图片是属于文件范畴的,所以是可以不局限于图片的,可灵活使用。

后端具体代码

后端代码内容大概分为以下俩步

  1. 设置允许跨域,设置允许某源进行访问;
  2. 具体的保存图片和获取图片的表示层实现。
  • 允许跨域代码(前端的端口号小编设置的是8081)
@Configuration
public class WebMvcOriginConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:8081/")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowCredentials(true);
    }

}
  • 配置请求资源映射(这步看你图片资源的位置,如果你的图片资源放在项目的根目录和src平级就不用配,如果你是放在项目之外或者说resources资源路径下,你需要配置这个资源映射)。
@Configuration
public class WebMvcImageConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/images/**")
                .addResourceLocations("file:images/");
    }
}
  • 具体存储图片和获取图片代码实现
@RestController
@RequestMapping("/images")
public class ImageController {


    @GetMapping
    public void getImage(@RequestParam("path") String path,
                         HttpServletResponse response) throws IOException {
        response.setContentType("image/png,image/jpeg");// 设置MIME类型,也就是响应类型
        ServletOutputStream out = response.getOutputStream();
        File file = new File("images" + path);
        InputStream in = new FileInputStream(file);
        int available = in.available();
        byte[] bytes = new byte[available];
        in.read(bytes);
        out.write(bytes);
        in.close();
        out.close();
    }

    @PostMapping("/{dirName}/{fileName}")
    public void setImage(MultipartFile file,
                         @PathVariable String dirName,
                         @PathVariable String fileName) throws IOException {

        File file1 = new File("images/" + dirName + "/" + fileName);
        OutputStream out = new FileOutputStream(file1);
        // 获取图片的输入流
        InputStream in = file.getInputStream();
        byte[] bytes = new byte[1024*100];//100kb
        int cnt = 0;
        // 开始存图片
        while((cnt=in.read(bytes))!=-1){
            out.write(bytes,0,cnt);
        }
        in.close();
        out.close();
    }
}

注意点

  1. 请求资源映射是根据图片的存放位置判断是否需要的(也就是上面的第二步),如果不配置这个的话,如果是存储在resources目录下,存储后是需要重启服务器才能访问到资源的。这是由于存储后的资源没有重新加载到服务器可访问到的地方。如果直接更改请求映射的资源路径,让一些请求的资源路径直接变化到磁盘上(绝对路径)。这样磁盘上的资源变化了,那路径可访问的资源也就变化了
  2. 需要使用SpringBoot提供的MultipartFile的接口,它可以用来处理文件上传,可以得到文件上传过程中的数据,可以得到其文件的输入流。(这里需要注意的是:MultipartFile不是Springboot的默认数据类型(不是像HttpServletRequest这样的),它是通过@RequestParam(“file”)注解引入的。小编上面的参数名是file,boot会给咱自动调@RequestParam(“file”)传参)
  3. 在使用response对象返回图片给前端时,需要设置响应类型(MIME类型)。

实现效果

首先说明一下这里本是没有图片文件的。
在这里插入图片描述
测试效果

请添加图片描述

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

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

相关文章

【零基础QQ机器人开发三】程序上云篇

前言&#xff1a;本文为大家带来QQ机器人程序上云的教程&#xff0c;环境搭建请参考下面链接 【0基础QQ机器人开发】基于go-cqhttp的QQ机器人开发教程,仅供自学 【零基础QQ机器人开发二】服务器篇 文章目录 程序Logger类StatuStore类MultiFunc类QQBot类main.py 前言&#xff1a…

高级Web题库

高级Web题库 For ZPT 声明 一切开发旨在学习&#xff0c;请勿用于非法用途 by rick rick 关注 永雏塔菲喵 永雏塔菲喵 选择题 第1题 知识点&#xff1a;CSS 题目&#xff1a;设置text-decoration属性的删除线的值为&#xff08; &#xff09;。 选项&#xff1a; A underlin…

Pytest自动化测试框架一些常见的插件

Pytest拥有丰富的插件架构&#xff0c;超过800个以上的外部插件和活跃的社区&#xff0c;在PyPI项目中以“ pytest- *”为标识。 本篇将列举github标星超过两百的一些插件进行实战演示。 插件库地址&#xff1a;http://plugincompat.herokuapp.com/ 1、pytest-html&#xff…

冗余-安全设计的基石

冗余构成原理就是在系统中采用2套中央处理器&#xff08;CPU&#xff09;单元&#xff0c;其中1套为工作主机&#xff0c;1套为热备&#xff0c;一旦工作主机发生故障&#xff0c;热备的CPU将自动投入工作&#xff0c;此时热备的CPU变为工作主机&#xff0c;原工作主机故障处理…

a标签属性href的多种写法

众所周知&#xff0c;a标签的最重要功能是实现超链接和锚点。而且&#xff0c;大多数人认为a标签最重要的作用是实现超链接&#xff0c;其实不单单是实现超链接的方法&#xff0c;今天新起点博客就来整理下a标签中href的几种用法。 1、a href“[removed]js_method();” 这是常用…

Android aidl及binder基础知识巩固

作者&#xff1a;义华 1、什么是binder binder是android framework提供的&#xff0c;用于跨进程方法调用的机制&#xff0c;具有安全高效等特点。 我们知道&#xff0c;在 Android 系统中&#xff0c;每个应用程序都运行在一个独立的进程中&#xff0c;各个进程之间需要进行…

chatGPT提问,BGP内容

ChatGPT提问&#xff1a;提问框架 背景角色任务要求 动态路由&#xff1a;内部网关协议&#xff1a;如RIP ISIS OSPF 在同一个公司内部运行的路由协议 外部网关协议&#xff1a;如 BGP 在不同公司之间运行的路由协议 AS&#xff1a;自治系统 每个自治系统都有唯一的…

玩机搞机-----安卓全机型 ADB FAST 各种指令解析说明与操作【二】基础联机

安卓全机型 玩机 搞机 ADB FAST 各种指令解析说明与操作_adb线刷命令_安卓机器的博客-CSDN博客 今天对上个帖子不足的地方进行补正。方便友友进行基础的联机操作&#xff0c;很多时候我们用adb指令的时候会有各种奇奇怪怪的问题。例如同一个机型&#xff0c;同一个指令。有时候…

OpenCL编程指南-4.4矢量操作符

矢量操作符 如下描述了可用于矢量数据类型或矢量和标量数据类型组合的各类操作符。 算术操作符 算术操作符&#xff08;加&#xff08;)、减&#xff08;–)、乘&#xff08;*&#xff09;和除&#xff08;/)&#xff09;&#xff0c;可以作用于内置整数、浮点标量和矢量数…

AWS 中的另外一种远程工具 AWS Session Manager

作者&#xff1a;SRE运维博客 博客地址&#xff1a;https://www.cnsre.cn/ 文章地址&#xff1a;https://www.cnsre.cn/posts/230129126154/ 相关话题&#xff1a;https://www.cnsre.cn/tags/aws/ 背景需求 因为项目的安全性。为了避免项目的服务器暴露在公网中。很多时候我们…

Python时间模块:time和datetime的区别与用法

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 目录标题 前言一. Python中表示时间的两种方式&#xff1a;二. time三. datetime1. datetime.datetime2.datetime.timedelta 尾语 &#x1f49d; 一. Python中表示时间的两种方式&#xff1a; 时间戳&#xff1a;相对于197…

OpenCL编程指南-3.2OpenCL上下文

OpenCL上下文 上下文是所有OpenCL应用的核心。上下文为关联的设备、内存对象&#xff08;例如&#xff0c;缓冲区和图像&#xff09;以及命令队列&#xff08;在上下文和各设备之间提供一个接口&#xff09;提供了一个容器。正是上下文驱动着应用程序与特定设备以及特定设备之…

Echarts 热力图的详细配置过程

文章目录 一&#xff0c;配置过程二&#xff0c;具体实例 一&#xff0c;配置过程 引入Echarts库和热力图插件 <script src"https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script> <script src"https://cdn.jsdelivr.net/npm/…

实时聊天如何做,让客户眼前一亮(二)

让我们继续讨论一下如何利用SaleSmartly&#xff08;ss客服&#xff09;在网站中的实时聊天视图如何提供出色的实时聊天体验。 四、在实时聊天会话期间 让我们来看看我们可以确保尽可能的提高客户体验的各种方法&#xff0c;使用SaleSmartly&#xff08;ss客服&#xff09;时聊…

算法设计 || 第5题:钓鱼问题-北京大学网站在线算法题(贪心算法)

目录 &#xff08;一&#xff09;题目网址视频网址 &#xff08;二&#xff09;手写草稿思考 Part1: 慕课PPT Part2: 笨蛋的学习 &#xff08;一&#xff09;题目网址视频网址 北京大学网站在线算法题&#xff1a;1042 -- Gone Fishing (poj.org) 视频讲解&#xff08;北…

MYSQL基本操作

数据库的列类型 int&#xff1a;整型 用于定义整数类型的数据 float&#xff1a;单精度浮点4字节32位 准确表示到小数点后六位 double&#xff1a;双精度浮点8字节64位 char&#xff1a;固定长度的字符类 用于定义字符类型数据&#xff0c;固定10字节&#xff0c;如果你设定5字…

(转载)从0开始学matlab(第1天)—变量和数组

MATLAB 程序的基本数据单元是数组。一个数组是以行和列组织起来的数据集合&#xff0c;并且拥有一个数组名。数组中的单个数据是可以被访问的&#xff0c;访问的方法是数组名后带一个括号&#xff0c;括号内是这个数据所对应行标和列标。标量在 MATLAB 中也被当作数组来处理——…

实在智能与浙江工商大学官宣战略合作,共建人工智能联合实验室和实习基地

5月10日&#xff0c;实在智能与浙江工商大学正式官宣战略合作&#xff0c;并进行“人工智能联合实验室” “大学生实习实践基地”揭牌仪式。躬身入局共筑人工智能人才生态&#xff0c;这是实在智能和浙江工商大学的共同愿景&#xff0c;也是校企双方深度产学研融合、加速科技型…

【蓝桥杯国赛真题26】Scratch队列练习 少儿编程scratch图形化编程 蓝桥杯省赛真题讲解

目录 scratch队列练习 一、题目要求 编程实现 二、案例分析 1、角色分析

【Linux】进程信号(中)

在上一个文章中&#xff0c;关于信号的产生&#xff0c;还有没补充完的&#xff0c;所以在这篇文章补充一下 文章目录 1.信号的产生硬件异常产生信号a/0问题验证为8号信号 野指针问题验证为11号信号 核心转储设置核心转储大小Core与Term的区别核心转储的作用 2.信号保存1. 概念…