IDEA阿里云OSS实现文件上传·解决苍穹外卖图片回显

简单交代配置阿里云OSS的思路

  1. 首先去阿里云开通一个OSS服务,配置好一个自己的Bucket

  2. 在IDEA配置Bucket

  1. 拷贝官网的OSS工具类代码
java 复制代码
package com.sky.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayInputStream;

@Data
@AllArgsConstructor
@Slf4j
public class AliOssUtil {

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

    /**
     * 文件上传
     *
     * @param bytes
     * @param objectName
     * @return
     */
    public String upload(byte[] bytes, String objectName) {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        try {
            // 创建PutObject请求。
            ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(bytes));
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }

        //文件访问路径规则 https://BucketName.Endpoint/ObjectName
        StringBuilder stringBuilder = new StringBuilder("https://");
        stringBuilder
                .append(bucketName)
                .append(".")
                .append(endpoint)
                .append("/")
                .append(objectName);

        log.info("文件上传到:{}", stringBuilder.toString());

        return stringBuilder.toString();
    }
}
  1. OSS工具类对象的创建
java 复制代码
package com.sky.config;

import com.sky.properties.AliOssProperties;
import com.sky.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类,用于创建AliOssUtil对象
 */
@Configuration
@Slf4j
public class OssConfiguration {


    // 通过参数注入的方式,将Oss的配置信息传递进来
    // Bean 如果容器中没有AliOssUtil对象,则创建AliOssUtil对象
    // ConditionalOnBean 表示如果容器中存在AliOssUtil对象,则不创建AliOssUtil对象
    @Bean
    @ConditionalOnMissingBean
    public AliOssUtil aliOssUtil(AliOssProperties aliOssProperties) {
        log.info("开始创建阿里云文件上传工具类对象:{}",aliOssProperties);
        // 创建AliOssUtil对象,并传入配置信息
        return new AliOssUtil(aliOssProperties.getEndpoint(),
                              aliOssProperties.getAccessKeyId(),
                              aliOssProperties.getAccessKeySecret(),
                              aliOssProperties.getBucketName());
    }
}
  1. 在Controller层编写文件上传逻辑
java 复制代码
// Autowired注解的作用:自动将匹配的Bean装配到@Autowired标注的变量、方法或构造函数上。(依赖注入)
    @Autowired
    private AliOssUtil aliOssUtil;


    /**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file) {
        log.info("文件上传接口被调用:{}",file);
        String filePath = null;
        try {
            //  获取原始文件名
            String originalFilename = file.getOriginalFilename();
            // 截取原始文件名的扩展名
            String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 生成新的文件名: UUID + 扩展名
            String newFileName = UUID.randomUUID().toString() + extName;

            // 文件上传请求路径
            filePath = aliOssUtil.upload(file.getBytes(), newFileName);
        }catch(IOException e){
            e.printStackTrace();
            log.error("文件上传失败:{}",e);
            return Result.error(MessageConstant.UPLOAD_FAILED);
        }
       return Result.success(filePath);
    }
  1. 测试(省略,做到这里基本无误了)

接下来就来讲讲文件回显失败的几点调试方向

文件回显失败的原因及其排查方向

1. 检查你文件上传拼接的url是否正确

这一步如果错了,实际上上传就已经错了,更别提回显这方面的事情了

2. 首先,如果你全程跟着苍穹老师写的代码去做,必然会导致文件回显失败,我记得视频里面的代码最后是没有返回文件上传路径的,你可以改一下再尝试

具体的,苍穹老师写的文件上传代码:

问题就出在成功的时候还封装了错误的信息进行返回,你应该要把错误的返回放到catch中,成功后把文件路径放到Result中

java 复制代码
/**
     * 文件上传
     * @param file
     * @return
     */
    @PostMapping("/upload")
    @ApiOperation("文件上传")
    public Result<String> upload(MultipartFile file) {
        log.info("文件上传接口被调用:{}",file);
        try {
            //  获取原始文件名
            String originalFilename = file.getOriginalFilename();
            // 截取原始文件名的扩展名
            String extName = originalFilename.substring(originalFilename.lastIndexOf("."));
            // 生成新的文件名: UUID + 扩展名
            String newFileName = UUID.randomUUID().toString() + extName;

            // 文件上传请求路径
            String filePath  = aliOssUtil.upload(file.getBytes(), newFileName);
        }catch(IOException e){
            e.printStackTrace();
            log.error("文件上传失败:{}",e);
            
        }
       return Result.error(MessageConstant.UPLOAD_FAILED);
    }
3. 接着排查OSS,你得允许你的网页可以访问你的OSS对象存储服务之后才可以拿到文件的访问路径,使用OSS必须设置公共读属性

由于我只是练习程序,不想麻烦所以直接设置了公共读写。但是其实最安全的方式还是配置一个防盗链放行你的网页会比较安全

相关推荐
平行线也会相交2 分钟前
云图库平台(三)——后端用户模块开发
数据库·spring boot·mysql·云图库平台
lxyzcm39 分钟前
深入理解C++23的Deducing this特性(上):基础概念与语法详解
开发语言·c++·spring boot·设计模式·c++23
励碼1 小时前
Spring Security 6.3 权限异常处理实战解析
spring boot
web150854159352 小时前
vue 集成 webrtc-streamer 播放视频流 - 解决阿里云内外网访问视频流问题
vue.js·阿里云·webrtc
m0_748257182 小时前
Spring Boot FileUpLoad and Interceptor(文件上传和拦截器,Web入门知识)
前端·spring boot·后端
lxyzcm3 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
迷糊的『迷』5 小时前
vue-axios+springboot实现文件流下载
vue.js·spring boot
小池先生5 小时前
springboot启动不了 因一个spring-boot-starter-web底下的tomcat-embed-core依赖丢失
java·spring boot·后端
苹果醋37 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行7 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate