1. 程式人生 > 其它 >阿里雲OSS無法使用圖片URL訪問,訪問時提示下載【已解決】

阿里雲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