Spring boot上传文件(图片)到阿里云OSS(直接上传到应用服务器)

Spring boot上传文件(图片)到阿里云OSS(直接上传到应用服务器)

主要思路

上传图片的思路有两种:

  • 第一种是上传到应用服务器,再由应用服务器上传到OSS。这种适合上传的文件较小,较为简单,但文件过大会造成服务器压力变大。

image-20210427214629760

  • 第二种是利用签名直传的方式,较为复杂,但能减轻服务器的压力。

    image-20210427214849576

直接上传到应用服务器的方式

0.导入依赖

除去常规的依赖还需要以下依赖:

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

        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.2</version>
        </dependency>

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
        </dependency>

        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>3.0.2</version>
        </dependency>

1.写配置

这里的配置主要是为了方便后面修改,可以直接利用读取配置文件的方式编写工具类,需要用到这些阿里云的相关参数时直接调用工具类即可。四个主要的属性需要参照自己实际情况来填写。

aliyun.oss.file.endpoint=<endpoint>
aliyun.oss.file.keyid=<keyid>
aliyun.oss.file.keysecret=<keysecret>
aliyun.oss.file.bucketname=<bucketname>

2.写工具类

编写一个工具类,读取配置文件,其中InitializingBean是为了复制给public静态变量,afterPropertiesSet()会在容器加载完后执行。

@Component
public class OssUtil implements InitializingBean {
    @Value("${aliyun.oss.file.endpoint}")
    private String endpoint;
    @Value("${aliyun.oss.file.keyid}")
    private String accessKeyID;
    @Value("${aliyun.oss.file.keysecret}")
    private String accesskeySecret;
    @Value("${aliyun.oss.file.bucketname}")
    private String bucketName;

    public static String END_POINT;
    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;
    public static String BUCKET_NAME;
    @Override
    public void afterPropertiesSet() throws Exception {
        END_POINT = endpoint;
        ACCESS_KEY_ID = accessKeyID;
        ACCESS_KEY_SECRET = accesskeySecret;
        BUCKET_NAME = bucketName;
    }
}

3.编写Controller和Service

完整的包结构:

image-20210427215701846

编写Controller:其中CrossOrigin是为了解决跨域请求的问题,这里会调用service的上传方法,返回一个url,这样,我们就可以把这个url存进数据库了。

@RestController
@RequestMapping("/cat")
@CrossOrigin
public class OSSController {
    @Autowired
    private OSSService ossService;

    @PostMapping("/oss/upload")
    public String upload(@RequestPart("file") MultipartFile file){
        String url = ossService.uploadFile(file);
        return url;
    }
}

编写service:这里只展示实现类

@Service
public class OSSServiceImpl implements OSSService {
    @Override
    public String uploadFile(MultipartFile file) {
        String url = null;
        String endpoint = OssUtil.END_POINT;
        String accessKeyId = OssUtil.ACCESS_KEY_ID;
        String accessKeySecret = OssUtil.ACCESS_KEY_SECRET;
        String bucketName = OssUtil.BUCKET_NAME;
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        try {
            InputStream inputStream = file.getInputStream();
            //获取上传的文件的名字
            String filename = file.getOriginalFilename();
            //随机uuid是为了拼接文件名,防止用户上传两个名字相同的文件后覆盖掉前一个
            UUID uuid = UUID.randomUUID();
            //这里是为了按上传时间分配目录。精确到月
            String s = DateTime.now().toString("yyyy/MM/");
            //拼接成完整的文件名。
            filename = s + uuid + filename;
            //传入三个参数
            ossClient.putObject(bucketName, filename, inputStream);
            //拼接url
            url = "https://" + bucketName + "." + endpoint + "/" + filename;
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            ossClient.shutdown();
        }
        return url;
    }
}

4.测试

启动项目,浏览器访问http://localhost:8080/swagger-ui/ 进行接口测试

上传文件:

image-20210427220716433

上传成功:

image-20210427220814304

阿里云oss控制台就可以看到相应的文件了:

image-20210427220931925

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值