热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

SpringBoot项目中实现文件上传功能的示例

这篇文章主要介绍了SpringBoot项目中实现文件上传功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

在实际项目中,文件上传是很多项目必不可少的一个功能。那么在 Spring Boot 项目中又是如何来实现文件上传功能的呢?一般来说,上传的文件可以保存到项目根目录下的某一文件夹中,但这样做显然是不太合适的。因此我们选择将文件上传到专门的文件服务器中。很多云计算厂商都提供文件存储服务。这里我选择的是阿里云的对象存储(OSS)。

一、配置OSS

1. 导入SDK

首先,你需要注册阿里云的账号并开通对象存储服务。在准备工作完成之后,需要导入 JAVA 版本的 SDK,这里使用 maven 进行导入



	com.aliyun.oss
	aliyun-sdk-oss
	3.8.0

2. 修改配置文件

导入完成后在 application.properties 配置文件中添加以下内容

# 节点域名
aliyun.oss.endpoint=oss-cn-xxxxxxx.aliyuncs.com
# 账户id
aliyun.oss.accessKeyId=xxxxxxxxxxxxx
# 账户密码
aliyun.oss.accessKeySecret=xxxxxxxxxxxxx
# bucket名称
aliyun.oss.bucketName=xxxxxxxxxxx
# 签名过期时间
aliyun.oss.policy.expire=300
# 上传文件的最大尺寸
aliyun.oss.maxSize=10
# 上传地址的前缀
aliyun.oss.dir.prefix=xxx
# 回调参数的请求地址
aliyun.oss.callback=http://www.xxxxxx.com/api/aliyun/oss/callback

以上内容在开通服务后均可获取到,请根据实际情况进行修改

3. 初始化

OSSClient是OSS的Java客户端,用于管理存储空间和文件等OSS资源。使用Java SDK发起OSS请求,您需要初始化一个OSSClient实例,并根据需要修改ClientConfiguration的默认配置项。

根据官方文档的描述,需要初始化一个ossClient实例并将其注入到Spring容器中,因此可以编写一个配置类OssConfig

@Configuration
@PropertySource(value = {"classpath:application.properties"}, encoding = "utf-8")
public class OssConfig {

 @Value("${aliyun.oss.endpoint}")
 private String endpoint;

 @Value("${aliyun.oss.accessKeyId}")
 private String accessKeyId;

 @Value("${aliyun.oss.accessKeySecret}")
 private String secretAccessKey;

 @Bean
 public OSS ossClient(){
 return new OSSClientBuilder().build(endpoint, accessKeyId, secretAccessKey);
 }
}

更多详细的配置,请参考官方文档:初始化

二、文件上传

1. 流程分析

我们以典型的表单上传为例,在使用对象存储OSS后,表单上传分为以下几个流程:

注:Policy表单域用于验证请求的合法性。例如可以指定上传的大小,可以指定上传的Object名称等,上传成功后客户端跳转到的URL,上传成功后客户端收到的状态码。

PolicyConditions policyCOnds= new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, DIR_PREFIX);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
// 将Policy字符串进行base64编码
String policy = BinaryUtil.toBase64String(binaryData);
// 用OSS的AccessKeySecret对base64编码后的Policy进行签名
String signature = ossClient.calculatePostSignature(postPolicy);

前端向OSS服务器上传文件时要上传Policy表单域,OSS服务器将对Policy表单域的内容进行验证。关于 Post Policy 的详细内容,请参考官方文档:Post Policy

当文件上传成功后,OSS服务器会向应用服务器发起回调请求,具体流程如下:

用户只需要在发送给 OSS 的请求中携带相应的 Callback 参数,即能实现回调。

Callback 参数是由一段经过 base64 编码的 JSON 字符串(字段)。构建 callback 参数的关键是指定请求回调的服务器 URL(callbackUrl)以及回调的内容(callbackBody)。

