基于天翼云OOS实现文件存储

1.技术分析

因项目原因必须采用天翼云OOS,而天翼云OOS开发文档简直一团糟。本文将实现基于OOS文件上传功能,若有不足,欢迎留言讨论。闲话不多说,直接上代码。

2.实现详细步骤

  1. 注册天翼云账户开通对象存储、创建容器(具体就不详细说明了)在这里插入图片描述
  2. 因maven中央仓库没有,所以需要手动下载oos-sdk-6.5.0.jar到本地,或者上传到maven私服下,这里放在了本地,项目上线建议放私服。
<dependency>
            <groupId>cn.ctyun</groupId>
            <artifactId>ctyun-sdk-oss</artifactId>
            <version>6.5.0</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/oos-sdk-6.5.0.jar</systemPath>
</dependency>

<dependency>
            <groupId>net.coobird</groupId>
            <artifactId>thumbnailator</artifactId>
            <version>0.4.8</version>
 </dependency>
  1. 配置key
    在这里插入图片描述
  2. 配置yml,endpoint可使用这个
    在这里插入图片描述

3.实现代码

@Data
@Component
@ConfigurationProperties(prefix = "oos.config")
public class OosClientConfig {

    private String accessKey;

    private String secretKey;

    private String endpoint;

    private String bucket;

    @Bean
    public AmazonS3 oosClient() {
        ClientConfiguration clientConfig = new ClientConfiguration();
        // 设置连接的超时时间,单位毫秒
        clientConfig.setConnectionTimeout(30 * 1000);
        // 设置 socket 超时时间,单位毫秒
        clientConfig.setSocketTimeout(30 * 1000);
        clientConfig.setProtocol(Protocol.HTTP); //设置 http
        // 设置 V4 签名算法中负载是否参与签名,关于签名部分请参看《OOS 开发者文档》
        S3ClientOptions options = new S3ClientOptions();
        options.setPayloadSigningEnabled(true);
        // 创建 client
        AmazonS3 oosClient = new AmazonS3Client(
                new PropertiesCredentials(accessKey, secretKey), clientConfig);
        // 设置 endpoint
        oosClient.setEndpoint(endpoint);
        //设置选项
        oosClient.setS3ClientOptions(options);
        return oosClient;
    }
}
@Log4j2
@Service
public class OosService {

    @Autowired
    private OosClientConfig oosClientConfig;

