開發前的準備:
自己在阿裡雲上申請免費的Oss對象存儲,建立Bucket---讀寫權限選擇公共讀,我開始這裡忘了導緻後來踩了小坑
接下來是代碼中的一些配置:我用的是springboot
1》添加pom依賴:
<!--OSS上傳-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>2.8.3</version>
</dependency>
2》yml配置:
oss:
endpoint: http://oss-cn-hangzhou.aliyuncs.com
accessKeyId: 你自己的---阿裡雲右上角頭像點選選擇可以擷取
accessKeySecret: 你自己的---阿裡雲右上角頭像點選選擇可以擷取
bucketName: tao11140------你自己建立的bucket節點
key: group1/pic-----------目錄字首
webserver: https://tao11140.oss-cn-hangzhou.aliyuncs.com
3》添加配置類:
OssProperties:
@Data
@ConfigurationProperties(prefix = "oss")
public class OssProperties {
private String endpoint;
private String accessKeyId;
private String accessKeySecret;
private String bucketName;
private String key;
private String webserver;
}
OssConfig:
Configuration
@EnableConfigurationProperties(OssProperties.class)
public class OssConfig {
@Autowired
private OssProperties ossProperties;
@Bean
public OSSClient getOSSClient(){
ClientConfiguration conf=new ClientConfiguration();
// Set the maximum number of allowed open HTTP connections
conf.setMaxConnections(1000);
conf.setConnectionTimeout(600000);
conf.setSocketTimeout(600000);
OSSClient client = new OSSClient(ossProperties.getEndpoint(),ossProperties.getAccessKeyId(),ossProperties.getAccessKeySecret(),conf);
return client;
}
}
OssClientUtils:
@Component
public class OssClientUtils {
@Autowired
private OssConfig ossConfig;
@Autowired
private OssProperties ossProperties;
/**
* 上傳圖檔
* @param file
* @param nfixName
* @param schoolId
* @return
*/
public String uploadPic(MultipartFile file, String nfixName, Long schoolId, String module){
String result=""; //傳回圖檔路徑
OSSClient ossClient =null;
String key=assembleOssPath(schoolId,module,nfixName); //目标oss檔案路徑
try {
ossClient=ossConfig.getOSSClient();
PutObjectResult tip=ossClient.putObject(ossProperties.getBucketName(), key, new ByteArrayInputStream(file.getBytes()));
if(tip!=null && !"".equals(tip.getETag())) {
// result = key;
result = ossProperties.getWebserver() + "/" + key;
}
}catch (Exception ex){
ex.printStackTrace();
}
return result;
}
public String uploadPic(MultipartFile file, String nfixName, String module){
String result=""; //傳回圖檔路徑
OSSClient ossClient =null;
String key=assembleOssPath(module,nfixName); //目标oss檔案路徑
try {
ossClient=ossConfig.getOSSClient();
PutObjectResult tip=ossClient.putObject(ossProperties.getBucketName(), key, new ByteArrayInputStream(file.getBytes()));
if(tip!=null && !"".equals(tip.getETag())) {
// result = key;
result = ossProperties.getWebserver() + "/" + key;
}
}catch (Exception ex){
ex.printStackTrace();
}
return result;
}
private List<MultipartFile> getFileList(HttpServletRequest request, String key){
//建立一個通用的多部分解析器
CommonsMultipartResolver multipartResovler = new CommonsMultipartResolver();
//判斷 request 是否有檔案上傳,即多部分請求
if (!multipartResovler.isMultipart(request)) {
//無附件上傳
return null;
}
// 轉型為MultipartHttpRequest:
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
// 獲得檔案:
List<MultipartFile> files = multipartRequest.getFiles(key);
System.out.println(files.size());
return files;
}
public String uploadImage(HttpServletRequest request, String module) {
Map<String, MultipartFile> files = this.getFileMap(request);
String result = "";
if (files == null || files.keySet().size() <=0) {
return result;
}
for(String key : files.keySet()){
MultipartFile file = files.get(key);
// 擷取檔案名
String uploadFileName = file.getOriginalFilename();
if(StringUtils.isBlank(uploadFileName)){
return result;
}
//不帶.的字尾
String nfixName = uploadFileName.substring(uploadFileName.lastIndexOf(".")+1);
result = this.uploadPic(file, nfixName, module);
return result;
}
return null;
}
public Map<String, MultipartFile> getFileMap(HttpServletRequest request){
//建立一個通用的多部分解析器
CommonsMultipartResolver multipartResovler = new CommonsMultipartResolver();
//判斷 request 是否有檔案上傳,即多部分請求
if (!multipartResovler.isMultipart(request)) {
//無附件上傳
return null;
}
// 轉型為MultipartHttpRequest:
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
// 獲得檔案:
Map<String, MultipartFile> files = multipartRequest.getFileMap();
return files;
}
//組裝上傳路徑
private String assembleOssPath(Long schoolId,String ossConstant,String suffix){
return ossProperties.getKey()+schoolId+ossConstant+ UUID.randomUUID().toString().replace("-", "")+"."+suffix;
}
private String assembleOssPath(String ossConstant,String suffix){
return ossProperties.getKey()+ossConstant+ UUID.randomUUID().toString().replace("-", "")+"."+suffix;
}
}
4》測試Controller:
@Api(value="OssController",description="oss上傳檔案測試",tags={"oss上傳檔案測試"})
@RestController
@RequestMapping("oss")
public class OssController {
@Autowired
private OssClientUtils ossClientUtils;
@RequestMapping(value = "uploadPic",method = RequestMethod.POST)
public String uploadOss(HttpServletRequest request,String path) {
return ossClientUtils.uploadImage(request, path);
}
}
至此,代碼已經準備完畢,接下來postman本地模拟上傳圖檔看看:
postman需要這麼傳:
首先傳參需要傳遞需要自定義儲存的路徑,我這裡是test
設定Headers:
選擇上傳檔案:
發送請求後,報錯:
Caused by: java.lang.NoClassDefFoundError: org/apache/commons/fileupload/disk/DiskFileItemFactory
解決:
缺少pom依賴:
<!-- common -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!-- 上傳檔案開始 -->
<dependency>
<groupId>net.sf.staccatocommons</groupId>
<artifactId>commons-io</artifactId>
<version>1.2</version>
</dependency>
<!-- 上傳檔案結束 -->
再次發送請求:
OK圖檔上傳成功,傳回圖檔路徑
浏覽器中通路顯示:
<Error>
<Code>AccessDenied</Code>
<Message>You do not have read permission on this object.</Message>
<RequestId>5D78AA96EBEC9441BEB05BA1</RequestId>
<HostId>tao11140.oss-cn-hangzhou.aliyuncs.com</HostId>
</Error>
神碼,竟然沒有權限???趕緊去阿裡雲背景看了下,圖檔确實是上傳成功了
那麼可能是要設定一個全局的讀取權限
在oss背景的基礎設定中找到讀寫權限,更改為公共讀即可
接下來我嘗試上傳一個apk檔案到oss,大概一兆多的大小,結果報錯:
The field file exceeds its maximum permitted size of 1048576 bytes.
檢視文檔之後,原因可能是springboot限制了單次請求的檔案大小
解決:
Spring Boot1.4版本後配置更改為:
spring.http.multipart.maxFileSize = 10Mb
spring.http.multipart.maxRequestSize=100Mb
Spring Boot2.0之後的版本配置修改為:
spring.servlet.multipart.max-file-size = 10MB
spring.servlet.multipart.max-request-size=100MB
我的yml添加配置如下:如果是想要不限制檔案上傳的大小,那麼就把兩個值都設定為-1就行
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 100MB
之後重新請求上傳apk,上傳成功