// 上传回调参数
Callback callback = new Callback();
// 指定请求回调的服务器URL
callback.setCallbackUrl(CALLBACK);
//(可选)设置回调请求消息头中Host的值,即您的服务器配置Host的值。
// callback.setCallbackHost("yourCallbackHost");
// 设置发起回调时请求body的值。
callback.setCallbackBody("{\\\"filename\\\":${object},\\\"mineType\\\":${mimeType}}");
// 设置发起回调请求的Content-Type。
callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
// 设置发起回调请求的自定义参数,由Key和Value组成,Key必须以x:开始。
// callback.addCallbackVar("x:dir", "value");

更详细的内容请阅读官方文档:Callback

2. 功能实现

首先编写 Post Policy 封装对象OssPolicyResult

@Data
public class OssPolicyResult {

	@ApiModelProperty("用户id")
	private String accessKeyId;
	
	@ApiModelProperty("Post Policy经过base64编码过的字符串")
 private String policy;
	
	@ApiModelProperty("对policy签名后的字符串")
 private String signature;

	// @ApiModelProperty("对象的键值")
	// private String key;
	
	@ApiModelProperty("上传文件夹路径前缀")
 private String dir;
	
	@ApiModelProperty("oss对外服务的访问域名")
 private String host;

	@ApiModelProperty("上传成功后的回调设置")
	private String callback;
}

然后需自定义一个回调结果对象OssCallBackResult

@Data
public class OssCallBackResult {

 @ApiModelProperty("文件的链接")
 private String url;
 @ApiModelProperty("文件名称")
 private String filename;
 @ApiModelProperty("文件大小")
 private String size;
 @ApiModelProperty("文件的mimeType")
 private String mimeType;
 @ApiModelProperty("图片文件的宽")
 private String width;
 @ApiModelProperty("图片文件的高")
 private String height;
}

注:以上内容可根据实际需要进行修改

之后编写 Service 接口及实现类

Service 接口:

public interface OssService {
	
 // 生成Post Policy
	OssPolicyResult policy();
	
 // 上传成功后的回调
	OssCallBackResult callback(Map requestBody);
}

Service 实现类:

@Slf4j
@Service
@PropertySource(value = {"classpath:application.properties"}, encoding = "utf-8")
public class OssServiceImpl implements OssService {

	@Value("${aliyun.oss.endpoint}")
	private String ENDPOINT;

	@Value("${aliyun.oss.accessKeyId}")
	private String ACCESS_KEY_ID;

	@Value("${aliyun.oss.accessKeySecret}")
	private String SECRET_ACCESS_KEY;

	@Value("${aliyun.oss.bucketName}")
	private String BUCKET_NAME;

	@Value("${aliyun.oss.policy.expire}")
	private int EXPIRE;

	@Value("${aliyun.oss.maxSize}")
	private int MAX_SIZE;

	@Value("${aliyun.oss.dir.prefix}")
	private String DIR_PREFIX;

	@Value("${aliyun.oss.callback}")
	private String CALLBACK;

	@Autowired
	private OSS ossClient;

