SpringBoot实现将图片上传到阿里云OSS

阿里云OSS的购买和使用可以参考我的这篇博客:阿里云OSS存储的购买和使用

1、导入相关依赖

 <!--阿里云OSS依赖-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>3.9.1</version>
        </dependency>
        <!--日期处理依赖-->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.1</version>
        </dependency>

2、创建相关配置类

@Configuration
@PropertySource("classpath:aliyun.yaml") //读取配置文件
@ConfigurationProperties(prefix = "aliyun")
@Data
public class AliyunConfig {

    private String endpoint ;
    private String accessKeyId;
    private String accessKeySecret;

    @Bean
    public OSS ossClient(){
        return new OSSClientBuilder().build(endpoint,accessKeyId,accessKeySecret);
    }
    
}

这里需要注意的是endpoint,accessKeyId,accessKeySecret的值是写到了配置文件中,使用@PropertySource注解来读取配置文件

SpringBoot实现将图片上传到阿里云OSS

 

 配置文件我这里使用的是yaml格式,看起来层次更加清晰

SpringBoot实现将图片上传到阿里云OSS

 

 同时还需要使用@ConfigurationProperties(prefix = "aliyun")注解来指定哪个前缀下面的值会被注入到AliyunConfig类的属性中(需要注意的是,该注解注入属性的方式是使用set方法,所以必须为AliyunConfig类中的属性提供set方法,我这里使用了@Data注解来简化开发)

@ConfigurationProperties注解使用的时候需要添加下面的依赖

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

配置文件中的endpoint指的是域名节点,可以在你创建的bucket概览中查看

SpringBoot实现将图片上传到阿里云OSS

 

 accessKeyId和accessKeySecret的获取

1、鼠标放在登录头向上,点击AccessKey管理

SpringBoot实现将图片上传到阿里云OSS

 

 2、点击使用子用户

SpringBoot实现将图片上传到阿里云OSS

 

 3、创建用户

SpringBoot实现将图片上传到阿里云OSS

 

 4、创建成功之后点击用户

SpringBoot实现将图片上传到阿里云OSS

 

 5、点击创建AccessKey

SpringBoot实现将图片上传到阿里云OSS

 

 6、将创建好的信息保存(accessSecret只能通过改方法获取一次,弹框关闭之后再也无法查看了!!!)

SpringBoot实现将图片上传到阿里云OSS

 

 编写上传逻辑代码

1、自定义结果类

@Data
public class PicUploadResult {

    /*
    * 这个类是我自定义的结果类,不一定非要按照这个格式写,里面的属性都可以自己定义
    * */
    
    private String uid; //自定义ID
    private String name;//自定义文件名称
    private String status;//上传结果的状态
    private String response;//上传响应的状态

    public PicUploadResult() {
    }

    public PicUploadResult(String uid, String name, String status, String response) {
        this.uid = uid;
        this.name = name;
        this.status = status;
        this.response = response;
    }
}

 

2、controller

@Controller
@CrossOrigin //我使用的是前后端分离,该注解用来解决跨域问题
@RequestMapping("/picUpload")
public class PicUploadController {

    @Autowired
    private PicUploadService picUploadService;

    @PostMapping()
    @ResponseBody
    public PicUploadResult upload(@RequestParam("file")MultipartFile file){
         return  picUploadService.upload(file);
    }
}

 

3、service层(主要逻辑代码的书写位置)

@Service
public class PicUploadServiceImpl implements PicUploadService {
    //注入OSS对象
    @Autowired
    private OSS oss;
    @Autowired
    private AliyunConfig aliyunConfig;
    //允许上传的格式
    private static final String[] IMAGE_TYPE = new String[]{".bmp", ".jpg", ".jpeg", ".webp", ".gif", ".png"};

    @Override
    public PicUploadResult upload(MultipartFile file) {
        PicUploadResult result = new PicUploadResult();
        //对图片的后缀名做校验
        boolean isLegal = false;
        for (String type : IMAGE_TYPE) {
            if (StringUtils.endsWithIgnoreCase(file.getOriginalFilename(), type)) {
                isLegal = true;
                break;
            }
        }
        if (!isLegal) {
            result.setStatus("error");
            return result;
        }

        //设置文件的路径,getFilePath为封装的自定义路径的方法,在下面
        String fileName = file.getOriginalFilename();
        String filePath = getFilePath(fileName);

        //上传到阿里云
        try {
            //调用阿里云提供的API
            oss.putObject(aliyunConfig.getBucketName(), filePath, new ByteArrayInputStream(file.getBytes()));
        } catch (IOException e) {
            e.printStackTrace();
            result.setStatus("error");
            return result;
        }

        result.setStatus("success");
        result.setName(aliyunConfig.getUrlPrefix() + fileName);
        result.setUid(String.valueOf(System.currentTimeMillis()));

        System.out.println("result = " + result);

        return result;
    }

    //定义生成文件新路径的方法,目录结构:images+年+月+日+xxx.jpg
    private String getFilePath(String sourceFileName) {
        DateTime dateTime = new DateTime();
        return "images" + "/" + dateTime.toString("yyyy") + "/" +
                dateTime.toString("MM") + "/" +
                dateTime.toString("dd") + "/" +
                System.currentTimeMillis() + RandomUtils.nextInt(100, 9999) + "." +
                StringUtils.substringAfterLast(sourceFileName, ".");
    }
}

 

逻辑已经写完了,大家自行测试吧!!!
------------------------------------------------------------------------------------------------------------------------------我是分割线-----------------------------------------------------------------------------------------------------------------------------------------------

把我在实现文件上传时候遇到的坑写出来给大家作参考,避免踩坑

错误一:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'picUploadController':
Unsatisfied dependency expressed through field 'picUploadService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'picUploadServiceImpl': Unsatisfied dependency expressed through field 'oss';
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'oss' defined in class path resource [com/jingzhe/blog/config/AliyunConfig.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate
[com.aliyun.oss.OSS]: Factory method 'oss' threw exception; nested exception is
java.lang.IllegalArgumentException: java.net.URISyntaxException: Illegal character in authority at index 7: http://oss-cn-beijing.aliyuncs.com

 

 这个错误真的是让我懵逼了很长时间,我一直以为是配置类出现了问题,但是翻来覆去的检查都觉得我写的是ok的(事实证明的确是OK的)

为了解决它我疯狂的百度、翻资料,本来就少的头发更是刷刷的往下掉,后来无意间(真的是,缘分这东西太™奇妙了)找到一篇帖子,说的是配置文件中的url路径可能写错了

嗯?!??!!!!0_0.。。。

在我一个字母一个字母翻来覆去的对比之后,终于发现了!!!!!一个不起眼的空格。。。。

SpringBoot实现将图片上传到阿里云OSS

 

 就是他!!!!去掉空格之后,项目成功运行,所以说,大家在遇到错误的时候一定不能心急,仔细一些,有些错误很可能自己就蹦出来了

------------------------------------

错误2:You have no right to access this object because of bucket acl.

这个错误是在测试的时候出现的问题,原因是你所使用的子用户没有被授权。

 SpringBoot实现将图片上传到阿里云OSS

 

 SpringBoot实现将图片上传到阿里云OSS

 

 

添加完成在测试就OK了。至此,文件上传至阿里云告一段落。

祝大家处事不惊,前程似锦,晚安!

 

上一篇:python函数式编程-偏向函数


下一篇:ABAP 删除内表重复数据