SpringBoot整合OSS实现图片存储
- maven依赖
- yml文件
- 配置类
- DTO类
- 工具类
- 控制类
- 测试
图片上传有很多方式,如存储至硬盘目录,数据库表中,还可以对象存储,这里使用的阿里云做测试
那些配置阿里云OSS的我就不过于多去介绍,可以去网站上找一些其他文章查看,我这里只做一下实现
maven依赖
首先需要一个Maven依赖如下
<!-- OSS SDK 相关依赖 -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.4.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
yml文件
在yml文件中加入一下OSS配置
具体如下,各个参数都可以在配置完成OSS之后去找到
# OSS相关配置信息
aliyun:
file:
endpoint: oss-cn-*******************.com # oss对外服务的访问域名
accessKeyId: LTAI4*********************3X2 # 访问身份验证中用到用户标识
accessKeySecret: w8Y9**************c14iQyQ3 # 用户用于加密签名字符串和oss用来验证签名字符串的密钥
bucketName: dd*****ile # oss的存储空间
folder : ****/
webUrl: http://************************.com
配置类
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
/**
* @Author uncletj
* @Date 2021/3/22 15:22
* @Version SpringBoot 2.2.2
* @projectName OSS存储配置类
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
@Configuration
public class ConstantConfig {
@Value("${aliyun.file.endpoint}")
private String endpoint;
@Value("${aliyun.file.accessKeyId}")
private String accessKeyId;
@Value("${aliyun.file.accessKeySecret}")
private String accessKeySecret;
@Value("${aliyun.file.folder}")
private String folder;
@Value("${aliyun.file.bucketName}")
private String bucketName;
@Value("${aliyun.file.webUrl}")
private String webUrl;
}
DTO类
这个类主要是将上传至OSS的数据进行返回然后将返回过来的数据存储至数据库
import lombok.Data;
/**
* @Author uncletj
* @Date 2021/3/22 15:25
* @Version SpringBoot 2.2.2
* @projectName 图片信息DTO类
*/
@Data
public class FileDTO {
/**
* 文件大小
*/
private Long fileSize;
/**
* 文件的绝对路径
*/
private String fileAPUrl;
/**
* 文件的web访问地址
*/
private String webUrl;
/**
* 文件后缀
*/
private String fileSuffix;
/**
* 存储的bucket
*/
private String fileBucket;
/**
* 原文件名
*/
private String oldFileName;
/**
* 存储的文件夹
*/
private String folder;
public FileDTO() {
}
public FileDTO(Long fileSize, String fileAPUrl, String webUrl, String fileSuffix, String fileBucket, String oldFileName, String folder) {
this.fileSize = fileSize;
this.fileAPUrl = fileAPUrl;
this.webUrl = webUrl;
this.fileSuffix = fileSuffix;
this.fileBucket = fileBucket;
this.oldFileName = oldFileName;
this.folder = folder;
}
}
工具类
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.CannedAccessControlList;
import com.aliyun.oss.model.CreateBucketRequest;
import com.aliyun.oss.model.PutObjectRequest;
import com.aliyun.oss.model.PutObjectResult;
import com.duodf.uncletj.config.ConstantConfig;
import com.duodf.uncletj.dto.ftp.FileDTO;
import com.duodf.uncletj.dto.ftp.FtpDto;
import com.duodf.uncletj.service.ftp.FtpService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.File;
import java.util.UUID;
/**
* @Author uncletj
* @Date 2021/3/22 15:26
* @Version SpringBoot 2.2.2
* @projectName OSS上传工具类
*/
@Component
public class AliyunOSSUtil {
@Autowired
private ConstantConfig constantConfig;
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class);
@Autowired
private FtpService ftpService;
/** 上传文件*/
public FileDTO upLoad(File file){
logger.info("------OSS文件上传开始--------"+file.getName());
String endpoint=constantConfig.getEndpoint();
System.out.println("获取到的Point为:"+endpoint);
String accessKeyId=constantConfig.getAccessKeyId();
String accessKeySecret=constantConfig.getAccessKeySecret();
String bucketName=constantConfig.getBucketName();
String fileHost=constantConfig.getFolder();
String uuid = UUID.randomUUID().toString().replace("-", "");
String suffix = file.getName().substring(file.getName().lastIndexOf("."));
// 判断文件
if(file==null){
return null;
}
OSSClient client=new OSSClient(endpoint, accessKeyId, accessKeySecret);
try {
// 判断容器是否存在,不存在就创建
if (!client.doesBucketExist(bucketName)) {
client.createBucket(bucketName);
CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
client.createBucket(createBucketRequest);
}
// 设置文件路径和名称
String fileUrl = fileHost + uuid + "-" + file.getName();
// 设置权限(公开读)
client.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
// 上传文件
PutObjectResult result = client.putObject(new PutObjectRequest(bucketName, fileUrl, file));
if (result != null) {
System.out.println(result);
logger.info("------OSS文件上传成功------" + fileUrl);
//这个是数据库的实体类,当然是可以直接使用fileDTO这个类当作数据库表的字段,但是我这里
//用了两个类去分开
FtpDto ftpDto = new FtpDto();
ftpDto.setBid(fileHost);
ftpDto.setFilepath(constantConfig.getWebUrl() +"/"+ fileUrl);
ftpDto.setFilename(suffix);
ftpService.getFtpInsert(ftpDto);
return new FileDTO(
file.length(),//文件大小
fileUrl,//文件的绝对路径
constantConfig.getWebUrl() +"/"+ fileUrl,//文件的web访问地址
suffix,//文件后缀
"",//存储的bucket
bucketName,//原文件名
fileHost//存储的文件夹
);
}
}catch (OSSException oe){
logger.error(oe.getMessage());
}catch (ClientException ce){
logger.error(ce.getErrorMessage());
}finally{
if(client!=null){
client.shutdown();
}
}
return null;
}
}
控制类
接下来基本上操作都已经完成,在写一个Controller去进行调用即可
import com.duodf.uncletj.dto.ftp.FileDTO;
import com.duodf.uncletj.utils.oss.AliyunOSSUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
/**
* @Author uncletj
* @Date 2021/3/22 12:35
* @Version SpringBoot 2.2.2
* @projectName
*/
@Api(description = "文件上传",tags = {"文件上传接口"})
@RestController
@RequestMapping("/oss")
public class OssController {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
private AliyunOSSUtil aliyunOSSUtil;
/** 文件上传*/
@PostMapping(value = "/uploadFile")
@ApiOperation(value = "上传图片", notes = "上传图片", httpMethod="POST" ,consumes="multipart/form-data")
public FileDTO uploadBlog(@ApiParam(value="文件",required=true) MultipartFile file) {
logger.info("文件上传");
String filename = file.getOriginalFilename();
System.out.println(filename);
try {
// 判断文件
if (file!=null) {
if (!"".equals(filename.trim())) {
File newFile = new File(filename);
FileOutputStream os = new FileOutputStream(newFile);
os.write(file.getBytes());
os.close();
file.transferTo(newFile);
// 上传到OSS
return aliyunOSSUtil.upLoad(newFile);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
测试
使用的是Swagger测试,下面看一下效果如何
去阿里云OSS看图片是否存储进去
将返回来的信息存储至数据库即可,再看看数据库信息(注意:添加至数据库的操作在上方代码中已经实现还需要写一个Service方法去实现)
这样OSS数据存储就完成了