Vue+SpringBoot+OSS+element实现图片上传服务器+图片展示墙
迪丽瓦拉
2024-06-02 05:02:09
0

1、技术选型:

(1)Vue(前端)
(2)Element(上传图片组件)
(3)SpringBoot(后端)
(4)Mybatis(数据库操作)
(3)OSS(阿里云存储服务器)

2、实现效果概述:

(1)图片展示墙(做了一个简单的,没有太花里胡哨)
在这里插入图片描述

(2)上传页面

在这里插入图片描述

3、项目概述:

注意这是一个练习项目,练习项目,练习项目,可能存在一些小问题!

简单来说,

=(1)图片上传逻辑:=

前端通过elementUI的上传图片的组件将图片进行上传,后端利用SpringBoot写的后端逻辑接受了前端穿过的图片,首先将图片上传到阿里云的OSS对象存储系统上,然后返回图片的地址存储到数据库。

=(2)图片展示墙逻辑:=

通过查询数据库的图片地址返回给前端,然后前端通过for循环,利用img标签对图片进行循环遍历然后显示!

项目简单,易于实现,全代码黏贴!!!!!!

4、图片上传

(1)前端项目结构:

在这里插入图片描述
(2)ImagesUpload.vue

=补充:这里主要是借助了elementUI的上传图片组件!!!!
这里只需要将action中的地址改成自己的后端请求地址就可以!!!
=



==前端逻辑完成,开始后端逻辑=

(3)安装阿里云OSS所需依赖:

	com.aliyun.ossaliyun-sdk-oss2.8.3

(4)OSS工具类封装:

=这里根据自己的实际情况合理选择域名,访问用户,秘钥…=

