文件(图片)上传-阿里云OSS的使用

阿里文档地址:https://help.aliyun.com/document_detail/196063.htm?spm=a2c4g.11186623.2.7.20dd2345yYW7fu#concept-2013568

您可以通过OSS控制台完成常见的基础操作,例如创建存储空间(Bucket)、上传和下载文件(Object)等。

所有的前提都是创建阿里账号,然后开通OSS服务,再创建存储空间bucket
举个例子

上传文件(最简单的一种,小文件的上传)

https://help.aliyun.com/document_detail/84781.htm?spm=a2c4g.11186623.2.2.71f07a74kZhE3G#concept-84781-zh

Endpoint 这个是bucket所在区域的 oss-cn-shenzhen.aliyuncs.com
bucketName:ly-upload-service01

用户登录名称 liangchao@1482895749648131.onaliyun.com
AccessKey ID LTAI5tN5vJWYAs96jWgcvWKV
AccessKey Secret 7D8I3DkOVKob0G7MQasXPK1ZlWKWPY

<!-- 1、集成阿里云OSS -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.6.0</version>
        </dependency>
public void test() {
    // 创建OSSClient实例
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    // 创建putObjectRequest对象
    // 参数一是存储空间bucket名字;参数二,是存储位置,自定义;参数三,是要上传的文件位置
    PutObjectRequest putObjectRequest = new PutObjectRequest("ly-upload-service01", "temp/上传文件.txt", new File("E:\\temp\\上传文件.txt"));
    ossClient.putObject(putObjectRequest);
    ossClient.shutdown();
}

ObjectMetadata metadata = new ObjectMetadata(); 可以通过这个对象来设置上传文件的大小访问权限等等
    metadata.setXXX()
    putObjectRequest.setMetadata(metadata);

例子:

<!-- 1、集成阿里云OSS -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.6.0</version>
        </dependency>
spring:
  datasource:
    druid:
      url: jdbc:mysql://localhost:3306/kaopuren?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=CONVERT_TO_NULL&useSSL=false&serverTimezone=Asia/Shanghai
      username: root
      password: root
      driver-class-name: com.mysql.cj.jdbc.Driver
      # 连接池配置
      initial-size: 5
      min-idle: 5
      max-active: 20
      # 连接超时时间
      max-wait: 30000
      #配置检监控可以关闭的空闲连接间隔时间
      time-between-eviction-runs-millis: 60000
      # 配置连接在池中的最小生存时间
      min-evictable-idle-time-millis: 300000
  redis:
    host: 127.0.0.1
    port: 6379
    password: root
  servlet:
    multipart:   # 配置上传文件的大小
      enabled: true
      max-file-size: 100MB
      max-request-size: 20MB
      file-size-threshold: 20MB


aliyun:
  oss:
    file:
      endpoint: oss-cn-shenzhen.aliyuncs.com
      keyid: LTAI5LxxxxxxxxxxxxxxAUrji3TaX
      keysecret: mMnIDIgxxxxxxxxxxxxxxxxxxnIDucoAZO
      bucketname: ly-xxxx-xxxxx
@Service
@Slf4j
public class AliyunOssServiceImpl implements AliyunOssService {

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    String endpoint = AliyunOssProperties.END_POINT;
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = AliyunOssProperties.ACCESS_KEY_ID;
    String accessKeySecret = AliyunOssProperties.ACCESS_KEY_SECRET;
    //块名
    String bucketName=AliyunOssProperties.BUCKET_NAME;


/**
     * 上传到oss
     *
     * @param file 文件对象
     * @return
     */

    @Override
    public String uploadFileAvatar(MultipartFile file) {
        String originalFilename = "";
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
            InputStream inputStream = file.getInputStream();
            //获取文件真实名称
            originalFilename = file.getOriginalFilename();
            //重命名,防止相同文件出现覆盖 生成的f4f2e1a3-391a-4d5a-9438-0c9f5d27708=》需要替换成f4f2e1a3391a4d5a94380c9f5d27708c
            String uuid = this.getRandomNum3();
            //新的文件名
            originalFilename=uuid+"_"+originalFilename;
            //2、把文件按照日期进行分类
            // 2021/6/30
            String datePath = new DateTime().toString("yyyy/MM/dd");
            //拼接 021/6/30/1.jpg
            originalFilename=datePath+"/"+originalFilename;
            // oss实现上传文件
            //第一个参数:Bucket名称
            //第二个参数:上传到oss文件路径和文件名称 /zhz/avatar.txt
            ossClient.putObject(bucketName, originalFilename, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();

            //把上传之后文件路径返回
            //需要把上传到阿里云oss路径手动拼接出来->https://zhz-mail.oss-cn-beijing.aliyuncs.com/WechatIMG19.jpeg
            String url="https://"+bucketName+"."+endpoint+"/"+originalFilename;
            return url;
        } catch (Exception e) {
            log.error(originalFilename+"文件上传失败:{}",e);
            return ResultEnum.UPLOAD_FAIL.getMessage();
        }
    }

/**
     * 生产3位数的随机数
     */
    public String getRandomNum3(){
        Random random = new Random();
        int x = random.nextInt(899);
        return x+100+"";
    }

}


