前后端图片交互的简易方式
测试结果
一、交互方式说明
在项目的实际开发中,难免会遇到前端需要渲染数据库中保存的图片,那咱知道图片也属于一种文件,不好保存到数据库,那怎么处理比较好呢?
这边小编采用的方式是将图片链接保存到数据库中,而实际图片保存在具体目录中。前端当使用
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)functionsucessUpload(){ElNotification({message:'图片上传成功',type:'success',duration:1500})
console.log('success')
flag.value=true
imageAction.value =`http://localhost:8080/images?path=/test/${fileName}`}functionerrorUpload(){ElNotification({message:"图片上传失败",type:'error',duration:1500})
console.log('error')}let fileName =''functionbeforeUpload(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
这个标签是用来上传文件的,图片是属于文件范畴的,所以是可以不局限于图片的,可灵活使用。
后端具体代码
后端代码内容大概分为以下俩步
- 设置允许跨域,设置允许某源进行访问;
- 具体的保存图片和获取图片的表示层实现。
- 允许跨域代码(前端的端口号小编设置的是8081)
@ConfigurationpublicclassWebMvcOriginConfigextendsWebMvcConfigurerAdapter{@OverridepublicvoidaddCorsMappings(CorsRegistry registry){
registry.addMapping("/**").allowedOrigins("http://localhost:8081/").allowedMethods("GET","POST","PUT","DELETE").allowCredentials(true);}}
- 配置请求资源映射(这步看你图片资源的位置,如果你的图片资源放在项目的根目录和src平级就不用配,如果你是放在项目之外或者说
resources
资源路径下,你需要配置这个资源映射)。
@ConfigurationpublicclassWebMvcImageConfigimplementsWebMvcConfigurer{@OverridepublicvoidaddResourceHandlers(ResourceHandlerRegistry registry){
registry.addResourceHandler("/images/**").addResourceLocations("file:images/");}}
- 具体存储图片和获取图片代码实现
@RestController@RequestMapping("/images")publicclassImageController{@GetMappingpublicvoidgetImage(@RequestParam("path")String path,HttpServletResponse response)throwsIOException{
response.setContentType("image/png,image/jpeg");// 设置MIME类型,也就是响应类型ServletOutputStream out = response.getOutputStream();File file =newFile("images"+ path);InputStream in =newFileInputStream(file);int available = in.available();byte[] bytes =newbyte[available];
in.read(bytes);
out.write(bytes);
in.close();
out.close();}@PostMapping("/{dirName}/{fileName}")publicvoidsetImage(MultipartFile file,@PathVariableString dirName,@PathVariableString fileName)throwsIOException{File file1 =newFile("images/"+ dirName +"/"+ fileName);OutputStream out =newFileOutputStream(file1);// 获取图片的输入流InputStream in = file.getInputStream();byte[] bytes =newbyte[1024*100];//100kbint cnt =0;// 开始存图片while((cnt=in.read(bytes))!=-1){
out.write(bytes,0,cnt);}
in.close();
out.close();}}
注意点
- 请求资源映射是根据图片的存放位置判断是否需要的(也就是上面的第二步),如果不配置这个的话,如果是存储在resources目录下,存储后是需要重启服务器才能访问到资源的。这是由于存储后的资源没有重新加载到服务器可访问到的地方。如果直接更改请求映射的资源路径,让一些请求的资源路径直接变化到磁盘上(绝对路径)。这样磁盘上的资源变化了,那路径可访问的资源也就变化了
- 需要使用SpringBoot提供的
MultipartFile
的接口,它可以用来处理文件上传,可以得到文件上传过程中的数据,可以得到其文件的输入流。(这里需要注意的是:MultipartFile不是Springboot的默认数据类型(不是像HttpServletRequest这样的),它是通过@RequestParam(“file”)注解引入的。小编上面的参数名是file,boot会给咱自动调@RequestParam(“file”)传参)。 - 在使用
response
对象返回图片给前端时,需要设置响应类型(MIME类型)。
实现效果
首先说明一下这里本是没有图片文件的。
测试效果
版权归原作者 假正经的小柴 所有, 如有侵权,请联系我们删除。