大纲

  • 一、前言
  • 二、思路
  • 三、关键性的代码
    • yml文件
    • 读取yaml值的类
    • 配置类获取绑定配置参数
    • controller类
    • 基本的文件存储的业务类
    • 存储服务接口类
    • 本地存储实现类
  • 四、测试

一、前言

最近在看一个开源项目,发现集成了本地存储以及云存储。大致看了一下思路,感觉也对面向对象的思想有了更进一步的理解。特来记录一下。

下文的描述不是很严谨,带有自己的理解存在。

如果有错误或者表述不恰当,欢迎指正。

二、思路

三、关键性的代码

以实现图片本地存储为例子

yml文件

storage:# 当前工作的对象存储模式,分别是local、aliyun、tencent、qiniuactive: local# 本地对象存储配置信息local:# 存储路径storagePath: storage# 访问地址address: http://localhost:1203/storage/fetch/

读取yaml值的类

@ConfigurationProperties其实就类似于使用多个@Value同时绑定,绑定的对象就是隐式绑定yaml里面的storage里面的值,意味着在配置文件编写的时候需要与对应yaml的字段名称相同

@ConfigurationProperties(prefix = "storage")
@Data
public class StorageProperties {private String active;private Local local;public static class Local {private String address;private String storagePath;// 省略get与set方法}
}

配置类获取绑定配置参数

@Configuration
@EnableConfigurationProperties(StorageProperties.class)
public class StorageAutoConfiguration {private final StorageProperties properties;public StorageAutoConfiguration(StorageProperties properties) {this.properties = properties;}/*** 获取配置参数里面的active值,通过active的不同,基础的存储服务类的中的存储模式也不同** @author hanyulin* @date 2021/12/4 10:57* @return BaseStorageService*/@Beanpublic BaseStorageService baseStorageService() {BaseStorageService baseStorageService = new BaseStorageService();String active = this.properties.getActive();baseStorageService.setActive(active);if ("local".equals(active)) {baseStorageService.setStorageType(localStorage());}else {throw new RuntimeException("当前存储模式 " + active + " 不支持");}return baseStorageService;}/*** 存储模式为local,注入LocalStorageImpl需要的属性** @author hanyulin* @date 2021/12/4 11:11* @return com.hanliy.storage.impl.LocalStorageImpl*/@Beanpublic LocalStorageImpl localStorage() {LocalStorageImpl localStorage = new LocalStorageImpl();StorageProperties.Local local = this.properties.getLocal();localStorage.setAddress(local.getAddress());localStorage.setStoragePath(local.getStoragePath());return localStorage;}
}

controller类

controller不做业务逻辑的处理

    @PostMapping("/upload")public Result<PicStorageEntity> create(@RequestParam("file") MultipartFile file) throws IOException {String originalFilename = file.getOriginalFilename();PicStorageEntity picStorage = baseStorageService.store(file.getInputStream(), file.getSize(),file.getContentType(), originalFilename);return new Result<PicStorageEntity>().ok(picStorage);}

基本的文件存储的业务类

负责对图片存储以及图片信息存储的转发

/*** @author hanyulin* @apiNote 基本的图片存储服务类,负责对图片存储以及图片信息存储的转发* @date 2021/12/3 16:27*/
@Data
public class BaseStorageService {private String active;private StorageType storageType;@Resourceprivate StorageService storageService;/***  图片存储** @param inputStream 图片流* @param contentLength 图片大小* @param contentType 图片的类型* @param fileName 图片原名称* @author hanyulin* @date 2021/12/4 11:24* @return PicStorageEntity*/public PicStorageEntity store(InputStream inputStream, long contentLength, String contentType, String fileName) {/** 产生图片唯一标识符号*/String key = generateKey(fileName);/** 调用接口StorageType的store实现文件存储*/storageType.store(inputStream, contentLength, contentType, key);/** 图片信息的存储*/PicStorageEntity picStorage = new PicStorageEntity();picStorage.setName(fileName);picStorage.setSize((int) contentLength);picStorage.setType(contentType);picStorage.setPicKey(key);picStorage.setUrl(storageType.generateUrl(key));storageService.insert(picStorage);return picStorage;}}

存储服务接口类

提供不同的存储服务类,所有存储服务均由该类对外提供

/*** @author hanyulin* @apiNote 提供不同的存储服务类,所有存储服务均由该类对外提供* @date 2021/12/3 9:49*/
public interface StorageType {/*** 存储一个文件对象** @param inputStream   文件输入流* @param contentLength 文件长度* @param contentType   文件类型* @param keyName       文件名*/void store(InputStream inputStream, long contentLength, String contentType, String keyName);/*** 通过唯一标识,产生访问路径* * @param keyName 唯一标识名称* @return 访问路径*/String generateUrl(String keyName);
}

本地存储实现类

@Data
public class LocalStorageImpl implements StorageType {private String storagePath;private String address;private Path rootLocation;/** 创建图片的存储目录*/public void setStoragePath(String storagePath) {this.storagePath = storagePath;this.rootLocation = Paths.get(storagePath);try {Files.createDirectories(rootLocation);} catch (IOException e) {e.getMessage();}}@Overridepublic void store(InputStream inputStream, long contentLength, String contentType, String keyName) {try {Files.copy(inputStream, rootLocation.resolve(keyName), StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {throw new RuntimeException("Failed to store file " + keyName, e);}}@Overridepublic String generateUrl(String keyName) {return address + keyName;}

四、测试

Q:在某个公众号看到一道面试题:一道面试题,GET 请求能传图片吗?

图片一般有两种传输方式:base64 和 file对象.

base64 :在客户端,由于浏览器地址栏的限制,只能够上传小图片(Blob、TypedArray、图片压缩方案)。在服务端,可以传任意大小的图片。

file:可以传输的,数据在body里面(GET 请求有 body 体。GET 和 POST 并没有本质上的区别,他们只是 HTTP 协议中两种请求方式,仅仅是报文格式不同(或者说规范不同)。)。

GET 请求能不能带 body 这个事是由 HTTP 协议来定义的。是一种规范。

SpringBootStudyDemos:pic-demo

集成本地图片、云图片存储的思路相关推荐