	@Override
	public OssPolicyResult policy() {
		OssPolicyResult result = new OssPolicyResult();
		// 签名有效期
		long expireEndTime = System.currentTimeMillis() + EXPIRE * 1000;
		Date expiration = new Date(expireEndTime);
		// 文件名称
		// String filename = UUID.randomUUID().toString();
		// 文件大小
		long maxSize = MAX_SIZE * 1024 * 1024;
		// 提交节点
		String action = "http://" + BUCKET_NAME + "." + ENDPOINT;
		// 上传回调参数
		Callback callback = new Callback();
		// 指定请求回调的服务器URL
		callback.setCallbackUrl(CALLBACK);
		//(可选)设置回调请求消息头中Host的值,即您的服务器配置Host的值。
		// callback.setCallbackHost("yourCallbackHost");
		// 设置发起回调时请求body的值。
		callback.setCallbackBody("{\\\"filename\\\":${object}}");
		// 设置发起回调请求的Content-Type。
		callback.setCalbackBodyType(Callback.CalbackBodyType.JSON);
		// 设置发起回调请求的自定义参数,由Key和Value组成,Key必须以x:开始。
		// callback.addCallbackVar("x:dir", "value");
		try {
			PolicyConditions policyCOnds= new PolicyConditions();
			policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, maxSize);
			policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, DIR_PREFIX);
			String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
			byte[] binaryData = postPolicy.getBytes(StandardCharsets.UTF_8);
 // 将Policy字符串进行base64编码
			String policy = BinaryUtil.toBase64String(binaryData);
 // 用OSS的AccessKeySecret对base64编码后的Policy进行签名
			String signature = ossClient.calculatePostSignature(postPolicy);
 // 将callback配置进行base64编码
			String callbackData = BinaryUtil.toBase64String(OSSUtils.jsonizeCallback(callback).getBytes());
			// 返回结果
			result.setAccessKeyId(ACCESS_KEY_ID);
			result.setPolicy(policy);
			result.setSignature(signature);
			// result.setKey(filename);
			result.setDir(dir);
			result.setHost(action);
			result.setCallback(callbackData);
		} catch (Exception e) {
			log.error("签名生成失败", e);
		}
		return result;
	}

	@Override
	public OssCallBackResult callback(Map requestBody) {
		OssCallBackResult ossCallbackResult = new OssCallBackResult();
		// 文件名
		String filename = requestBody.get("filename").toString();
		// 文件链接
		String url = "https://" + BUCKET_NAME + "." + ENDPOINT + "/" + DIR_PREFIX + "/" + filename;
		ossCallbackResult.setUrl(url);
		return ossCallbackResult;
	}
}

添加 Controller 层:

@Api(tags = "阿里云对象存储接口")
@RequestMapping("/api")
@RestController
public class OssController {
	
	@Autowired
	private OssService ossService;
	
	@ApiOperation(value = "OSS上传签名生成")
	@GetMapping("/aliyun/oss/policy")
	public Object policy() {
		return ossService.policy();
	}

	@ApiOperation(value = "OSS上传成功回调")
	@PostMapping("/aliyun/oss/callback")
	public Object callback(@RequestBody Map requestBody) {
		return ossService.callback(requestBody);
	}
}

