Day09 后端Web实战:员工管理2(新增.事务.上传)
需求

目录
- 新增员工
- 事务管理
- 文件上传
1. 新增员工
①需求

新增员工sql语句
-- 新增员工
-- 保存员工基本信息-emp
insert into emp(username, name, gender, phone, job, salary, image, entry_date, dept_id, create_time, update_time) values
('linpingzhi','林平之',1,'13309091234',1,6000,'1.jpg','2020-01-01',1, '2024-10-01 00:00:00', '2024-10-01 00:00:00');
-- 批量保存员工工作经历信息-emp_exprx
insert into emp_expr(emp_id, begin, end, company,job) values
(37,'2020-01-01','2021-01-01','百度','java开发'),
(37,'2021-01-01','2023-01-01','字节','java开发');
②思路

③实现

cn/zjy/pojo/Emp.java 添加下列1条属性
//封装工作经历信息
private List<EmpExpr> exprList;
cn/zjy/controller/EmpController.java 添加下列方法
/**
* 新增员工
*/
@PostMapping
public Result save(@RequestBody Emp emp){
log.info("新增员工:{}", emp);
empService.save(emp);
return Result.success();
};
cn/zjy/service/EmpService.java 添加下列1条方法名
void save(Emp emp);
cn/zjy/mapper/EmpExprMapper.java 添加本接口
package cn.zjy.mapper;
import cn.zjy.pojo.EmpExpr;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* 员工管理
*/
@Mapper
public interface EmpExprMapper {
/**
* 批量保存员工的工作经历信息
*/
void insertBatch(List<EmpExpr> exprList);
}
cn/zjy/service/impl/EmpServiceImpl.java 修改save中保存员工工作经历信息部分
@Autowired
private EmpExprMapper empExprMapper;
@Override
public void save(Emp emp) {
//1.保存员工基本信息
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
empMapper.insert(emp);
//2.保存员工工作经历信息
List<EmpExpr> exprList = emp.getExprList();
if (!CollectionUtils.isEmpty(exprList)){
//遍历集合,为empId赋值
exprList.forEach(empExpr-> {
empExpr.setEmpId(emp.getId());
});
empExprMapper.insertBatch(exprList);
}
}
cn/zjy/mapper/EmpMapper.java 添加@Options注解
/**
*新增员工基本信息
*/
@Options(useGeneratedKeys = true, keyProperty = "id") //获取到生成的主键--主键返回
@Insert("insert into emp(username, name, gender, phone, job, salary, image, entry_date, dept_id, create_time, update_time)" +
" values (#{username},#{name},#{gender},#{phone},#{job},#{salary},#{image},#{entryDate},#{deptId},#{createTime},#{updateTime})")
void insert(Emp emp);
src/main/resources/cn/zjy/mapper/EmpExprMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.zjy.mapper.EmpExprMapper">
<!--批量保存员工工作经历信息
foreach标签:
collection:遍历的集合
item:遍历出来的元素
separator:每次循环之间的分隔符
-->
<insert id="insertBatch">
insert into emp_expr(emp_id, begin, end, company, job) values
<foreach collection="exprList" item="expr" separator=",">
(#{expr.empId},#{expr.begin},#{expr.end},#{expr.company},#{expr.job})
</foreach>
</insert>
</mapper>
新增员工--批量保存工作经历






2. 事务管理
问题提出

2.1 介绍&操作
①介绍
- 概念:事务是一组操作的集合,它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,即这些操作要么同时成功,要么同时失败

②操作
-- 成功测试 -- 同时成功
-- 开启事务
start transaction ;
-- 保存员工基本信息-emp
insert into emp(id, username, name, gender, phone,job, salary, image, entry_date, dept_id, create_time, update_time)
values(48,'qiaofeng','杜乔峰', 1,'13356560011', 1,6000,'1.jpg','2020-01-01', 1,now(), now());
-- 批量保存员工工作经历信息-emp_expr
insert into emp_expr(emp_id, begin, end, company, job) values
(48,'2020-01-01','2021-01-01','百度','java开发'),
(48,'2021-01-01','2023-01-01','字节','java开发');
-- 提交事务
commit;
select * from emp;
select * from emp_expr;

-- 新增员工 -- 回滚测试
-- 开启事务
start transaction ;
-- 保存员工基本信息-emp
insert into emp(id, username, name, gender, phone,job, salary, image, entry_date, dept_id, create_time, update_time)
values(49,'duanyu','杜段誉', 1,'13356560012', 1,6000,'1.jpg','2020-01-01', 1,now(), now());
-- 批量保存员工工作经历信息-emp_expr
insert into emp_expr(emp_id, begin, end, company, job) values
(49,'2020-01-01','2021-01-01','百度','java开发')
(49,'2021-01-01','2023-01-01','字节','java开发');
-- 回滚事务
rollback ;
select * from emp;
select * from emp_expr;

小结

2.2 Spring事务管理
事务

① Spring事务控制
- 注解:@Transactional
- 作用:将当前方法交给spring进行事务管理,方法执行前,开启事务;成功执行完毕,提交事务;出现异常,回滚事务
- 位置:业务(service)层的方法上、类上、接口上

cn/zjy/service/impl/EmpServiceImpl.java
@Transactional
@Override
public void save(Emp emp) {
//1.保存员工基本信息
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
empMapper.insert(emp);
int i = 1/0;
//2.保存员工工作经历信息
List<EmpExpr> exprList = emp.getExprList();
if (!CollectionUtils.isEmpty(exprList)){
//遍历集合,为empId赋值
exprList.forEach(empExpr-> {
empExpr.setEmpId(emp.getId());
});
empExprMapper.insertBatch(exprList);
}
src/main/resources/application.yml 添加如下配置
# 配置事务管理日志级别
logging:
level:
org.springframework.jdbc.support.JdbcTransactionManager: debug
Grep Console 插件



② 事务进阶-rollbackFor属性

cn/zjy/controller/EmpController.java 添加 throws Exception
@PostMapping
public Result save(@RequestBody Emp emp) throws Exception {
log.info("新增员工:{}", emp);
empService.save(emp);
return Result.success();
};
cn/zjy/service/EmpService.java 添加 throws Exception
void save(Emp emp) throws Exception;
cn/zjy/service/impl/EmpServiceImpl.java throw new Exception("出错啦~~~");
@Transactional //(rollbackFor={Exception.class})
//事务管理-默认出现运行时异常RuntimeException才会回滚 //Spring事务控制
@Override
public void save(Emp emp) throws Exception {
//1.保存员工基本信息
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
empMapper.insert(emp);
// int i = 1/0;
if (true){
throw new Exception("出错啦~~~");
}
//2.保存员工工作经历信息
List<EmpExpr> exprList = emp.getExprList();
if (!CollectionUtils.isEmpty(exprList)){
//遍历集合,为empId赋值
exprList.forEach(empExpr-> {
empExpr.setEmpId(emp.getId());
});
empExprMapper.insertBatch(exprList);
}
}


③ 事务传播行为
- 事务传播行为:指的就是当一个事务方法被另一个事务方法调用时,这个事务方法应该如何进行事务控制。
| 属性值 | 含义 |
|---|---|
| REQUIRED | 【默认值】需要事务,有则加入,无则创建新事务 |
| REQUIRES_NEW | 需要新事务,无论有无,总是创建新事务 |
| SUPPORTS | 支持事务,有则加入,无则在无事务状态中运行 |
| NOT_SUPPORTED | 不支持事务,在无事务状态下运行,如果当前存在已有事务,则挂起当前事务 |
| MANDATORY | 必须有事务,否则抛异常 |
| NEVER | 必须没事务,否则抛异常 |
| . . . |

事务传播案例

-- 创建员工日志表
create table emp_log(
id int unsigned primary key auto_increment comment 'ID, 主键',
operate_time datetime comment '操作时间',
info varchar(2000) comment '日志信息'
) comment '员工日志表';
ccn/zjy/pojo/EmpLog.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class EmpLog {
private Integer id; //ID
private LocalDateTime operateTime; //操作时间
private String info; //详细信息
}
cn/zjy/mapper/EmpLogMapper.java
@Mapper
public interface EmpLogMapper {
@Insert("insert into emp_log (operate_time, info) values (#{operateTime}, #{info})")
public void insert(EmpLog empLog);
}
cn/zjy/service/EmpLogService.java
package cn.zjy.service;
import cn.zjy.pojo.EmpLog;
public interface EmpLogService {
void insertLog(EmpLog empLog);
}
cn/zjy/service/impl/EmpLogServiceImpl.java
package cn.zjy.service.impl;
import cn.zjy.mapper.EmpLogMapper;
import cn.zjy.pojo.EmpLog;
import cn.zjy.service.EmpLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class EmpLogServiceImpl implements EmpLogService {
@Autowired
private EmpLogMapper empLogMapper;
@Override
public void insertLog(EmpLog empLog) {
empLogMapper.insert(empLog);
}
}
cn/zjy/service/impl/EmpServiceImpl.java修改save方法,去掉 throws Exception; 等
@Transactional //(rollbackFor={Exception.class})//事务管理-默认出现运行时异常RuntimeException才会回滚 //Spring事务控制
@Override
public void save(Emp emp) { // throws Exception {
try{
//1.保存员工基本信息
emp.setCreateTime(LocalDateTime.now());
emp.setUpdateTime(LocalDateTime.now());
empMapper.insert(emp);
// int i = 1/0;
// if (true){
// throw new Exception("出错啦~~~");
// }
//2.保存员工工作经历信息
List<EmpExpr> exprList = emp.getExprList();
if (!CollectionUtils.isEmpty(exprList)){
//遍历集合,为empId赋值
exprList.forEach(empExpr-> {
empExpr.setEmpId(emp.getId());
});
empExprMapper.insertBatch(exprList);
}
} finally {
//记录操作日志
EmpLog empLog =new EmpLog(null,LocalDateTime.now(),"新增员工:"+emp);
empLogService.insertLog(empLog);
}
}

cn/zjy/service/impl/EmpLogServiceImpl.java 添加@Transactional(propagation = Propagation.REQUIRES_NEW )
@Service
public class EmpLogServiceImpl implements EmpLogService {
@Autowired
private EmpLogMapper empLogMapper;
@Transactional(propagation = Propagation.REQUIRES_NEW )
@Override
public void insertLog(EmpLog empLog) {
empLogMapper.insert(empLog);
}
}
cn/zjy/service/impl/EmpLogServiceImpl.java 修改
int i = 1/0;

小结

2.3 四大特性
- 事务是不可分割的最小单元,要么全部成功,要么全部失败
- 事务完成时,必须使所有的数据都保持一致状态
- 数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运行
- 事务一旦提交或回滚,它对数据库中的数据的改变就是永久的

3.文件上传
3.0 问题的提出

3.1 简介
- 文件上传:是指将本地图片、视频、音频等文件上传到服务器,供其他用户浏览或下载的过程。
- 文件上传在项目中应用非常广泛,我们经常发微博、发微信朋友圈都用到了文件上传功能。

中国梦.txt
张婧怡《中国梦》
党的十八大闭幕不久,习近平总书记在参观国家博物馆《复兴之路》展览时,首次提出并阐述“中国梦”
十年来,从提出中国梦,到强调不忘初心、牢记使命,再到谋划以中国式现代化全面推进中华民族伟大复兴,中国共产党人把光荣梦想书写在自己的旗帜上,团结带领中国人民为实现这个光荣梦想而不懈奋斗。
十年来,从提出中国梦,到强调不忘初心、牢记使命,再到谋划以中国式现代化全面推进中华民族伟大复兴,中国共产党人把光荣梦想书写在自己的旗帜上,团结带领中国人民为实现这个光荣梦想而不懈奋斗。
十年来,从提出中国梦,到强调不忘初心、牢记使命,再到谋划以中国式现代化全面推进中华民族伟大复兴,中国共产党人把光荣梦想书写在自己的旗帜上,团结带领中国人民为实现这个光荣梦想而不懈奋斗。
十年来,从提出中国梦,到强调不忘初心、牢记使命,再到谋划以中国式现代化全面推进中华民族伟大复兴,中国共产党人把光荣梦想书写在自己的旗帜上,团结带领中国人民为实现这个光荣梦想而不懈奋斗。
十年来,从提出中国梦,到强调不忘初心、牢记使命,再到谋划以中国式现代化全面推进中华民族伟大复兴,中国共产党人把光荣梦想书写在自己的旗帜上,团结带领中国人民为实现这个光荣梦想而不懈奋斗。
党的十八大闭幕不久,习近平总书记在参观国家博物馆《复兴之路》展览时,首次提出并阐述“中国梦”。
src/main/resources/static/upload.html
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
姓名: <input type="text" name="name"><br>
年龄: <input type="text" name="age"><br>
头像: <input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>

src/main/resources/static/upload.html 去掉enctype="multipart/form-data
<!DOCTYPE html>
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>上传文件</title>
</head>
<body>
<form action="/upload" method="post">
姓名: <input type="text" name="name"><br>
年龄: <input type="text" name="age"><br>
头像: <input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>

cn/zjy/controller/UploadController.java
package cn.zjy.controller;
import cn.zjy.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@RestController
public class UploadController{
@PostMapping("/upload")
public Result upload(String name, Integer age, MultipartFile file) {
log.info("接收参数:{},{},{}",name,age,file);
return Result.success();
}
}


3.2 本地存储
src/test/java/cn/zjy/UUIDTest.java
import org.junit.jupiter.api.Test;
import java.util.UUID;
public class UUIDTest {
@Test
public void testUuid() {
for (int i = 0; i < 10000; i++) {
System.out.println(UUID.randomUUID().toString());
}
}
}
cn/zjy/controller/UploadController.java
package cn.zjy.controller;
import cn.zjy.pojo.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@Slf4j
@RestController
public class UploadController{
@PostMapping("/upload")
public Result upload(String name, Integer age, MultipartFile file) {
log.info("接收参数:{},{},{}",name,age,file);
// 获取原始文件名
String originalFilename =file.getOriginalFilename();
// 新的文件名
// String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
// String newFileName = UUID.randomUUID().toString()+ extension;
String newFileName = UUID.randomUUID().toString() +"_" + originalFilename; // uuid_原始文件名
// 保存文件
file.transferTo(new File("D:/images/" + newFileName));
// return Result.success();
return Result.success(newFileName); // 返回文件名 uuid_原始文件名
}
}
// 备忘
@PostMapping("/upload")
public Result handleFileUpload(MultipartFile file) throws Exception {
log.info("文件上传:{}", file);
// 生成唯一文件名
String uniqueFileName = generateUniqueFileName(file.getOriginalFilename());
// 保存文件
image.transferTo(new File("D:/images/" + uniqueFileName));
return Result.success();
}
private String generateUniqueFileName(String originalFilename) {
String randomStr = UUID.randomUUID().toString().replaceAll("-", "");
String extension = originalFilename.substring(originalFilename.lastIndexOf("."));
return randomStr + extension;
}
MaxUploadSizeExceededException:Maximum upload size exceeded]
application.yml
spring:
servlet:
multipart:
max-file-size:10MB # 最大单个文件大小
max-request-size:100MB # 最大请求总大小(包括所有文件和表单数据)


3.3 阿里云OSS
问题的提出

阿里云
阿里云是阿里巴巴集团旗下全球领先的云计算公司,也是国内最大的云服务提供商。(全球第4大云服务供应商,前三:亚马逊、微软、谷歌)

阿里云OSS
阿里云对象存储OSS(Object Storage Service),是一款海量、安全、低成本、高可靠的云存储服务。使用OSS,您可以通过网络随时存储和调用包括文本、图片、音频和视频等在内的各种文件。

第三方服务一通用思路
- 准备工作 -->> 参照官方SDK编写入门程序 -->> 集成使用
- SDK:SoftwareDevelopmentKit的缩写,软件开发工具包,包括辅助软件开发的依赖(jar包)、代码示例等,都可以叫做SDK。
① 准备工作
- 注册阿里云、开通OSS服务、创建bucket、获取并配置AccessKey(注意保管好你的AccessKey)。
阿里云OSS-使用步骤
- 注册阿里云(实名认证)->充值->开通对象存储服务(OSS)->创建bucket:java-ai->获取并配置AccessKey(秘钥)->参照官方SDK编写入门程序->案例集成OSS
- 官网:aliyun.com
- bucket:du-java-ai 公共读 个性化bucket名
- Bucket:存储空间是用户用于存储对象(Object,就是文件)的容器,所有的对象都必须隶属于某个存储空间。



配置AccessKey
以管理员身份打开CMD命令行,执行如下命令。
# 配置系统的环境变量
set OSS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
set OSS_ACCESS_KEY_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# 执行如下命令,让更改生效。
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%
注意:将上述的ACCESS_KEY_ID 与 ACCESS_KEY_SECRET 的值一定要替换成自己的、一定要保存好自己的密钥 。
② 阿里云OSS-入门程序
oss.console.aliyun.com/sdk
Demo程序网址

src/test/java/cn/zjy/Demo.java
package cn.zjy;
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.*;
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 = "du-java-ai";
// 填写Object完整路径,完整路径中不能包含Bucket名称,例如exampledir/exampleobject.txt。
String objectName = "zjy.jpg";
// 填写Bucket所在地域。以华东1(杭州)为例,Region填写为cn-hangzhou。
String region = "cn-beijing";
// 创建OSSClient实例。
// 当OSSClient实例不再使用时,调用shutdown方法以释放资源。
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("D:\\images\\zjy.jpg");
byte[] content = Files.readAllBytes(file.toPath());
// 创建PutObjectRequest对象。
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content));
// 创建PutObject请求。
PutObjectResult result = ossClient.putObject(putObjectRequest);
} 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();
}
}
}
}

