阿里云OSS实现图片上传(后端接口)
改进方法:在文件名称添加随机唯一值,让每个文件名称不同/**产生随机值*/ String uuid = UUID . randomUUID() . toString() . replaceAll("-" , "");
文章目录
1、阿里云oss服务开通
去阿里云官网开通“对象存储OSS”服务
点击免费试用:
点击立即试用即可
-
进入管理控制台
(1). 使用oss,创建bucket
(2)
完成创建
2、java操作阿里云oss,上传文件到阿里云oss
1. 创建操作阿里云oss许可证
新建的子用户AccessKey配置相应的管理对象存储服务(OSS)权限。
不加的话,会报com.aliyun.oss.OSSException: You have no right to access this object because of bucket acl.别问我是怎么知道的呜呜呜
将创建出的AccessKeyId和AccessKeySecret导出并保存到本地,方便以后使用
2. 安装SDK
在Maven工程中使用OSS Java SDK,只需在pom.xml中加入相应依赖即可。以3.15.1版本为例,在中加入如下内容:
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
3.修改配置文件
将endpoint及下面的配置写入你自己的
aliyun:
oss:
file:
endpoint:
keyid:
keysecret:
# bucket可以由控制台创建,也可以使用java代码创建
bucketname:
有可能你的OSS放在一个单独的子模块中,该子模块只做上传到OSS这一个功能,以至于启动类在启动时,去找数据库配置,由于找不到数据库配置,会报错。
解决方法是在启动类添加属性,默认不去加载数据库配置,如下:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
还需要设置文件上传最大限制,因为springboot对文件上传有默认最大限制,即最大可支持1MB的文件大小,在单个请求中最多可容纳10Mb的文件数据。当你传输的文件大于1MB,就会报👇
The field file exceeds its maximum permitted size of 1048576 bytes.
Spring Boot 2.0版本及以上,配置如下:具体设置文件上限大小就依你们实际需求而定,我只是举个例子
spring:
application:
name: service
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
4.创建常量类,读取配置文件中的内容
@Component
public class ConstantPropertiesUtil implements InitializingBean {
// 读取配置文件内容
@Value("${aliyun.oss.file.endpoint}")
private String endpoint;
@Value("${aliyun.oss.file.keyid}")
private String keyId;
@Value("${aliyun.oss.file.keysecret}")
private String keySecret;
@Value("${aliyun.oss.file.bucketname}")
private String bucketName;
public static String END_POINT;
public static String KEY_ID;
public static String KEY_SECRET;
public static String BUCKET_NAME;
@Override
public void afterPropertiesSet() throws Exception {
END_POINT = endpoint;
KEY_ID = keyId;
KEY_SECRET = keySecret;
BUCKET_NAME = bucketName;
}
}
由于实现了InitializingBean这个接口,当读取完配置文件中的数据后,就会调用afterPropertiesSet方法,将属性暴露出去,供其他类使用
5、OssController
@RestController
@RequestMapping("/oss/fileoss")
public class OssController {
@Autowired
private OssService ossService;
@PostMapping
public ResultUtil uploadOssFile(@RequestBody MultipartFile file){
/**返回上传到oss的路径*/
String url = ossService.uploadFileAvatar(file);
return ResultUtil.success(url);
}
}
@Data
public class ResultUtil {
private String code;
private String message;
private Object data;
public static ResultUtil success(Object data){
ResultUtil resultUtil = new ResultUtil();
resultUtil.setCode("200");
resultUtil.setMessage("请求成功");
resultUtil.setData(data);
return resultUtil;
}
}
6、OssService
public interface OssService {
/**上传头像到oss*/
String uploadFileAvatar(MultipartFile multipartFile);
}
7、OssServiceImpl
@Service
public class OssServiceImpl implements OssService {
@Override
public String uploadFileAvatar(MultipartFile multipartFile) {
String endpoint = ConstantPropertiesUtil.END_POINT;
String accessKeyId = ConstantPropertiesUtil.ACCESS_KEY_ID;
String accessKeySecret = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
// 填写Bucket名称
String bucketName = ConstantPropertiesUtil.BUCKET_NAME;
/** 创建OSSClient实例。*/
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
try {
/** 获取上传文件输入流*/
InputStream inputStream = multipartFile.getInputStream();
/**获取文件名称*/
String filename = multipartFile.getOriginalFilename();
/**调用oss方法实现上传*/
//第一个参数 Bucket名称
//第二个参数 上传到oss文件路径或文件名称
//第三个参数 上传文件输入流
ossClient.putObject(bucketName, filename, inputStream);
/** 返回上传到阿里OSS的路径*/
String url = "https://".concat(bucketName).concat(".").concat(endpoint).concat("/").concat(filename);
return url;
}catch (Exception e){
e.printStackTrace();
return null;
}finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
postman测试:
可以看到,已经上传成功。
8、改进
1. 多次上传相同名称文件,会造成最后一次上传把之前上传文件覆盖
改进方法:在文件名称添加随机唯一值,让每个文件名称不同
/**产生随机值*/
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
filename = filename.concat(uuid);
2. 把文件进行分类管理
改进方法:根据日期进行分类,实现年月日分类
如果ossClient.putObject中的第二个参数形式为aa/bb/1.jpg,则上传到OSS后,OSS会创建aa/bb目录。
/**把文件按照日期进行分类*/
String datePath = new DateTime().toString("yyyy/MM/dd");
filename = datePath.concat("/").concat(filename);
还是传之前的图片,结果👇:
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)