注意:

1.假如你上次后返回的url,只能查看文件而不能下载,那可能是你的bucket没设置对

一般情况下,使用自定义域名通过浏览器访问OSS内存储的文件时,仅图片和网页文件支持预览,其他类型文件均会直接下载。

将OSS文件配置成访问即下载的形式可以参考下文档:https://help.aliyun.com/document_detail/171120.html

2. 此时你上传的文件只能通过url下载,不能查看

想要查看按照下面修改

package com.zykj.zycxapplet.service.impl;

import cn.hutool.core.date.DateTime;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.GetObjectRequest;

import com.aliyun.oss.model.ObjectMetadata;
import com.zykj.zycxapplet.common.exception.BizException;
import com.zykj.zycxapplet.config.AliyunOssProperties;
import com.zykj.zycxapplet.service.AliyunOssService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Random;


/**
 * @author lc
 * @version 1.0
 * @date 2021/12/27 14:58
 */

@Service
@Slf4j
public class AliyunOssServiceImpl implements AliyunOssService {

    // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
    String endpoint = AliyunOssProperties.END_POINT;
    // 阿里云账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维,请登录RAM控制台创建RAM用户。
    String accessKeyId = AliyunOssProperties.ACCESS_KEY_ID;
    String accessKeySecret = AliyunOssProperties.ACCESS_KEY_SECRET;
    //块名
    String bucketName = AliyunOssProperties.BUCKET_NAME;


    /**
     * 上传到oss
     *
     * @param file 文件对象
     * @return
     */

    @Override
    public String uploadFileAvatar(MultipartFile file) {
        String originalFilename = "";
        try {
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
            // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
            InputStream inputStream = file.getInputStream();
            //获取文件真实名称
            originalFilename = file.getOriginalFilename();
            //重命名,防止相同文件出现覆盖 生成的f4f2e1a3-391a-4d5a-9438-0c9f5d27708=》需要替换成f4f2e1a3391a4d5a94380c9f5d27708c
            String uuid = this.getRandomNum3();
            //新的文件名
            originalFilename = uuid + "_" + originalFilename;
            //2、把文件按照日期进行分类
            // 2021/6/30
            String datePath = new DateTime().toString("yyyy/MM/dd");
            //拼接 021/6/30/1.jpg
            originalFilename = datePath + "/" + originalFilename;

            ObjectMetadata objectMetadata = new ObjectMetadata(); -----------------------新增
            objectMetadata.setContentType(getcontentType(originalFilename.substring(originalFilename.lastIndexOf(".")))); -------------------------新增


            // oss实现上传文件
            //第一个参数:Bucket名称
            //第二个参数:上传到oss文件路径和文件名称 /zhz/avatar.txt
            ossClient.putObject(bucketName, originalFilename, inputStream, objectMetadata);  --------------------- 参数
            // 关闭OSSClient。
            ossClient.shutdown();

            //把上传之后文件路径返回
            //需要把上传到阿里云oss路径手动拼接出来->https://zhz-mail.oss-cn-beijing.aliyuncs.com/WechatIMG19.jpeg
            String url = "https://" + bucketName + "." + endpoint + "/" + originalFilename;
            return url;
        } catch (Exception e) {
            log.error(originalFilename + "文件上传失败:{}", e);
            throw new BizException("文件上传失败:"+e.getMessage());
        }
    }

    /**
     * 生产3位数的随机数
     */
    public String getRandomNum3() {
        Random random = new Random();
        int x = random.nextInt(899);
        return x + 100 + "";
    }

    /**
     * 解决问题,直接访问上传的图片地址,会让下载而不是直接访问
     * 设置设置 HTTP 头 里边的 Content-Type
     * txt 格式经过测试,不需要转换 上传之后就是 text/plain。其他未测试
     * 已知  如果 Content-Type = .jpeg 访问地址会直接下载,本方法也是解决此问题
     * @param FilenameExtension
     * @return
     */
    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }

        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LC超人在良家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值