注意:
在使用第三方提供的云服务或技术时,一定要参照对应的官方文档进行开发和测试。
③ 阿里云OSS-案例集成
需求

步骤:
- 引入阿里云OSS文件上传工具类(由官方的示例代码改造而来)
cn/zjy/utils/AliyunOSSOperator.java
package cn.zjy.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 = "du-java-ai"; //修改为你自己的bucketName
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;
}
}
- 上传文件接口开发
UploadController.java 修改upload方法
@Autowired
private AliyunOSSOperator aliyunOSSOperator;
/**
* 文件上传,上传到阿里云oss
*/
@PostMapping("/upload")
public Result upload(MultipartFile file) throws Exception {
log.info("文件上传:{}", file);
String url = aliyunOSSOperator.upload(file.getBytes(), file.getOriginalFilename());
log.info("文件上传oss,url:{}", url);
return Result.success(url);
}


参数配置化
- 指将一些需要灵活变化的参数,配置在配置文件中,然后通过@Value注解来注入外部配置的属性。

application.yml
aliyun:
oss:
endpoint: https://oss-cn-beijing.aliyuncs.com
bucketName: java-ai
region: cn-beijing
AliyunOSSOperator
import org.springframework.beans.factory.annotation.Value;
@Component
public class AliyunOSSOperator {
@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("${aliyun.oss.bucketName}")
private String bucketName;
@Value("${aliyun.oss.region}")
private String region;
}


@ConfigurationProperties


cn/zjy/utils/AliyunOSSProperties.java
package cn.zjy.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;
}
cn/zjy/utils/AliyunOSSOperator.java
package cn.zjy.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 {
// 将参数写入代码 中
// private String endpoint = "https://oss-cn-beijing.aliyuncs.com";
// private String bucketName = "du-java-ai"; //修改为你自己的bucketName
// private String region = "cn-beijing";
// 方式1 将参数读取配置文件
/*@Value("${aliyun.oss.endpoint}")
private String endpoint;
@Value("$[aliyun.oss.bucketName}")
private String bucketName;
@Value("$[aliyun.oss.region}")
private String region;*/
// 方式2 将参数读取配置文件和创建对象Properties文件
@Autowired
private AliyunOSSProperties aliyunOSSProperties;
public String upload(byte[] content, String originalFilename) throws Exception {
// 方式2
String bucketName = aliyunOSSProperties.getBucketName();
String region = aliyunOSSProperties.getRegion();
String endpoint = aliyunOSSProperties.getEndpoint();
//.....
}
}


①②③④⑤⑥⑦⑧⑨⑩