Springboot文件上传

发布时间:2026/7/12 20:20:50
Springboot文件上传 一阿里云OSS1.1 准备介绍阿里云是阿里巴巴集团旗下全球领先的云计算公司也是国内最大的云服务提供商 。云服务指的就是通过互联网对外提供的各种各样的服务比如像语音服务、短信服务、邮件服务、视频直播服务、文字识别服务、对象存储服务等等。当我们在项目开发时需要用到某个或某些服务就不需要自己来开发了可以直接使用阿里云提供好的这些现成服务就可以了。比如在项目开发当中我们要实现一个短信发送的功能如果我们项目组自己实现将会非常繁琐因为你需要和各个运营商进行对接。而此时阿里云完成了和三大运营商对接并对外提供了一个短信服务。我们项目组只需要调用阿里云提供的短信服务就可以很方便的来发送短信了。这样就降低了我们项目的开发难度同时也提高了项目的开发效率。大白话别人帮我们实现好了功能我们只要调用即可云服务提供商给我们提供的软件服务通常是需要收取一部分费用的。阿里云对象存储OSSObject Storage Service是一款海量、安全、低成本、高可靠的云存储服务。使用OSS您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。在我们使用了阿里云OSS对象存储服务之后我们的项目当中如果涉及到文件上传这样的业务在前端进行文件上传并请求到服务端时在服务器本地磁盘当中就不需要再来存储文件了。我们直接将接收到的文件上传到oss由 oss帮我们存储和管理同时阿里云的oss存储服务还保障了我们所存储内容的安全可靠。那我们学习使用这类云服务我们主要学习什么呢其实我们主要学习的是如何在项目当中来使用云服务完成具体的业务功能。而无论使用什么样的云服务阿里云也好腾讯云、华为云也罢在使用第三方的服务时操作的思路都是一样的。SDKSoftware Development Kit 的缩写软件开发工具包包括辅助软件开发的依赖jar包、代码示例等都可以叫做SDK。简单说sdk中包含了我们使用第三方云服务时所需要的依赖以及一些示例代码。我们可以参照sdk所提供的示例代码就可以完成入门程序。第三方服务使用的通用思路我们做一个简单介绍之后接下来我们就来介绍一下我们当前要使用的阿里云oss对象存储服务具体的使用步骤。Bucket存储空间是用户用于存储对象Object就是文件的容器所有的对象都必须隶属于某个存储空间。1.2 账号准备下面我们根据之前介绍的使用步骤完成准备工作1). 注册阿里云账户2). 注册完账号之后就可以登录阿里云1.3 开通OSS云服务1). 通过控制台找到对象存储OSS服务选择要开通的服务如果是第一次访问还需要开通对象存储服务OSS2). 开通OSS服务之后就可以进入到阿里云对象存储的控制台3). 点击左侧的 Bucket列表创建一个Bucket输入Bucket的相关信息.其他的信息配置项使用默认的即可。1.4 配置AccessKey1). 创建AccessKey点击 AccessKey管理进入到管理页面。点击 创建AccessKey。2). 配置AccessKey以管理员身份打开CMD命令行执行如下命令配置系统的环境变量。set OSS_ACCESS_KEY_IDxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx set OSS_ACCESS_KEY_SECRETxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx注意将上述的ACCESS_KEY_ID 与 ACCESS_KEY_SECRET 的值一定一定一定一定一定一定要替换成自己的 。执行如下命令让更改生效。setx OSS_ACCESS_KEY_ID %OSS_ACCESS_KEY_ID% setx OSS_ACCESS_KEY_SECRET %OSS_ACCESS_KEY_SECRET%执行如下命令验证环境变量是否生效。echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%二入门阿里云oss 对象存储服务的准备工作我们已经完成了接下来我们就来完成第二步操作参照官方所提供的sdk示例来编写入门程序。首先我们需要来打开阿里云OSS的官方文档在官方文档中找到 SDK 的示例代码如果是在实际开发当中我们是需要从前往后仔细的去阅读这一份文档的但是由于现在是教学我们就只挑重点的去看。有兴趣的同学大家下来也可以自己去看一下这份官方文档。参照文档引入依赖!--阿里云OSS依赖-- dependency groupIdcom.aliyun.oss/groupId artifactIdaliyun-sdk-oss/artifactId version3.17.4/version /dependency dependency groupIdjavax.xml.bind/groupId artifactIdjaxb-api/artifactId version2.3.1/version /dependency dependency groupIdjavax.activation/groupId artifactIdactivation/artifactId version1.1.1/version /dependency !-- no more than 2.3.3-- dependency groupIdorg.glassfish.jaxb/groupId artifactIdjaxb-runtime/artifactId version2.3.3/version /dependency参照文档编写入门程序将官方提供的入门程序复制过来将里面的参数值改造成我们自己的即可。代码如下package com.itheima; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import java.io.ByteArrayInputStream; import java.io.File; import java.nio.file.Files; public class Demo { public static void main(String[] args) throws Exception { // Endpoint以华东1杭州为例其它Region请按实际情况填写。 String endpoint https://oss-cn-beijing.aliyuncs.com; // 从环境变量中获取访问凭证。运行本代码示例之前请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Bucket名称例如examplebucket。 String bucketName java-ai; // 填写Object完整路径例如exampledir/exampleobject.txt。Object完整路径中不能包含Bucket名称。 String objectName 001.jpg; // 填写Bucket所在地域。以华东1杭州为例Region填写为cn-hangzhou。 String region cn-beijing; // 创建OSSClient实例。 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { File file new File(C:\\Users\\deng\\Pictures\\1.jpg); byte[] content Files.readAllBytes(file.toPath()); ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); } catch (OSSException oe) { System.out.println(Caught an OSSException, which means your request made it to OSS, but was rejected with an error response for some reason.); System.out.println(Error Message: oe.getErrorMessage()); System.out.println(Error Code: oe.getErrorCode()); System.out.println(Request ID: oe.getRequestId()); System.out.println(Host ID: oe.getHostId()); } catch (ClientException ce) { System.out.println(Caught an ClientException, which means the client encountered a serious internal problem while trying to communicate with OSS, such as not being able to access the network.); System.out.println(Error Message: ce.getMessage()); } finally { if (ossClient ! null) { ossClient.shutdown(); } } } }切记大家需要将上面的endpointbucketNameobjectNamefile都需要改成自己的。在以上代码中需要替换的内容为endpoint阿里云OSS中的bucket对应的域名bucketNameBucket名称objectName对象名称在Bucket中存储的对象的名称regionbucket所属区域运行以上程序后会把本地的文件上传到阿里云OSS服务器上。三集成3.1 介绍阿里云oss对象存储服务的准备工作以及入门程序我们都已经完成了接下来我们就需要在案例当中集成oss对象存储服务来存储和管理案例中上传的图片。在新增员工的时候上传员工的图像而之所以需要上传员工的图像是因为将来我们需要在系统页面当中访问并展示员工的图像。而要想完成这个操作需要做两件事需要上传员工的图像并把图像保存起来存储到阿里云OSS访问员工图像通过图像在阿里云OSS的存储地址访问图像OSS中的每一个文件都会分配一个访问的url通过这个url就可以访问到存储在阿里云上的图片。所以需要把url返回给前端这样前端就可以通过url获取到图像。我们参照接口文档来开发文件上传功能基本信息请求路径/upload 请求方式POST 接口描述上传图片接口请求参数参数格式multipart/form-data参数说明参数名称参数类型是否必须示例备注imagefile是响应数据参数格式application/json参数说明参数名类型是否必须备注codenumber必须响应码1 代表成功0 代表失败msgstring非必须提示信息dataobject非必须返回的数据上传图片的访问路径响应数据样例{ code: 1, msg: success, data: https://web-framework.oss-cn-hangzhou.aliyuncs.com/2022-09-02-00-27-0400.jpg }3.2 实现1). 引入阿里云OSS上传文件工具类由官方的示例代码改造而来package com.itheima.utils; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; Component public class AliyunOSSOperator { private String endpoint https://oss-cn-beijing.aliyuncs.com; private String bucketName java-ai; private String region cn-beijing; public String upload(byte[] content, String originalFilename) throws Exception { // 从环境变量中获取访问凭证。运行本代码示例之前请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Object完整路径例如202406/1.png。Object完整路径中不能包含Bucket名称。 //获取当前系统日期的字符串,格式为 yyyy/MM String dir LocalDate.now().format(DateTimeFormatter.ofPattern(yyyy/MM)); //生成一个新的不重复的文件名 String newFileName UUID.randomUUID() originalFilename.substring(originalFilename.lastIndexOf(.)); String objectName dir / newFileName; // 创建OSSClient实例。 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); } finally { ossClient.shutdown(); } return endpoint.split(//)[0] // bucketName . endpoint.split(//)[1] / objectName; } }2). 修改UploadController代码package com.itheima.controller; import com.itheima.pojo.Result; import com.itheima.utils.AliyunOSSOperator; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.File; import java.util.UUID; Slf4j RestController public class UploadController { Autowired private AliyunOSSOperator aliyunOSSOperator; PostMapping(/upload) public Result upload(MultipartFile file) throws Exception { log.info(上传文件{}, file); if (!file.isEmpty()) { // 生成唯一文件名 String originalFilename file.getOriginalFilename(); String extName originalFilename.substring(originalFilename.lastIndexOf(.)); String uniqueFileName UUID.randomUUID().toString().replace(-, ) extName; // 上传文件 String url aliyunOSSOperator.upload(file.getBytes(), uniqueFileName); return Result.success(url); } return Result.error(上传失败); } }使用 Apifox 测试接口测试通过之后我们就可以进行前后端联调了。3.3 功能优化员工管理的新增功能我们已开发完成但在我们所开发的程序中还一些小问题下面我们就来分析一下当前案例中存在的问题以及如何优化解决。在刚才我们制作的AliyunOSS操作的工具类中我们直接将 endpoint、bucketName参数直接在java文件中写死了。如下所示如果后续项目要部署到测试环境、上生产环境我们需要来修改这两个参数。 而如果开发一个大型项目所有用到的技术涉及到的这些个参数全部写死在java代码中是非常不便于维护和管理的。那么对于这些容易变动的参数我们可以将其配置在配置文件中然后通过Value注解来注解外部配置的属性。如下所示具体实现代码如下1). application.yml#阿里云OSS aliyun: oss: endpoint: https://oss-cn-beijing.aliyuncs.com bucketName: java-ai region: cn-beijing2). AliyunOSSOperatorpackage com.itheima.utils; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; Component public class AliyunOSSOperator { //方式一: 通过Value注解一个属性一个属性的注入 Value(${aliyun.oss.endpoint}) private String endpoint; Value(${aliyun.oss.bucketName}) private String bucketName; Value(${aliyun.oss.region}) private String region; public String upload(byte[] content, String originalFilename) throws Exception { // 从环境变量中获取访问凭证。运行本代码示例之前请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Object完整路径例如2024/06/1.png。Object完整路径中不能包含Bucket名称。 //获取当前系统日期的字符串,格式为 yyyy/MM String dir LocalDate.now().format(DateTimeFormatter.ofPattern(yyyy/MM)); //生成一个新的不重复的文件名 String newFileName UUID.randomUUID() originalFilename.substring(originalFilename.lastIndexOf(.)); String objectName dir / newFileName; // 创建OSSClient实例。 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); } finally { ossClient.shutdown(); } return endpoint.split(//)[0] // bucketName . endpoint.split(//)[1] / objectName; } }如果只有一两个属性需要注入而且不需要考虑复用性使用Value注解就可以了。但是使用Value注解注入配置文件的配置项如果配置项多注入繁琐不便于维护管理 和 复用。如下所示:那么有没有一种方式可以简化这些配置参数的注入呢答案是肯定有在Spring中给我们提供了一种简化方式可以直接将配置文件中配置项的值自动的注入到对象的属性中。Spring提供的简化方式套路1). 需要创建一个实现类且实体类中的属性名和配置文件当中key的名字必须要一致比如配置文件当中叫endpoint实体类当中的属性也得叫endpoint另外实体类当中的属性还需要提供 getter / setter方法2). 需要将实体类交给Spring的IOC容器管理成为IOC容器当中的bean对象3). 在实体类上添加ConfigurationProperties注解并通过perfect属性来指定配置参数项的前缀具体实现步骤:1). 定义实体类AliyunOSSProperties 并交给IOC容器管理package com.itheima.utils; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; Data Component ConfigurationProperties(prefix aliyun.oss) public class AliyunOSSProperties { private String endpoint; private String bucketName; private String region; }2). 修改AliyunOSSOperatorpackage com.itheima.utils; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.io.ByteArrayInputStream; import java.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.UUID; Component public class AliyunOSSOperator { //方式一: 通过Value注解一个属性一个属性的注入 //Value(${aliyun.oss.endpoint}) //private String endpoint; //Value(${aliyun.oss.bucketName}) //private String bucketName; //Value(${aliyun.oss.region}) //private String region; Autowired private AliyunOSSProperties aliyunOSSProperties; public String upload(byte[] content, String originalFilename) throws Exception { String endpoint aliyunOSSProperties.getEndpoint(); String bucketName aliyunOSSProperties.getBucketName(); String region aliyunOSSProperties.getRegion(); // 从环境变量中获取访问凭证。运行本代码示例之前请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。 EnvironmentVariableCredentialsProvider credentialsProvider CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // 填写Object完整路径例如2024/06/1.png。Object完整路径中不能包含Bucket名称。 //获取当前系统日期的字符串,格式为 yyyy/MM String dir LocalDate.now().format(DateTimeFormatter.ofPattern(yyyy/MM)); //生成一个新的不重复的文件名 String newFileName UUID.randomUUID() originalFilename.substring(originalFilename.lastIndexOf(.)); String objectName dir / newFileName; // 创建OSSClient实例。 ClientBuilderConfiguration clientBuilderConfiguration new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content)); } finally { ossClient.shutdown(); } return endpoint.split(//)[0] // bucketName . endpoint.split(//)[1] / objectName; } }