package com.blog.util;/*** @author * @version 1.0* @description TODO* @date 2023/3/12 8:28*/import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URL;
import java.util.Date;
import java.util.Random;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;public class OSSClientUtil {/*** log日志*/public static final Logger logger = LoggerFactory.getLogger(OSSClientUtil.class);/*** 访问域名*/private String endpoint = "oss-cn-beijing.aliyuncs.com";/*** accessKey访问秘钥*  访问用户*/private String accessKeyId = "########";/*** 密钥*/private String accessKeySecret = "################";/*** 空间  名称*/private String bucketName = "############";/***  文件存储目录*/private String filedir = "###########/";private OSSClient ossClient;public OSSClientUtil() {ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);}/*** 初始化*/public void init() {ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);}/*** 销毁*/public void destory() {ossClient.shutdown();}/*** 上传图片** @param url* @throws*/public void uploadImg2Oss(String url) throws IOException {File fileOnServer = new File(url);FileInputStream fin;try {fin = new FileInputStream(fileOnServer);String[] split = url.split("/");this.uploadFile2OSS(fin, split[split.length - 1]);} catch (FileNotFoundException e) {throw new IOException("图片上传失败");}}public String uploadImg2Oss(MultipartFile file) throws IOException {if (file.getSize() > 10 * 1024 * 1024) {throw new IOException("上传图片大小不能超过10M!");}String originalFilename = file.getOriginalFilename();String substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();Random random = new Random();String name = random.nextInt(10000) + System.currentTimeMillis() + substring;try {InputStream inputStream = file.getInputStream();this.uploadFile2OSS(inputStream, name);return name;} catch (Exception e) {throw new IOException("图片上传失败");}}/*** 获得图片路径** @param fileUrl* @return*/public String getImgUrl(String fileUrl) {System.out.println(fileUrl);if (!StringUtils.isEmpty(fileUrl)) {String[] split = fileUrl.split("/");return this.getUrl(this.filedir + split[split.length - 1]);}return "" ;}/*** 上传到OSS服务器 如果同名文件会覆盖服务器上的** @param instream*            文件流* @param fileName*            文件名称 包括后缀名* @return 出错返回"" ,唯一MD5数字签名*/public String uploadFile2OSS(InputStream instream, String fileName) {String ret = "";try {// 创建上传Object的MetadataObjectMetadata objectMetadata = new ObjectMetadata();objectMetadata.setContentLength(instream.available());objectMetadata.setCacheControl("no-cache");objectMetadata.setHeader("Pragma", "no-cache");objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));objectMetadata.setContentDisposition("inline;filename=" + fileName);// 上传文件PutObjectResult putResult = ossClient.putObject(bucketName, filedir + fileName, instream, objectMetadata);ret = putResult.getETag();} catch (IOException e) {logger.error(e.getMessage(), e);} finally {try {if (instream !=null ) {instream.close();}} catch (IOException e) {e.printStackTrace();}}return ret;}/*** Description: 判断OSS服务文件上传时文件的contentType** @param** @return String*/public static String getcontentType(String filenameExtension) {if (filenameExtension.equalsIgnoreCase("bmp")) {return "image/bmp";}if (filenameExtension.equalsIgnoreCase("gif")) {return "image/gif";}if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")|| filenameExtension.equalsIgnoreCase("png")) {return "image/jpeg";}if (filenameExtension.equalsIgnoreCase("html")) {return "text/html";}if (filenameExtension.equalsIgnoreCase("txt")) {return "text/plain";}if (filenameExtension.equalsIgnoreCase("vsd")) {return "application/vnd.visio";}if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) {return "application/vnd.ms-powerpoint";}if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {return "application/msword";}if (filenameExtension.equalsIgnoreCase("xml")) {return "text/xml";}return "image/jpeg";}/*** 获得url链接** @param key* @return*/public String getUrl(String key) {// 设置URL过期时间为10年 3600l* 1000*24*365*10Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);// 生成URL// URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);String url = "https://"+bucketName+"."+endpoint+"/"+key;if (url != null) {return url.toString();}return  "";}
}

(5)Controller层:

package com.blog.controller.Vue;import com.blog.pojo.Images;
import com.blog.service.ImagesService;
import com.blog.util.FileUtil;
import com.blog.util.OSSClientUtil;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;/*** @author * @version 1.0* @description TODO* @date 2023/3/11 10:39*/@RestController
@RequestMapping("/images")
public class UploadController {@AutowiredImagesService imagesService;@PostMapping("/upload")public Map fileupload(MultipartFile file, HttpServletRequest req) throws IOException {if (file == null || file.getSize() <= 0) {throw new IOException("file不能为空");}//获取文件的大小,单位/KBlong size = file.getSize();OSSClientUtil ossClient=new OSSClientUtil();//将文件上传String name = ossClient.uploadImg2Oss(file);//获取文件的URl地址  以便前台  显示String imgUrl = ossClient.getImgUrl(name);HashMap map=new HashMap<>();//文件存储的路径map.put("name", imgUrl);Images images = new Images();images.setImg(imgUrl);System.out.println("添加数据");imagesService.insert(images);return map ;}}

(6)Service层:

package com.blog.service;import com.blog.pojo.Images;import java.util.List;public interface ImagesService {int insert(Images images);List getImages();
}

(7)ServiceImpl:

package com.blog.service.impl;import com.blog.dao.ImagesDao;
import com.blog.pojo.Images;
import com.blog.service.ImagesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** @author * @version 1.0* @description TODO* @date 2023/3/12 10:38*/
@Service
public class ImagesServiceImpl implements ImagesService {@AutowiredImagesDao imagesDao;@Overridepublic int insert(Images images) {return imagesDao.insert(images);}@Overridepublic List getImages() {return imagesDao.getImages();}
}

(8)Dao层:

package com.blog.dao;import com.blog.pojo.Images;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;import java.util.List;@Mapper
@Repository
public interface ImagesDao {int insert(Images images);List getImages();
}

(9)xml层:



insert into t_images (img)values (#{img});

(10)实体类:

package com.blog.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;/*** @author * @version 1.0* @description TODO* @date 2023/3/12 10:33*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Images {private Integer id;private String img;
}

5、照片墙功能:

(1)前端项目结构:

在这里插入图片描述

(2)Waterfall组件(主要是通过一个瀑布流图片展示组件来实现)




(3)ImagesShow.vue(照片墙显示页面,借助于上一个瀑布流图片展示组件)

=①在这里需要注意路径问题,这里./代表了本项目所在的目录,在引入组件地址的时候,要根据自己项目的实际路径合理改变!=



(4)images.js

import request from '@/request/request'
export function list() {return request({url: '/imagesList/list',method: 'get',})
}

=配置到这里,那么前端核心的逻辑已经写完了=


(5)ImagesController

package com.blog.controller.Vue;import com.blog.pojo.Images;
import com.blog.service.ImagesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;/*** @author * @version 1.0* @description TODO* @date 2023/3/12 11:00*/
@RestController
@RequestMapping("/imagesList")
public class ImagesController {@AutowiredImagesService imagesService;@GetMapping("/list")public List getImagesList(){List images = imagesService.getImages();return images;}}

(6)关于service层、Dao层、实体类都在图片上传的ImagesService里,在这里我就不重复添加了!!!

6、总结:

(1)利用了vue、element组件搭建了前端
(2)利用SpringBoot、Mybatis实现了后端
(3)借助OSS组件将图片上传到了阿里云OSS

7、补充:

如果你对阿里云的OSS不太熟悉,那么给你推荐几篇博客,加速理解。

=(1)阿里云OSS注册及功能详解:=

https://blog.csdn.net/weixin_52851967/article/details/126924361

=(2)SpringBoot整合阿里云OSS云存储=

https://blog.csdn.net/qq_43021813/article/details/82665394

=(3)可能碰到的问题,以我为例,我创建的是私有Bucket,所以只有带着秘钥的时候才能访问,只根据图片路径而不带秘钥是无法访问的,这篇博客包含了我遇到的一些问题!=

https://blog.csdn.net/H_Q_Li/article/details/126471699

在这里插入图片描述

相关内容