• 阿里云OSS无法使用图片URL访问,访问时提示下载【已解决】


    阿里云OSS无法使用图片URL访问,访问时提示下载【已解决】

    阿里云OSS无法使用图片URL访问,访问时提示下载【已解决】_JGYBZX_G的博客-CSDN博客_oss 访问图片

    实现图片上传到oss,解决阿里云OSS无法使用图片URL访问,访问时提示下载,不用申请域名。
    简单图片上传
    实现图片上传到oss,解决阿里云OSS无法使用图片URL访问,访问时提示下载,不用申请域名。
    创建 Bucket
    建立RAM账号 链接: [官方文档](https://help.aliyun.com/document_detail/93720.html).
    根据官方文档 编写简单上传
    填坑环节
    二次修改
    修改文件太大,spring报错的问题
    三次修改
    关于返回路径的问题
    创建 Bucket
    右上方选择创建 Bucket,可以看到下方有很多常用入口

    创建 一般选择默认即可,注意命名规范,此时留意一下读写权限,后边有个坑

    右上角点击 bucket列表 可以查看

    建立RAM账号 链接: 官方文档.
    官方提示 建立RAM账号,因为自己的账号权限太大一旦泄露,就会出现问题,所以需要建立RAM账号,相当于子账号,然后给子账号分配权限,比如本次是实现对象存储。
    创建用户。注意选择编程式访问,用于程序访问

    返回用户列表,点击用户进入设置用户。
    创建 AccessKey,及时记录下来,如果忘记了,可以重新创建


    添加权限(此处指OSS权限)


    根据官方文档 编写简单上传
    用的是先保存到本地然后以文件流的形式上传到OSS,上传方式很多种,这是最简单的
    1
    controller

    @PostMapping("/fileUpload.json")
    public String fileUpload(@RequestParam("file") MultipartFile file) throws FileNotFoundException {
    if (file.isEmpty()) {
    return "上传文件内容为空,请重新选择";
    }
    String tempFilePath = this.getClass().getResource("/").getPath();
    String fileName = file.getOriginalFilename();
    File tempFile = new File(tempFilePath + fileName);
    try {
    file.transferTo(tempFile);
    //return "上传成功" + tempFilePath + fileName;
    } catch (IOException e) {
    e.printStackTrace();
    }
    return ossConfig.fileUpload(fileName, tempFilePath + fileName);
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    package com.jgybzx.config;

    import com.aliyun.oss.OSS;
    import com.aliyun.oss.OSSClientBuilder;
    import com.aliyun.oss.model.ObjectMetadata;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.stereotype.Component;

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    import java.text.SimpleDateFormat;
    import java.util.Date;

    /**
    * @author jgybzx
    * @date 2020/12/21 15:40
    * @description 用于连接阿里 OSS 对象存储的必要条件,放在配置文件中,以ConfigurationProperties方式读取
    */
    @Component
    @ConfigurationProperties(prefix = "oss")
    public class OssConfig {
    /**
    * 使用自己真实的地址
    */
    private String endpoint;
    /**
    * 之前复制的 accessKeyId
    */
    private String accessKeyId;
    /**
    * 之前复制的 accessKeySecret
    */
    private String accessKeySecret;
    /**
    * 自己新建的 bucketName
    */
    private String bucketName;

    /**
    * @param fileName 文件上传时的名字
    * @param tempFilePath 文件保存到本地时的临时目录,用于生产文件流
    * @return
    * @throws FileNotFoundException
    */
    public String fileUpload(String fileName, String tempFilePath) throws FileNotFoundException {
    // 用于在OSS上命名,建议格式 :年月日/文件名.后缀名,此时可以 以时间建立一个文件夹保存上传的图片
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    String transformDate = simpleDateFormat.format(new Date());
    String objectName = transformDate + "/" + System.currentTimeMillis() + "_" + fileName;
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    // 上传文件流。
    InputStream inputStream = new FileInputStream(tempFilePath);

    ossClient.putObject(bucketName, objectName, inputStream);

    // 返回一个带有时间限制的 访问连接,(此处坑很大)
    Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
    String url = ossClient.generatePresignedUrl(bucketName, objectName, expiration).toString();
    // 关闭OSSClient。
    ossClient.shutdown();
    return url.split("\\?")[0];
    }


    /*省略get set*/
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    结果展示


    填坑环节
    文件正常上传,但是返回的地址无法直接访问,一打开就是下载。
    经过百度,出现各种方法,比如映射自己的域名、添加Content-Disposition inline 关键字。标题所示,这个方法不用申请域名,并且不用设置 HTTP头。首先出现让直接下载的情况,怀疑是因为Content-Type = image/jpeg 如果换为 image/jpg 则可以直接预览。
    所以解决方法为 代码中设置 Content-Type 参考链接
    所以代码进行改动
    /**
    * @param fileName 文件上传时的名字
    * @param tempFilePath 文件保存到本地时的临时目录,用于生产文件流
    * @return
    * @throws FileNotFoundException
    */
    public String fileUpload(String fileName, String tempFilePath) throws FileNotFoundException {
    // 用于在OSS上命名,建议格式 :年月日/文件名.后缀名,此时可以 以时间建立一个文件夹保存上传的图片
    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    String transformDate = simpleDateFormat.format(new Date());
    String objectName = transformDate + "/" + System.currentTimeMillis() + "_" + fileName;
    // 创建OSSClient实例。
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    // 设置设置 HTTP 头 里边的 Content-Type
    ObjectMetadata objectMetadata = new ObjectMetadata();
    objectMetadata.setContentType(getcontentType(fileName.substring(fileName.lastIndexOf("."))));
    // 上传文件流。
    InputStream inputStream = new FileInputStream(tempFilePath);
    //ossClient.putObject(bucketName, objectName, inputStream);
    ossClient.putObject(bucketName, objectName, inputStream, objectMetadata);

    // 返回一个有时间的链接,
    Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
    String url = ossClient.generatePresignedUrl(bucketName, objectName, expiration).toString();
    // 关闭OSSClient。
    ossClient.shutdown();
    return url.split("\\?")[0];
    }

    /**
    * 解决问题,直接访问上传的图片地址,会让下载而不是直接访问
    * 设置设置 HTTP 头 里边的 Content-Type
    * txt 格式经过测试,不需要转换 上传之后就是 text/plain。其他未测试
    * 已知 如果 Content-Type = .jpeg 访问地址会直接下载,本方法也是解决此问题
    * @param FilenameExtension
    * @return
    */
    public static String getcontentType(String FilenameExtension) {
    if (FilenameExtension.equalsIgnoreCase(".bmp")) {
    return "image/bmp";
    }
    if (FilenameExtension.equalsIgnoreCase(".gif")) {
    return "image/gif";
    }
    if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
    FilenameExtension.equalsIgnoreCase(".jpg") ||
    FilenameExtension.equalsIgnoreCase(".png")) {
    return "image/jpg";
    }
    if (FilenameExtension.equalsIgnoreCase(".html")) {
    return "text/html";
    }

    if (FilenameExtension.equalsIgnoreCase(".txt")) {
    return "text/plain";
    }
    if (FilenameExtension.equalsIgnoreCase(".vsd")) {
    return "application/vnd.visio";
    }
    if (FilenameExtension.equalsIgnoreCase(".pptx") ||
    FilenameExtension.equalsIgnoreCase(".ppt")) {
    return "application/vnd.ms-powerpoint";
    }
    if (FilenameExtension.equalsIgnoreCase(".docx") ||
    FilenameExtension.equalsIgnoreCase(".doc")) {
    return "application/msword";
    }
    if (FilenameExtension.equalsIgnoreCase(".xml")) {
    return "text/xml";
    }
    return "image/jpg";
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    各种百度之后,访问还是不行,经过思索发现需要设置 Bucket 读写权限
    之前创建Bucket的时候 设置的读写权限为 私有,所以需要设置为 “公共读”,上传的图片默认继承Bucket的权限

    终极大坑。
    进过以上步骤发现还是不能访问,一直要权限,经过了各种搜索无果,思考了整个过程,发现有一步建立RAM账号很特殊。在设置权限的时候发现下边有一个
    Bucket 授权策略
    Bucket Policy 是阿里云 OSS 推出的针对 Bucket 的授权策略,您可以通过 Bucket Policy 授权您的 RAM 子账号,或其他用户的 RAM 子账号,访问您的 Bucket 的指定资源,并限制访问来源等。
    此时问题可能就找到原因了,此时的Bucket访问是用RAM,所以需要对RAM设置授权策略


    二次修改
    修改文件太大,spring报错的问题
    Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.FileUploadBase$SizeLimitExceededException: the request was rejected because its size (216185201) exceeds the configured maximum (104857600)
    1
    配置文件添加配置
    properties写法

    spring.servlet.multipart.max-file-size=500MB
    spring.servlet.multipart.max-request-size=500MB
    1
    2
    yml 写法

    spring:
    servlet:
    multipart:
    max-file-size: 500MB
    max-request-size: 500MB
    1
    2
    3
    4
    5
    三次修改
    关于返回路径的问题
    原来是 调用了ossClient.generatePresignedUrl返回了一个地址,后来发现阿里提供了访问的方法,如果文件的读写权限ACL为公共读,即该文件允许匿名访问,那么文件URL的格式为https://BucketName.Endpoint/ObjectName
    所以只需要修改一下返回值即可

    ————————————————
    版权声明:本文为CSDN博主「JGYBZX_G」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/JGYBZX_G/article/details/111480067

  • 相关阅读:
    对计算机科学与技术专业的认识及未来的规划
    秋季学期学习总结
    自我介绍
    Leetcode每日一题 83. 删除排序链表中的重复元素
    Leetcode每日一题 82. 删除排序链表中的重复元素 II
    Leetcode每日一题 456.132 模式
    Leetcode每日一题 341. 扁平化嵌套列表迭代器
    Leetcode每日一题 191. 位1的个数
    Leetcode每日一题 73. 矩阵置零
    Leetcode每日一题 150. 逆波兰表达式求值
  • 原文地址:https://www.cnblogs.com/zkwarrior/p/16262003.html
Copyright © 2020-2023  润新知