阿里云OSS实现图片上传(后端接口)

文章介绍了如何开通阿里云OSS服务,配置Java环境以上传文件,包括创建AccessKey,安装SDK,修改配置,以及通过OSSController和服务层实现文件上传。还提出了两个改进措施,一是添加随机值避免文件覆盖,二是按日期对文件进行分类管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、阿里云oss服务开通

去阿里云官网开通“对象存储OSS”服务
在这里插入图片描述
点击免费试用:
在这里插入图片描述
点击立即试用即可
在这里插入图片描述

  1. 进入管理控制台
    在这里插入图片描述

    (1). 使用oss,创建bucket
    在这里插入图片描述
    (2)
    在这里插入图片描述
    在这里插入图片描述
    完成创建

2、java操作阿里云oss,上传文件到阿里云oss

1. 创建操作阿里云oss许可证

在这里插入图片描述
在这里插入图片描述
新建的子用户AccessKey配置相应的管理对象存储服务(OSS)权限。
在这里插入图片描述
不加的话,会报com.aliyun.oss.OSSException: You have no right to access this object because of bucket acl.别问我是怎么知道的呜呜呜

将创建出的AccessKeyId和AccessKeySecret导出并保存到本地,方便以后使用

2. 安装SDK

在Maven工程中使用OSS Java SDK,只需在pom.xml中加入相应依赖即可。以3.15.1版本为例,在中加入如下内容:

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.1.0</version>
</dependency>

 <dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
</dependency>
<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.18</version>
</dependency>

3.修改配置文件

将endpoint及下面的配置写入你自己的

aliyun:
  oss:
    file:
      endpoint: 
      keyid: 
      keysecret:
#        bucket可以由控制台创建,也可以使用java代码创建
      bucketname:

有可能你的OSS放在一个单独的子模块中,该子模块只做上传到OSS这一个功能,以至于启动类在启动时,去找数据库配置,由于找不到数据库配置,会报错。

解决方法是在启动类添加属性,默认不去加载数据库配置,如下:
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)

还需要设置文件上传最大限制,因为springboot对文件上传有默认最大限制,即最大可支持1MB的文件大小,在单个请求中最多可容纳10Mb的文件数据。当你传输的文件大于1MB,就会报👇

The field file exceeds its maximum permitted size of 1048576 bytes.

Spring Boot 2.0版本及以上,配置如下:具体设置文件上限大小就依你们实际需求而定,我只是举个例子

spring:
  application:
    name: service
  servlet:
    multipart:
      max-file-size: 100MB
      max-request-size: 100MB

4.创建常量类,读取配置文件中的内容

@Component
public class ConstantPropertiesUtil implements InitializingBean {
//    读取配置文件内容

    @Value("${aliyun.oss.file.endpoint}")
    private String endpoint;

    @Value("${aliyun.oss.file.keyid}")
    private String keyId;

    @Value("${aliyun.oss.file.keysecret}")
    private String keySecret;

    @Value("${aliyun.oss.file.bucketname}")
    private String bucketName;

    public static String END_POINT;

    public static String KEY_ID;

    public static String KEY_SECRET;

    public static String BUCKET_NAME;

    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT = endpoint;

        KEY_ID = keyId;

        KEY_SECRET = keySecret;

        BUCKET_NAME = bucketName;
    }
}

由于实现了InitializingBean这个接口,当读取完配置文件中的数据后,就会调用afterPropertiesSet方法,将属性暴露出去,供其他类使用

5、OssController

@RestController
@RequestMapping("/oss/fileoss")
public class OssController {

    @Autowired
    private OssService ossService;

    @PostMapping
    public ResultUtil uploadOssFile(@RequestBody MultipartFile file){

        /**返回上传到oss的路径*/
        String url = ossService.uploadFileAvatar(file);

        return ResultUtil.success(url);
    }
}
@Data
public class ResultUtil {

    private String code;

    private String message;

    private  Object data;
    public static  ResultUtil success(Object data){
        ResultUtil resultUtil = new ResultUtil();
        resultUtil.setCode("200");
        resultUtil.setMessage("请求成功");
        resultUtil.setData(data);
        return resultUtil;
    }
}


