springboot 阿里云上传文件实例(OSS)
导包
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.8.0</version>
</dependency>
配置文件(application.properties)
#访问OSS的域名
aliyun.endpoint=http://oss-cn-beijing.aliyuncs.com
aliyun.accessKeyId=your accessKeyId
aliyun.accessKeySecret=your accessKeySecret
#管理所存储Object的存储空间名称
aliyun.bucketName=your bucketName
spring.servlet.multipart.max-request-size=10MB
spring.servlet.multipart.max-file-size=10MB
OSS配置
@Configuration
@Component
public class OSSConfiguration {
private volatile static OSS ossClient;
private volatile static OSSClientBuilder ossClientBuilder;
private static String endpoint;
private static String accessKeyId;
private static String accessKeySecret;
@Value("${aliyun.bucketName}")
private String bucketName;
@Value("${aliyun.endpoint}")
public void setEndpoint(String endpoint) {
OSSConfiguration.endpoint = endpoint;
}
@Value("${aliyun.accessKeyId}")
public void setAccessKeyId(String accessKeyId) {
OSSConfiguration.accessKeyId = accessKeyId;
}
@Value("${aliyun.accessKeySecret}")
public void setAccessKeySecret(String accessKeySecret) {
OSSConfiguration.accessKeySecret = accessKeySecret;
}
public String getBucketName() {
return bucketName;
}
/**
* 用来解决多例问题,如果多线程同时请求的话,单例不安全,要用多例,使用这个注解解决这个问题
* 单例表示每次只是用一个对象,不用重新生成对象,所以性能搞,但不安全,所以要用多例每次请求都要生成一个对象
* 定义一个非静态成员变量时候,则通过注解@Scope("prototype"),将其设置为多例模式。
*
* 这里是初始化阿里云oss客户端
*/
@Bean
@Scope("prototype")
public static OSS initOSSClient() {
if (ossClient == null) {
synchronized (OSSConfiguration.class) {
if (ossClient == null) {
ossClient = initOSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
}
}
}
return ossClient;
}
public static OSSClientBuilder initOSSClientBuilder() {
if (ossClientBuilder == null) {
synchronized (OSSConfiguration.class) {
if (ossClientBuilder == null) {
ossClientBuilder = new OSSClientBuilder();
}
}
}
return ossClientBuilder;
}
}
service
@Component
public class OSSService {
public static Logger log = LoggerFactory.getLogger(OSSService.class);
@Autowired
private OSSConfiguration ossConfiguration;
@Autowired
private OSS ossClient;
/**
* 上传文件到阿里云 OSS 服务器
* 链接:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/upload_object.html?spm=5176.docoss/user_guide/upload_object
*
* @param file
* @param storagePath 文件夹名称
* @return
*/
public String uploadFile(MultipartFile file, String storagePath) {
String fileName = "";
try {
// 创建一个唯一的文件名,类似于id,就是保存在OSS服务器上文件的文件名
fileName = UUID.randomUUID().toString();
InputStream inputStream = file.getInputStream();
// 设置对象
ObjectMetadata objectMetadata = new ObjectMetadata();
// 设置数据流里有多少个字节可以读取
objectMetadata.setContentLength(inputStream.available());
objectMetadata.setCacheControl("no-cache");
objectMetadata.setHeader("Pragma", "no-cache");
//objectMetadata.setContentType(file.getContentType());
//图片的时候就用就用下面这个类型,如果用上面的会导致预览地址的时候会直接下载文件
objectMetadata.setContentType("image/jpg");
objectMetadata.setContentDisposition("inline;filename=" + fileName);
fileName = storagePath + "/" + fileName;
//log.info("test===>"+file.getContentType());
// 上传文件
ossClient.putObject(ossConfiguration.getBucketName(), fileName, inputStream, objectMetadata);
} catch (IOException e) {
log.error("Error occurred: {}", e.getMessage(), e);
}
return fileName;
}
/**
* 下载文件
* 详细请参看“SDK手册 > Java-SDK > 上传文件”
* 链接:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/download_object.html?spm=5176.docoss/sdk/java-sdk/manage_object
*
* @param os
* @param objectName
*/
public void exportFile(OutputStream os, String objectName) {
// ossObject包含文件所在的存储空间名称、文件名称、文件元信息以及一个输入流
OSSObject ossObject = ossClient.getObject(ossConfiguration.getBucketName(), objectName);
// 读取文件内容
BufferedInputStream in = new BufferedInputStream(ossObject.getObjectContent());
BufferedOutputStream out = new BufferedOutputStream(os);
byte[] buffer = new byte[1024];
int lenght;
try {
while ((lenght = in.read(buffer)) != -1) {
out.write(buffer, 0, lenght);
}
out.flush();
} catch (IOException e) {
log.error("Error occurred: {}", e.getMessage(), e);
}
}
/**
* 获取 url
*
* @param filename
* @param expSeconds
* @return
*/
public String getSingeNatureUrl(String filename, int expSeconds) {
Date expiration = new Date(System.currentTimeMillis() + expSeconds * 1000);
URL url = ossClient.generatePresignedUrl(ossConfiguration.getBucketName(), filename, expiration);
if (url != null) {
return url.toString();
}
return null;
}
/**
* 删除文件
* 详细请参看“SDK手册 > Java-SDK > 管理文件”
* 链接:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/sdk/java-sdk/manage_bucket
*
* @param fileName
*/
public void deleteFile(String fileName) {
try {
ossClient.deleteObject(ossConfiguration.getBucketName(), fileName);
} catch (Exception e) {
log.error("Error occurred: {}", e.getMessage(), e);
}
}
/**
* 判断文件是否存在
*
* @param fileName
* @return
*/
public boolean doesObjectExist(String fileName) {
try {
if (Strings.isEmpty(fileName)) {
log.error("文件名不能为空");
return false;
} else {
return ossClient.doesObjectExist(ossConfiguration.getBucketName(), fileName);
}
} catch (OSSException | ClientException e) {
e.printStackTrace();
}
return false;
}
/**
* 查看 Bucket 中的 Object 列表
* 详细请参看“SDK手册 > Java-SDK > 管理文件”
* 链接:https://help.aliyun.com/document_detail/oss/sdk/java-sdk/manage_object.html?spm=5176.docoss/sdk/java-sdk/manage_bucket
*
* @return
*/
public List<String> listObjects() {
ListObjectsRequest listObjectsRequest = new ListObjectsRequest(ossConfiguration.getBucketName()).withMaxKeys(200);
ObjectListing objectListing = ossClient.listObjects(listObjectsRequest);
List<OSSObjectSummary> objectSummaries = objectListing.getObjectSummaries();
return objectSummaries.stream().map(OSSObjectSummary::getKey).collect(Collectors.toList());
}
/**
* 设置文件访问权限
* 详细请参看“SDK手册 > Java-SDK > 管理文件”
* 链接:https://help.aliyun.com/document_detail/84838.html
*
* @param fileName
*/
public void setObjectAcl(String fileName) {
ossClient.setObjectAcl(ossConfiguration.getBucketName(), fileName, CannedAccessControlList.PublicRead);
}
}
controller
@RestController
@RequestMapping("/oss")
public class OSSController {
@Autowired
private OSSService ossService;
/**
* 上传文件
*
* @param file
* @return
*/
@PostMapping(value = "/uploadFiles")
public String uploadFiles(@RequestParam("file") MultipartFile file) {
return ossService.uploadFile(file, "imgs");
}
/**
* 下载文件
*
* @param fileName
*/
@PostMapping(value = "/exportFile")
public void exportFile(OutputStream os, @RequestParam("fileName") String fileName) {
ossService.exportFile(os, fileName);
}
/**
* 删除文件
*
* @param fileName
*/
@PostMapping(value = "/deleteFile")
public void deleteFile(@RequestParam("fileName") String fileName) {
ossService.deleteFile(fileName);
}
/**
* 查看文件列表
*
* @return
*/
@PostMapping(value = "/listObjects")
public List<String> listObjects() {
return ossService.listObjects();
}
/**
* 判断文件是否存在
*
* @param fileName
*/
@PostMapping(value = "/doesObjectExist")
public boolean doesObjectExist(@RequestParam("fileName") String fileName) {
return ossService.doesObjectExist(fileName);
}
/**
* 获取 url
*
* @param fileName
* @param expSeconds
*/
@PostMapping(value = "/getSingeNatureUrl")
public String getSingeNatureUrl(@RequestParam("fileName") String fileName, @RequestParam("expSeconds") int expSeconds) {
return ossService.getSingeNatureUrl(fileName, expSeconds);
}
/**
* 设置文件访问权限
*
* @param fileName
*/
@PostMapping(value = "/setObjectAcl")
public void setObjectAcl(@RequestParam("fileName") String fileName) {
ossService.setObjectAcl(fileName);
}
}