SpringBoot接入阿里云oss
1、pom中添加阿里云oss坐标
<?xml version="1.0" encoding="utf-8"?> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.15</version> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <!-- 阿里云OSS --> <dependency> <groupId>com.aliyun.oss</groupId> <artifactId>aliyun-sdk-oss</artifactId> <version>3.10.2</version> </dependency> </dependencies>
2、定义阿里云上传(其他操作操作)结果实体
import lombok.Data; /** * 阿里云上传结果集 * * @author sunguoqiang * @create 2022-07-08 */ @Data public class AliyunOssResult { /** * code:200成功 * code: 400失败 */ private int code; /** * 上传成功的返回url */ private String url; /** * 提示信息 */ private String msg; }
3、yml设置阿里云oss参数、上传文件大小限制
aliyunOss: endpoint: "http://oss-cn-shanghai.aliyuncs.com" accessKeyId: "xxxxxxx" accessKeySecret: "xxxxxxx" bucketName: "xxxxxx" urlPrefix: "http://bucketName.oss-cn-shanghai.aliyuncs.com/" spring: servlet: multipart: max-file-size: 20MB max-request-size: 20MB
4、阿里云oss操作工具类封装
package cc.mrbird.febs.finance.util; import cc.mrbird.febs.finance.domain.dto.AliyunOssResult; import cc.mrbird.febs.finance.exception.FileUploadException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.model.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.io.*; import java.net.URL; import java.util.Date; import java.util.List; /** * @Author: sunguoqiang * @Description: TODO * @DateTime: 2022/8/3 16:23 **/ @Component @Slf4j public class AliyunOSSUtil { @Value("${aliyunOss.endpoint}") private String endpoint; @Value("${aliyunOss.accessKeyId}") private String accessKeyId; @Value("${aliyunOss.accessKeySecret}") private String accessKeySecret; @Value("${aliyunOss.bucketName}") private String bucketName; @Value("${aliyunOss.urlPrefix}") private String urlPrefix; private OSS ossClient; /** * 初始化OssClient */ @PostConstruct public void generateOSS() { OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret); if (ossClient != null) { this.ossClient = ossClient; } else { log.error("OSS对象实例化失败."); throw new RuntimeException("OSS对象实例化失败."); } } /** * 判断阿里云bucket下是否存在filePath文件夹,不存在则创建 * * @param filePath */ public void isExistAndCreateFolder(String filePath) { if (!isExists(filePath)) { boolean mkdirs = createFolder(filePath); if (!mkdirs) { throw new FileUploadException("附件文件夹创建失败!"); } } } /** * 上传文件,以IO流方式 * * @param inputStream 输入流 * @param objectName 唯一objectName(在oss中的文件名字) */ public AliyunOssResult upload(InputStream inputStream, String objectName) { AliyunOssResult aliyunOssResult = new AliyunOssResult(); try { // 上传内容到指定的存储空间(bucketName)并保存为指定的文件名称(objectName)。 PutObjectResult putObject = ossClient.putObject(bucketName, objectName, inputStream); // 关闭OSSClient。 ossClient.shutdown(); aliyunOssResult.setCode(200); aliyunOssResult.setUrl(urlPrefix + objectName); aliyunOssResult.setMsg("上传成功"); } catch (Exception e) { e.printStackTrace(); aliyunOssResult.setCode(400); aliyunOssResult.setMsg("上传失败"); } return aliyunOssResult; } /** * 获取oss文件 * * @param folderName * @return */ public OSSObject get(String folderName) { OSSObject ossObject = ossClient.getObject(bucketName, folderName); return ossObject; } /** * 删除OSS中的单个文件 * * @param objectName 唯一objectName(在oss中的文件名字) */ public void delete(String objectName) { try { ossClient.deleteObject(bucketName, objectName); // 关闭OSSClient。 ossClient.shutdown(); } catch (Exception e) { e.printStackTrace(); } } /** * 批量删除OSS中的文件 * * @param objectNames oss中文件名list */ public void delete(List<String> objectNames) { try { // 批量删除文件。 DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(objectNames)); List<String> deletedObjects = deleteObjectsResult.getDeletedObjects(); // 关闭OSSClient。 ossClient.shutdown(); } catch (Exception e) { e.printStackTrace(); } } /** * 获取文件临时url * * @param objectName oss中的文件名 * @param effectiveTime 有效时间(ms) */ public String getUrl(String objectName, long effectiveTime) { // 设置URL过期时间 Date expiration = new Date(new Date().getTime() + effectiveTime); GeneratePresignedUrlRequest generatePresignedUrlRequest; generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectName); generatePresignedUrlRequest.setExpiration(expiration); URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest); return url.toString(); } /** * oss拷贝文件 * * @param sourcePath * @param targetPath */ public void copyFileSourceToTarget(String sourcePath, String targetPath) throws FileNotFoundException { try { CopyObjectResult copyObjectResult = ossClient.copyObject(bucketName, sourcePath, bucketName, targetPath); } catch (Exception e) { throw new FileUploadException("文件转移操作异常."); } } /** * 根据文件路径获取输出流 * * @param filePath * @return * @throws IOException */ public InputStream getInputStream(String filePath) throws IOException { if (filePath == null || filePath.isEmpty()) { log.error("方法[getInputStream]参数[filePath]不能为空."); return null; } OSSObject object = ossClient.getObject(bucketName, filePath); InputStream input = object.getObjectContent(); byte[] bytes = toByteArray(input); return new ByteArrayInputStream(bytes); } /** * InputStream流转byte数组 * * @param input * @return * @throws IOException */ private static byte[] toByteArray(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] buffer = new byte[input.available()]; int n = 0; while (-1 != (n = input.read(buffer))) { output.write(buffer, 0, n); } return output.toByteArray(); } /** * 创建文件夹 * * @param folderName * @return */ private Boolean createFolder(String folderName) { if (folderName == null || folderName.isEmpty()) { log.error("方法[createFolder]参数[folderName]不能为空."); return false; } // 防止folderName文件夹因为末尾未加【/】导致将目录当做文件创建 if (!folderName.substring(folderName.length() - 1).equals("/")) { folderName = folderName + "/"; } // 创建文件夹 try { ossClient.putObject(bucketName, folderName, new ByteArrayInputStream(new byte[0])); log.info("附件文件夹[" + folderName + "]创建成功."); return true; } catch (Exception e) { log.error("附件文件夹[" + folderName + "]创建失败."); return false; } } /** * 判断文件夹是否存在 * * @param folderName * @return */ private Boolean isExists(String folderName) { return ossClient.doesObjectExist(bucketName, folderName); } /** * 根据文件路径获取File * * @param filePath * @return * @throws IOException */ public File getFile(String filePath) throws IOException { if (filePath == null || filePath.isEmpty()) { log.error("方法[getFile]参数[filePath]不能为空."); return null; } File file = new File(filePath); InputStream inputStream = getInputStream(filePath); copyInputStreamToFile(inputStream, file); return file; } /** * InputStream -> File * * @param inputStream * @param file * @throws IOException */ private static void copyInputStreamToFile(InputStream inputStream, File file) throws IOException { try (FileOutputStream outputStream = new FileOutputStream(file)) { int read; byte[] bytes = new byte[1024]; while ((read = inputStream.read(bytes)) != -1) { outputStream.write(bytes, 0, read); } } } }
5、测试
import com.example.demo.util.AliyunOSSUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.util.UUID; @RestController @RequestMapping("/file") public class FileController { @Autowired private AliyunOSSUtil aliyunOSSUtil; @RequestMapping(value = "/uploadFile") public @ResponseBody Object uploadFile(@RequestParam(value = "file", required = false) MultipartFile file, String strPath) throws IOException { String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") + 1); String objectName = strPath+"/"+ UUID.randomUUID().toString()+"."+suffix; return aliyunOSSUtil.upload(file.getInputStream(),objectName); } }