6、OssService

public interface OssService {
    /**上传头像到oss*/
    String uploadFileAvatar(MultipartFile multipartFile);
}

7、OssServiceImpl

@Service
public class OssServiceImpl implements OssService {


    @Override
    public String uploadFileAvatar(MultipartFile multipartFile) {

        String endpoint = ConstantPropertiesUtil.END_POINT;
        String accessKeyId = ConstantPropertiesUtil.ACCESS_KEY_ID;
        String accessKeySecret = ConstantPropertiesUtil.ACCESS_KEY_SECRET;
        // 填写Bucket名称
        String bucketName = ConstantPropertiesUtil.BUCKET_NAME;
        /** 创建OSSClient实例。*/
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
       try {
            

           /** 获取上传文件输入流*/
           InputStream inputStream = multipartFile.getInputStream();

           /**获取文件名称*/
           String filename = multipartFile.getOriginalFilename();

           /**调用oss方法实现上传*/
           //第一个参数 Bucket名称
           //第二个参数 上传到oss文件路径或文件名称
           //第三个参数 上传文件输入流
           ossClient.putObject(bucketName, filename, inputStream);

           /** 返回上传到阿里OSS的路径*/
           String url = "https://".concat(bucketName).concat(".").concat(endpoint).concat("/").concat(filename);

           return url;
       }catch (Exception e){
            e.printStackTrace();
            return null;
       }finally {
           if (ossClient != null) {
               ossClient.shutdown();
           }
       }
    }
}

postman测试:
在这里插入图片描述

可以看到,已经上传成功。
在这里插入图片描述

8、改进

1. 多次上传相同名称文件,会造成最后一次上传把之前上传文件覆盖

改进方法:在文件名称添加随机唯一值,让每个文件名称不同

  			/**产生随机值*/
           String uuid = UUID.randomUUID().toString().replaceAll("-", "");
           filename = filename.concat(uuid);

2. 把文件进行分类管理

改进方法:根据日期进行分类,实现年月日分类
如果ossClient.putObject中的第二个参数形式为aa/bb/1.jpg,则上传到OSS后,OSS会创建aa/bb目录。

			/**把文件按照日期进行分类*/
           String datePath = new DateTime().toString("yyyy/MM/dd");
           filename = datePath.concat("/").concat(filename);

还是传之前的图片,结果👇:

在这里插入图片描述

### 阿里云OSS上传图片不显示的原因分析 当遇到阿里云OSS上传图片后无法正常显示的情况时,可能涉及多个方面的问题。以下是常见的原因及对应的解决方案: #### 1. 文件权限设置不当 如果文件的访问权限未被正确配置,则可能导致外部无法访问该文件。默认情况下,新上传的对象可能是私有的。 ```java // 设置文件为公共读取权限 PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectName, file); putObjectRequest.setCannedAcl(CannedAccessControlList.PublicRead); // 设置公开读权限 ossClient.putObject(putObjectRequest); ``` #### 2. URL路径错误 确保用于展示图片的URL地址是正确的,并且包含了Bucket名称和地区信息。可以通过调用`generatePresignedUrl()`来生成临时链接[^4]。 ```java // 获取带签名的URL GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, objectName); request.setExpiration(expirationDate); URL url = ossClient.generatePresignedUrl(request); System.out.println(url.toString()); ``` #### 3. 图片格式或编码问题 确认上传过程中没有改变原始图像的内容类型(Content-Type),这会影响浏览器如何解析并渲染这些资源。 ```java // 明确指定MIME类型 InputStream inputStream = ...; String contentType = "image/jpeg"; // 或其他合适的媒体类型 PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, key, inputStream).withContentType(contentType)); ``` #### 4. CDN缓存影响 对于启用了CDN加速的服务端口来说,有时候即使更新了源站上的内容,在前端仍然看不到最新的版本。此时可以尝试刷新CDN节点中的静态资源缓存[^1]。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值