1、引入依赖

<!-- 引入阿里云OSS的SDK依赖 -->
<!-- https://mvnrepository.com/artifact/com.aliyun.oss/aliyun-sdk-oss -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>


2、在application.properties中配置

# 阿里云 OSS
# 不同的服务器,地址不同
aliyun.oss.file.endpoint=oss-cn-hangzhou.aliyuncs.com
aliyun.oss.file.keyid=keyid
aliyun.oss.file.keysecret=keysecret
# bucket可以在控制台创建,也可以使用java代码创建
aliyun.oss.file.bucketname=bucketname
aliyun.oss.file.filehost=filehost
    
/**
	aliyun.oss.file.endpoint:Bucket所在地域对应的Endpoint
	aliyun.oss.file.keyid:阿里云账号AccessKey拥有所有API的访问权限,id
	aliyun.oss.file.keysecret:阿里云账号AccessKey拥有所有API的访问权限,密码
	aliyun.oss.file.bucketname:Bucket名称
	aliyun.oss.file.filehost:在阿里云Bucket下的一级目录名称
*/


3、配置相关变量赋值

package com.example.oss.config.properties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class OssConfigurationProperties 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;

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

    public static String END_POINT;

    public static String ACCESS_KEY_ID;

    public static String ACCESS_KEY_SECRET;

    public static String BUCKET_NAME;

    public static String FILE_HOST;

    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT = this.endpoint;
        ACCESS_KEY_ID = this.keyId;
        ACCESS_KEY_SECRET = this.keySecret;
        BUCKET_NAME = this.bucketName;
        FILE_HOST = this.fileHost;
    }
}


/**
	1、使用 @Value 读取 application.properties 里的配置内容
	2、用 spring 的 InitializingBean 的 afterPropertiesSet 来初始化配置信息,这个方法将在所有的属性被初始化后调用。
	
	建议:可使用 @ConfigurationProperties 去实现以上变量赋值,看起来会比当前代码合理一点。
     
	还有,写完这文章后突然发现,OssConfigurationProperties 既然已经注入到 Spring 容器当中了,
	那其实也可以直接作为 OssServiceImpl 的属性,通过 @Autowired 方式注入。
    代码很久之前写的,你懂的,我不想改。。。

*/


4、控制器OssController

package com.example.oss.controller;

import com.example.common.utils.Result;
import com.example.oss.exception.OssException;
import com.example.oss.service.OssService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.Optional;

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

    @Autowired
    private OssService ossService;

    @PostMapping(value = "/uploadFile2Oss")
    public Result uploadFile2Oss(@RequestParam("file") MultipartFile file) {
        Optional.ofNullable(file).orElseThrow(() -> new OssException("文件不能为空!"));
        String filePath = ossService.uploadFile2Oss(file);
        return Result.ok().message("上传文件到阿里云服务器成功!").data("filePath", filePath);
    }

}


5、业务层OssServiceImpl

package com.example.oss.service.impl;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.example.oss.exception.OssException;
import com.example.oss.service.OssService;
import com.example.oss.config.properties.OssConfigurationProperties;
import org.joda.time.LocalDate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Optional;
import java.util.UUID;

@Service
public class OssServiceImpl implements OssService {

    private static final String[] FILETYPE = {".png", ".jpg", ".bmp", ".gif", ".jpeg"};

    @Override
    public String uploadFile2Oss(MultipartFile file) throws IOException {
        Optional.ofNullable(file).orElseThrow(() -> new OssException("上传的文件不能为空!"));
        // 校验不同浏览器下getOriginalFilename()结果,返回空子符串时表示文件名称有问题
        String fileName = checkFileName(file.getOriginalFilename());
        if (!StringUtils.hasLength(fileName)) {
            throw new OssException("上传的文件名称不能为空!");
        }
        // 上传文件到阿里云服务器,文件成功后返回该文件在阿里云服务器上的路径
        return uploadToALiYun(file, fileName);
    }

    private String checkFileName(String fileName) {
        fileName = Optional.ofNullable(fileName).orElse("");
        int pos = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('/'));
        return pos == -1 ? fileName : fileName.substring(pos + 1);
    }

    private String uploadToALiYun(MultipartFile file, String fileName) throws IOException {
        OSS ossClient = null;
        try {
            // 创建OSSClient实例。
            ossClient = new OSSClientBuilder().build(
                    OssConfigurationProperties.END_POINT,
                    OssConfigurationProperties.ACCESS_KEY_ID,
                    OssConfigurationProperties.ACCESS_KEY_SECRET);

            // 校验上传文件类型
            String fileType = fileName.substring(fileName.lastIndexOf("."));
            if (!Arrays.asList(FILETYPE).contains(fileType)) {
                throw new OssException("暂不支持该类型文件上传!");
            }

            // 校验图片内容是否正确
            BufferedImage image = ImageIO.read(file.getInputStream());
            Optional.ofNullable(image).orElseThrow(() -> new OssException("文件内容不正确!"));

            // 填写本地文件的完整路径。如果未指定本地路径,则默认从示例程序所属项目对应本地路径中上传文件流。
            // 依次填写Bucket名称(例如examplebucket)和Object完整路径(例如exampledir/exampleobject.txt)。Object完整路径中不能包含Bucket名称。
            String currentDateStr = getCurrentDateStr();
            String uuid = UUID.randomUUID().toString();
            String urlPath = OssConfigurationProperties.FILE_HOST.concat("/")
                    .concat(currentDateStr).concat("/")
                    .concat(uuid).concat(fileType);
						
            // 上传文件
            ossClient.putObject(OssConfigurationProperties.BUCKET_NAME, urlPath, file.getInputStream());

            // 文件上传成功后返回该文件在阿里云服务器上的路径
            return "https://".concat(OssConfigurationProperties.BUCKET_NAME).concat(".")
                    .concat(OssConfigurationProperties.END_POINT).concat("/").concat(urlPath);

        } finally {
            // 释放资源
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    private String getCurrentDateStr() {
        return LocalDate.now().toString("yyyy/MM/dd");
    }
}