天天看點

springboot內建阿裡OSS上傳檔案

開發前的準備:

自己在阿裡雲上申請免費的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

springboot內建阿裡OSS上傳檔案

設定Headers:

springboot內建阿裡OSS上傳檔案

選擇上傳檔案:

springboot內建阿裡OSS上傳檔案

發送請求後,報錯:

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>
        <!-- 上傳檔案結束 -->
           

 再次發送請求:

springboot內建阿裡OSS上傳檔案

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,上傳成功

至此,springboot內建oss檔案上傳圓滿成功

繼續閱讀