    /**
     * @Desecription: 上传文件
     * @Param:
     * @Return:
     * @Author: yangyu
     * @Date: 2021/8/16 15:29
     */
    public String uploadFile(MultipartFile file, String fileName) {
        InputStream inputStream = null;
        String pathUrl = "";
        try {
            // 文件大小校验
            FileUploadUtils.assertAllowed(file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
            inputStream = file.getInputStream();
            AmazonS3 ossClient = oosClientConfig.oosClient();
            String remoteFilePath = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            String dir = remoteFilePath + "/"; // 用户上传文件时指定的前缀。
            // 创建上传Object的Metadata
            ObjectMetadata objectMetadata = new ObjectMetadata();
            objectMetadata.setCacheControl("no-cache");
            objectMetadata.setHeader("Pragma", "no-cache");
            String path = dir + IdWorker.getIdStr() +"."+ FileUploadUtils.getExtension(file);
            try {
                objectMetadata.setContentLength(inputStream.available());
                // 上传文件
                log.info("开始上传文件到oss");
                ossClient.putObject(oosClientConfig.getBucket(), path, inputStream, objectMetadata);
                // URL url = ossClient.generatePresignedUrl(new GeneratePresignedUrlRequest(oosClientConfig.getBucket(), path));
                String url = generatePresignedUrl(path);
                pathUrl = url;
            } catch (Exception e) {
                log.error("上传文件到oos失败", e.getMessage());
            } finally {
                if (ossClient != null) {
                    ((AmazonS3Client) ossClient).shutdown();
                }
                if (inputStream != null) {
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return pathUrl;
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return null;
    }

    /**
     * @Desecription: 删除文件
     * @Param:
     * @Return:
     * @Author: yangyu
     * @Date: 2021/8/16 15:29
     */
    public boolean deleteFile(String filePath, String fileName) {
        AmazonS3 ossClient = oosClientConfig.oosClient();
        String path = filePath + fileName;
        boolean exist = ossClient.doesBucketExist(oosClientConfig.getEndpoint());
        if (!exist) {
            log.error("从OSS存储删除的文件不存在,path={}", path);
            return false;
        } else {
            try {
                ossClient.deleteObject(oosClientConfig.getEndpoint(), path);
            } catch (Exception e) {
                log.error("从天翼云OSS删除文件出错,path={}", path, e);
                return false;
            } finally {
                if (ossClient != null) {
                    try {
                        ((AmazonS3Client) ossClient).shutdown();
                    } catch (AmazonClientException e) {
                        e.printStackTrace();
                    }
                }
            }
            return true;
        }
    }

    /**
     * @Desecription: 获取文件下载地址 ,并设置过期时间
     * @Param:
     * @Return:
     * @Author: yangyu
     * @Date: 2021/8/24 10:01
     */
    public String generatePresignedUrl(String fileKey) throws ParseException {
        GeneratePresignedUrlRequest request = new
                GeneratePresignedUrlRequest(oosClientConfig.getBucket(), fileKey);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date expireDate = sdf.parse("2031-01-01");
        request.setExpiration(expireDate);
        URL url = oosClientConfig.oosClient().generatePresignedUrl(request);
        return url.toString();
    }

}
@RestController
@RequestMapping("/crcx/attachment")
public class OosController {

    protected final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private OosService oosService;

    @PostMapping("/upload")
    public AjaxResult upload(@RequestParam("file") MultipartFile file) {
        try {
            if (file.isEmpty())
                return AjaxResult.success("上传文件为空");
            ByteArrayInputStream inputStream;
            if (FileUtils.getFileNameEx(file.getOriginalFilename()).equals("jpg") || FileUtils.getFileNameEx(file.getOriginalFilename()).equals("png")) {
                ByteArrayOutputStream outputStreamut = new ByteArrayOutputStream();
                Thumbnails.of(file.getInputStream())
                        .scale(1f) // 值在0到1之间,1f就是原图大小,0.5就是原图的一半大小
                        .outputQuality(0.5f) // 值也是在0到1,越接近于1质量越好,越接近于0质量越差
                        .toOutputStream(outputStreamut);
                inputStream = new ByteArrayInputStream(outputStreamut.toByteArray());
                MultipartFile newFile = new MockMultipartFile(file.getOriginalFilename(), file.getOriginalFilename(), ContentType.APPLICATION_OCTET_STREAM.toString(), inputStream);
                String pathUrl = oosService.uploadFile(newFile, file.getOriginalFilename());
                AjaxResult ajax = AjaxResult.success();
                ajax.put("fileName", file.getOriginalFilename());
                ajax.put("url", pathUrl);
                return ajax;
            } else {
                MultipartFile newFile = new MockMultipartFile(file.getOriginalFilename(), file.getOriginalFilename(), ContentType.APPLICATION_OCTET_STREAM.toString(), file.getInputStream());
                String pathUrl = oosService.uploadFile(newFile, file.getOriginalFilename());
                AjaxResult ajax = AjaxResult.success();
                ajax.put("fileName", file.getOriginalFilename());
                ajax.put("url", pathUrl);
                return ajax;
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new CustomException("文件上传失败");
        }
    }
}

图片压缩部分图片会抛出如下错误

net.coobird.thumbnailator.tasks.UnsupportedFormatException: No suitable ImageReader found for source data.
        at net.coobird.thumbnailator.tasks.io.InputStreamImageSource.read(Unknown Source) ~[thumbnailator-0.4.8.jar:0.4.8]
        at net.coobird.thumbnailator.tasks.SourceSinkThumbnailTask.read(Unknown Source) ~[thumbnailator-0.4.8.jar:0.4.8]
        at net.coobird.thumbnailator.Thumbnailator.createThumbnail(Unknown Source) ~[thumbnailator-0.4.8.jar:0.4.8]
        at net.coobird.thumbnailator.Thumbnails$Builder.toFile(Unknown Source) ~[thumbnailator-0.4.8.jar:0.4.8]

引入webp,便可解决

<dependency>
            <groupId>org.sejda.imageio</groupId>
            <artifactId>webp-imageio</artifactId>
            <version>0.1.6</version>
</dependency>
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