  1. 【python 人像抠图】利用阿里云api进行对本地图片进行批量人像抠图

    阿里云智能视觉开发平台分割抠图 利用阿里云的人像抠图算法,对本地图片进行批量人像抠图,然后批量下载到本地. # -*- coding: utf-8 -*- import sys import requ ...

  2. 对于阿里云的oss上传本地图片的相关注意点

    #先在阿里云购买储存空间 我的结果如下: 然后下载相关的SDK,下面是C++相关SDK包: https://help.aliyun.com/document_detail/106216.html?sp ...

  3. TinyMCE 新增本地图片上传功能

    TinyMCE 新增本地图片上传功能 在TinyMCE 在处理富文本时,可以通过网站的相对路径录入图片地址.这样TinyMCE 就可以正常显示图片了.其实该功能属于普通HTML富文本控件基本功能了.现 ...

  4. Webview加载本地图片的方案对比

    前言 先讲讲为什么会有这篇blog,话说前几天做个模块,要求是这样的: 做一个webview的页面,功能类似于微信发朋友圈一样,要求能上传本地图片到webview中进行展示,并按用户喜好添加和删除,当 ...

  5. 解决导入markdown时本地图片无法显示问题——图床

    解决导入markdown时本地图片无法显示问题--图床 图床工具: PicGo 图片服务器:Gitee 辅助工具:Node.js 14.17.6 图床: 一般是指储存图片的服务器,有国内和国外之分.国 ...

  6. Unity获取本地图片并保存后使用

    本文思路为,打开本地文件夹,获取到图片,然后存到相对路径下,再次调用. 首先,打开本地目录,获取路径: /// <summary>/// 获得路径/// </summary>p ...

  7. Tapd GitHub集成 详细图片

    此为系列博客 阿里云服务器 CentOS7 Tomcat + Jenkins+国内镜像 TAPD关联Jenkins Tapd GitHub集成 详细图片(当前位置) TAPD pytest自动化测试部 ...

  8. Typora+PicGo图床配置(本地图片-->网络url~博客必备)

    前段时间搭了一个hexo博客,但是发现了一个很大的问题,在Typora里编辑你的博文的时候,插入的图片都是一些本地图片,然后部署的时候根本不能加载这些图片~~ 其中一个解决方法就是通过一些平台,像知乎 ...

  9. 浅谈js本地图片预览

    最近在工作中遇到一个问题,就是实现一个反馈页面,这个反馈页面的元素有反馈主题.反馈类型.反馈内容.反馈人联系电话以及反馈图片.前端将这些反馈的元素POST给后台提供的接口:实现这个工作的步骤就是:页面 ...

最新文章

  1. 今天mtk笔试,没信心了
  2. 我怎么在AD里面找到已经改名的Administrator账户?
  3. python官方下载步骤-Python 下载及安装详细步骤
  4. 使用MMC管理windows机器
  5. nlp构建_使用NLP构建自杀性推文分类器
  6. mysql中when用法_Mysql 中的CASE WHEN 用法
  7. c++模板显示实例化,显示具体化,隐式实例化
  8. HEVC算法和体系结构:预测编码之帧内预测
  9. raspberry pi_如何将Raspberry Pi配置为微控制器
  10. 转载:使用Wireshark解密TLS 1.3流量
  11. 异步promise、Async/await介绍
  12. 办公必备的WPS Office 2021 for mac(wps 2021中文版)
  13. MATLAB 中跳出if条件判断
  14. macOS Monterey 12.6.1 (21G217) 正式版 ISO、IPSW、PKG 下载
  15. 大数据加工的方法,主要分为哪几种?
  16. 深度学习之目标检测--Pytorch实战
  17. oracle11 如何启动企业管理器
  18. 有无孔孟之道,太阳照常升起
  19. [JavaME]手机玩点对点MSN传情动漫之补充说明
  20. 高一下学期计算机考试知识点,高一第一学期计算机期末考试-基础模块(含答案)...

热门文章

  1. nginx fastcgi_buffers设置
  2. 整活~使用webAI做一个网页AR吃豆人小游戏
  3. 荀子《劝学》原文及翻译
  4. linux挂载u盘显示目录忙,linux下挂载u盘及iso8859-1 not found错误解决
  5. Python攻城师的成长————网络编程(socket套接字、通信循环、链接循环、黏包问题)
  6. 优秀开源音乐项目---落雪音乐软件(免费听歌下载歌曲)
  7. 网络服务器是指带有大容量硬盘的计算机,中国人民大学网络教育201812统考计算机模拟题...
  8. 删除前几页的页眉同时删掉页眉上的横线
  9. 蚂蚁花呗账单分期和交易分期的费用如何计算?
  10. WEB前端性能优化,提高页面加载速度