到此这篇关于Spring Boot项目中实现文件上传功能的示例的文章就介绍到这了,更多相关Spring Boot实现文件上传内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 本项目在Java Maven框架下,利用POI库实现了Excel数据的高效导入与导出功能。通过优化数据处理流程,提升了数据操作的性能和稳定性。项目已发布至GitHub,当前最新版本为0.0.5。该项目不仅适用于小型应用,也可扩展用于大型企业级系统,提供了灵活的数据管理解决方案。GitHub地址:https://github.com/83945105/holygrail,Maven坐标:`com.github.83945105:holygrail:0.0.5`。 ... [详细]
  • 本文介绍了使用 Python 编程语言高效抓取微博文本和动态网页图像数据的方法。通过详细的示例代码,展示了如何利用爬虫技术获取微博内容和动态图片,为数据采集和分析提供了实用的技术支持。对于对网络数据抓取感兴趣的读者,本文具有较高的参考价值。 ... [详细]
  • Spring框架入门指南:专为新手打造的详细学习笔记
    Spring框架是Java Web开发中广泛应用的轻量级应用框架,以其卓越的功能和出色的性能赢得了广大开发者的青睐。本文为初学者提供了详尽的学习指南,涵盖基础概念、核心组件及实际应用案例,帮助新手快速掌握Spring框架的核心技术与实践技巧。 ... [详细]
  • Jedis接口分类详解与应用指南
    本文详细解析了Jedis接口的分类及其应用指南,重点介绍了字符串数据类型(String)的接口功能。作为Redis中最基本的数据存储形式,字符串类型支持多种操作,如设置、获取和更新键值对等,适用于广泛的应用场景。 ... [详细]
  • 本文介绍了如何通过掌握 IScroll 技巧来实现流畅的上拉加载和下拉刷新功能。首先,需要按正确的顺序引入相关文件:1. Zepto;2. iScroll.js;3. scroll-probe.js。此外,还提供了完整的代码示例,可在 GitHub 仓库中查看。通过这些步骤,开发者可以轻松实现高效、流畅的滚动效果,提升用户体验。 ... [详细]
  • Ceph API微服务实现RBD块设备的高效创建与安全删除
    本文旨在实现Ceph块存储中RBD块设备的高效创建与安全删除功能。开发环境为CentOS 7,使用 IntelliJ IDEA 进行开发。首先介绍了 librbd 的基本概念及其在 Ceph 中的作用,随后详细描述了项目 Gradle 配置的优化过程,确保了开发环境的稳定性和兼容性。通过这一系列步骤,我们成功实现了 RBD 块设备的快速创建与安全删除,提升了系统的整体性能和可靠性。 ... [详细]
  • Django新手指南:第三步——构建你的首个项目
    在本教程中,我们将引导你完成创建第一个Django应用的步骤。通过实际操作,你将逐步了解Django框架的核心概念和基本功能。从项目结构到视图和模板的实现,我们将详细介绍每个环节,帮助你快速上手并构建出一个功能完整的Web应用。 ... [详细]
  • Django框架进阶教程:掌握Ajax请求的基础知识与应用技巧
    本教程深入探讨了Django框架中Ajax请求的核心概念与实用技巧,帮助开发者掌握异步数据交互的方法,提升Web应用的响应速度和用户体验。通过实例解析,详细介绍了如何在Django项目中高效实现Ajax请求,涵盖从基础配置到复杂场景的应用。 ... [详细]
  • Windows环境下详细教程:如何搭建Git服务
    Windows环境下详细教程:如何搭建Git服务 ... [详细]
  • 在Python 3环境中,当无法连接互联网时,可以通过下载离线模块包来实现模块的安装。具体步骤包括:首先从PyPI网站下载所需的模块包,然后将其传输到目标环境,并使用`pip install`命令进行本地安装。此方法不仅适用于单个模块,还支持依赖项的批量安装,确保开发环境的完整性和一致性。 ... [详细]
  • 在2020年8月19日的深度分析中,我们探讨了HTML标签中同时存在`a`标签的`href`和`onclick`属性时的触发顺序问题。此外,还讨论了如何在一个自适应高度的父级`div`中,使两个子`div`中的一个固定高度为300px,另一个自动填充剩余空间的方法。最后,文章详细介绍了JavaScript异步加载的多种实现方式,包括但不限于`async`、`defer`属性以及动态脚本插入技术,为开发者提供了丰富的技术参考。 ... [详细]
  • 本文将深入探讨FastJSON的基础解析机制与自定义JSON处理技巧。通过详细分析FastJSON的核心功能和高级用法,帮助读者掌握高效、灵活的JSON数据处理方法。文中还将分享一些实用的代码示例和最佳实践,助力开发者在实际项目中更好地应用FastJSON。 ... [详细]
  • Java 并发容器 ConcurrentLinkedQueue 的 peek() 方法解析与应用 ... [详细]
  • 本文介绍了在Windows 10系统下使用VirtualBox虚拟机环境部署CentOS 7.2,并在其上安装Docker的具体步骤。针对宝塔面板在Docker容器中磁盘空间限制为8GB的问题,提供了详细的解决方案和优化建议,确保用户能够高效利用有限的存储资源。 ... [详细]
  • 本文详细介绍了在 Docker 环境中部署 Zookeeper 镜像的最佳实践与步骤。首先,通过 `docker search zookeeper` 命令查找可用的 Zookeeper 镜像。接着,使用 `docker pull zookeeper` 或 `docker pull jplock/zookeeper` 命令下载所需的镜像。文章还涵盖了配置文件的优化、网络设置以及容器运行时的注意事项,为用户提供了一套完整的部署方案。 ... [详细]
author-avatar
lou123456_541
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有