SpringBoot使用阿里雲oss實現文件上傳


一、對象存儲OSS

1、開通“對象存儲OSS”服務

(1)申請阿里雲賬號
(2)實名認證
(3)開通“對象存儲OSS”服務
(4)進入管理控制台

2、創建Bucket

Bucket名稱:javalimb-file

地域:華北2(北京)

存儲類型:標准存儲

同城冗余存儲:關閉

版本控制:不開通

讀寫權限:公共讀

服務器加密方式:無

實時日志查詢:不開通

定時備份:不開通

3、創建AccessKey

 

阿里雲幫助文檔地址

https://help.aliyun.com/?spm=a2c4g.11186623.6.538.6cb923458Rfc7f

阿里雲對象存儲OSS地址

https://help.aliyun.com/document_detail/31883.html?spm=a2c4g.11186623.6.595.385114a0f8JyvT

阿里雲javaSDK文件上傳地址

https://help.aliyun.com/document_detail/32013.html?spm=a2c4g.11186623.6.934.5ce314a0xWEkf2

文件上傳參照地址

https://help.aliyun.com/document_detail/84781.html?spm=a2c4g.11186623.6.935.59df14a0eK7bAr

使用SDK需要先安裝,具體可以參照阿里雲官方文檔。

案例1(vue+springboot圖片上傳)

pom文件依賴

<dependencies>
        <!-- 阿里雲oss依賴 -->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
        </dependency>

        <!-- 日期工具欄依賴 -->
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
    </dependencies>

yml文件

 1 server:
 2   port: 9120
 3 
 4 spring:
 5   profiles:
 6     # 環境設置
 7     active: dev
 8 
 9   application:
10     # 服務名
11     name: service_oss
12 aliyun:
13   oss:
14     endpoint: oss-cn-beijing.aliyuncs.com
15     keyId: xxxx
16     keySecret: Vxxxx
17     bucketname: exxxx
18 #阿里雲 OSS
19 #不同的服務器,地址不同
20 #  aliyun.oss.file.endpoint=oss-cn-beijing.aliyuncs.com
21 #  aliyun.oss.file.keyid=xxxxxxxx
22 #  aliyun.oss.file.keysecret=dddddddddd
23 #
24 #  # nacos服務地址
25 #  spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
26 #
27 #  #bucket可以在控制台創建,也可以使用java代碼創建
28 #  aliyun.oss.file.bucketname=edu8806

讀取配置文件的類

 1 package com.stu.service.oss.utils;
 2 
 3 import lombok.Data;
 4 import org.springframework.boot.context.properties.ConfigurationProperties;
 5 import org.springframework.stereotype.Component;
 6 
 7 /******************************
 8  * 用途說明:從配置文件讀取變量
 9  * 作者姓名: Administrator
10  * 創建時間: 2022-05-03 1:12
11  ******************************/
12 @Data
13 @Component
14 @ConfigurationProperties(prefix = "aliyun.oss")
15 public class OssProperties {
16 
17     private String endpoint;
18     private String keyId;
19     private String keySecret;
20     private String bucketname;
21 }

讀取配置文件的類(另一種寫法,這里下邊沒有用到)

 1 package com.stu.oss.utils;
 2 
 3 import org.springframework.beans.factory.InitializingBean;
 4 import org.springframework.beans.factory.annotation.Value;
 5 import org.springframework.stereotype.Component;
 6 
 7 //項目啟動,spring接口,spring加載之后,執行接口一個方法
 8 @Component
 9 public class ConstantPropertiesUtil implements InitializingBean {
10 
11     //讀取配置文件的內容
12 
13     @Value("${aliyun.oss.file.endpoint}")
14     private String endpoint;
15     @Value("${aliyun.oss.file.keyid}")
16     private String keyid;
17     @Value("${aliyun.oss.file.keysecret}")
18     private String keysecret;
19     @Value("${aliyun.oss.file.bucketname}")
20     private String bucketname;
21 
22     //定義一些靜態常量
23     public  static String END_POINT;
24     public  static String KEY_ID;
25     public  static String KEY_SECRET;
26     public  static String BUCKET_NAME;
27 
28     //上邊賦值完成后,會執行afterPropertiesSet方法,這是spring機制
29     @Override
30     public void afterPropertiesSet() throws Exception {
31         END_POINT = endpoint;
32         KEY_ID = keyid;
33         KEY_SECRET = keysecret;
34         BUCKET_NAME = bucketname;
35 
36 
37     }
38 }

controller文件

 1 package com.stu.service.oss.controller;
 2 
 3 import com.stu.service.base.result.R;
 4 import com.stu.service.oss.service.FileService;
 5 import lombok.extern.slf4j.Slf4j;
 6 import org.springframework.beans.factory.annotation.Autowired;
 7 import org.springframework.web.bind.annotation.PostMapping;
 8 import org.springframework.web.bind.annotation.RequestMapping;
 9 import org.springframework.web.bind.annotation.RestController;
10 import org.springframework.web.multipart.MultipartFile;
11 
12 /******************************
13  * 用途說明:
14  * 作者姓名: Administrator
15  * 創建時間: 2022-05-03 2:22
16  ******************************/
17 @RestController
18 @RequestMapping("admin/oss/file")
19 @Slf4j
20 public class FIleController {
21 
22     @Autowired
23     private FileService fileService;
24 
25     @PostMapping("upload")
26     public R upload(MultipartFile file) {
27            String url = fileService.upload(file);
28             return R.ok().data("url", url);
29     }
30 
31 }

service接口

 1 package com.stu.service.oss.service;
 2 
 3 import org.springframework.web.multipart.MultipartFile;
 4 
 5 public interface FileService {
 6 
 7     /***********************************
 8      * 用途說明:文件上傳
 9      * 返回值說明: java.lang.String
10      ***********************************/
11     String upload(MultipartFile file);
12 }

service實現類

endPoint,accessKeyId,accessKeySecret,bucketName的取值來源如下

 

  1 package com.stu.service.oss.service.impl;
  2 
  3 import com.aliyun.oss.ClientException;
  4 import com.aliyun.oss.OSS;
  5 import com.aliyun.oss.OSSClientBuilder;
  6 import com.aliyun.oss.OSSException;
  7 import com.stu.service.oss.service.FileService;
  8 import com.stu.service.oss.utils.OssProperties;
  9 import org.joda.time.DateTime;
 10 import org.springframework.beans.factory.annotation.Autowired;
 11 import org.springframework.stereotype.Service;
 12 import org.springframework.web.multipart.MultipartFile;
 13 
 14 import java.io.IOException;
 15 import java.io.InputStream;
 16 import java.util.UUID;
 17 
 18 /******************************
 19  * 用途說明:文件上傳
 20  * 作者姓名: Administrator
 21  * 創建時間: 2022-05-03 1:26
 22  ******************************/
 23 @Service
 24 public class FileServiceImpl implements FileService {
 25 
 26     @Autowired
 27     private OssProperties ossProperties;
 28 
 29     @Override
 30     public String upload(MultipartFile file) {
 31         // Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
 32         String endPoint = ossProperties.getEndpoint();
 33         // 阿里雲賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM用戶進行API訪問或日常運維,請登錄RAM控制台創建RAM用戶。
 34         String accessKeyId = ossProperties.getKeyId();
 35         String accessKeySecret = ossProperties.getKeySecret();
 36         // 填寫Bucket名稱,例如examplebucket。
 37         String bucketName = ossProperties.getBucketname();
 38         /*// 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
 39         //獲取當前日期 joda-time
 40         String datePath = new DateTime().toString("yyyy/MM/dd");
 41         //1.文件名稱添加一個唯一值
 42         String uuid = UUID.randomUUID().toString().replace("-", "");
 43         orginalFileName = uuid + orginalFileName;
 44         String fileExtention = orginalFileName.substring(orginalFileName.lastIndexOf("."));
 45         String objectName = module + "/" + datePath + orginalFileName + fileExtention;*/
 46 
 47         // 創建OSSClient實例。
 48         OSS ossClient = new OSSClientBuilder().build(endPoint, accessKeyId, accessKeySecret);
 49         String url = null;
 50         // 填寫本地文件的完整路徑。如果未指定本地路徑,則默認從示例程序所屬項目對應本地路徑中上傳文件流。
 51         InputStream inputStream = null;
 52         try {
 53             //獲取上傳文件輸入流
 54             inputStream = file.getInputStream();
 55             //調用oss方法實現上傳
 56             //第一個參數 Bucket名稱
 57             //第二個參數,上傳到oss文件路徑和文件名稱   A/B/圖片.jpg
 58             //第三個參數,上傳文件輸入流
 59             //獲取文件名稱
 60             // test.png
 61             String fileName = file.getOriginalFilename();
 62             //1.文件名稱添加一個唯一值
 63             //80b8fbf76d5140f9b33917f883533cc3
 64             String uuid = UUID.randomUUID().toString().replace("-", "");
 65             fileName = uuid + fileName;
 66             //2.把文件安裝日期進行分類
 67             //2021/05/20/圖片.jpg
 68             //獲取當前日期 joda-time
 69             String datePath = new DateTime().toString("yyyy/MM/dd");
 70 
 71             //fileName 2022/05/03/80b8fbf76d5140f9b33917f883533cc3test.png
 72             fileName = datePath + "/" + fileName;
 73             ossClient.putObject(bucketName, fileName, inputStream);
 74             // 關閉OSSClient。
 75             ossClient.shutdown();
 76             //上傳之后把文件路徑返回
 77             //https://edu8806.oss-cn-beijing.aliyuncs.com/2022/05/03/80b8fbf76d5140f9b33917f883533cc3test.png
 78             url = "https://" + bucketName + "." + endPoint + "/" + fileName;
 79 
 80         } catch (OSSException oe) {
 81             System.out.println("Caught an OSSException, which means your request made it to OSS, "
 82                     + "but was rejected with an error response for some reason.");
 83             System.out.println("Error Message:" + oe.getErrorMessage());
 84             System.out.println("Error Code:" + oe.getErrorCode());
 85             System.out.println("Request ID:" + oe.getRequestId());
 86             System.out.println("Host ID:" + oe.getHostId());
 87         } catch (ClientException ce) {
 88             System.out.println("Caught an ClientException, which means the client encountered "
 89                     + "a serious internal problem while trying to communicate with OSS, "
 90                     + "such as not being able to access the network.");
 91             System.out.println("Error Message:" + ce.getMessage());
 92         } catch (IOException e) {
 93             e.printStackTrace();
 94         } finally {
 95             if (ossClient != null) {
 96                 ossClient.shutdown();
 97             }
 98         }
 99         return url;
100     }
101 
102 }

vue頁面

<template>
  <div class="app-container">
    講師添加
    <el-form label-width="120px">
      <el-form-item label="活動名稱">
        <el-input v-model="teacher.name" />
      </el-form-item>
      <el-form-item label="入駐時間">
        <el-date-picker
          type="date"
          placeholder="選擇日期"
          v-model="teacher.joinDate"
          value-format="yyyy-MM-dd"
        ></el-date-picker>
      </el-form-item>

      <el-form-item label="排序">
        <el-input v-model="teacher.sort" :min="0" />
      </el-form-item>
      <el-form-item label="講師頭銜">
        <el-select v-model="teacher.level" clearable placeholder="講師頭銜">
          <el-option :value="1" label="高級講師" />
          <el-option :value="2" label="首席講師" />
        </el-select>
      </el-form-item>

      <el-form-item label="講師簡介">
        <el-input v-model="teacher.intro" />
      </el-form-item>

      <el-form-item label="講師資歷">
        <el-input v-model="teacher.career" />
      </el-form-item>

      <el-form-item label="講師頭像">
        <el-upload
          :action="BASE_API + '/admin/oss/file/upload'"
          :show-file-list="false"
          :on-success="handleSuccess"
          :on-error="handleError"
          :before-upload="beforeUpload"
          class="avatar-uploader"
        >
          <img v-if="teacher.avatar" :src="teacher.avatar">
          <i v-else class="el-icon-plus avatar-uploader-icon" />
        </el-upload>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          :disabled="saveBtnDisabled"
          @click="saveOrUpdate()"
          >{{ saveOrUpdateText }}</el-button
        >
      </el-form-item>
    </el-form>
  </div>
</template>

<script>
import teacherApi from "@/api/teacher";
export default {
  data() {
    return {
      saveBtnDisabled: false,
      saveOrUpdateText: "保存",
      BASE_API: process.env.BASE_API,
      //講師對象
      teacher: {
        name: "",
        intro: "", //講師簡介
        career: "", //講師資歷
        level: 1, //頭銜 1高級講師 2首席講師
        avatar: "", //講師頭像
        sort: 0,
        joinDate: "", //入駐時間
      },
    };
  },
  created() {
    //created之執行一次

    this.init();
  },
  watch: {
    //路由每次變化都執行
    $route(to, from) {
      debugger;
      console.log("to==== " + to);
      console.log("from=== " + from);

      this.init();
    },
  },
  methods: {
    handleSuccess(res) {
      if (res.success) {
        this.$message.success(res.message);
        this.teacher.avatar = res.data.url;
        this.$forceUpdate();
      } else {
        this.$message.error(res.message);
      }
    },
    handleError(res) {
      this.$message.error(res.message);
    },
    beforeUpload(file) {
      let isJpg = file.type === "image/jpeg";
      if (!isJpg) {
        this.$message.error("上傳頭像圖片只能是JPG格式!");
        return false;
      }
      let isLt2M = file.size / 1024 / 1024 < 2;
      if (!isLt2M) {
        this.$message.error("上傳頭像圖片不能超過2MB!");
        return false;
      }
      return true;
    },
    init() {
      //修改就把詳情查出來,否則頁面是新增頁面,新增頁面對象數據是空
      if (this.$route.params && this.$route.params.id) {
        this.getDetail(this.$route.params.id);
        this.saveOrUpdateText = "修改";
      } else {
        this.teacher = {};
        this.saveOrUpdateText = "保存";
      }
    },
    //同一個頁面,判斷是新增還是修改
    saveOrUpdate() {
      if (this.teacher.id) {
        //更新
        this.update();
      } else {
        //新增
        this.save();
      }
    },
    //進入到修改頁面,需要回顯的數據
    getDetail(id) {
      teacherApi.getDetail(id).then((res) => {
        if (res.code === 20000 && res.data.dataInfo) {
          this.teacher = res.data.dataInfo;
          this.$message({
            type: "info",
            message: "數據初始化成功",
          });
        } else {
          this.$message({
            type: "info",
            message: "數據初始化失敗",
          });
        }
      });
    },
    //新增
    save() {
      teacherApi.save(this.teacher).then((res) => {
        if (res.code === 20000 && res.data) {
          this.$message({
            type: "info",
            message: "添加成功",
          });
          this.$router.push({ path: "/teacher/list" });
        } else {
          this.$message({
            type: "info",
            message: "添加失敗",
          });
        }
      });
    },
    //修改
    update() {
      teacherApi.update(this.teacher).then((res) => {
        if (res.code === 20000 && res.data) {
          this.$message({
            type: "info",
            message: "修改成功",
          });
          this.$router.push({ path: "/teacher/list" });
        } else {
          this.$message({
            type: "info",
            message: "修改失敗",
          });
        }
      });
    },
  },
};
</script>

<style scoped>
.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409EFF;
}

.avatar-uploader .avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  line-height: 178px;
  text-align: center;
}

.avatar-uploader img {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

案例2

1、阿里雲開通用戶和權限

通過子用戶

子賬號

創建 

創建AccessKey

點擊創建AccessKey,注意目前這個只能看一次,要么復制用戶和密碼然后自己保存,要么下載csv文件保存。

然后給這個子用戶添加權限

2、通過SDK簡單上傳-上傳文件流

參考文檔:https://help.aliyun.com/document_detail/32009.html

2.1、添加pom依賴

<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.10.2</version>
</dependency>

2.2、代碼

package com.stu.gulimall.product;

import com.stu.gulimall.product.entity.BrandEntity;
import com.stu.gulimall.product.service.BrandService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.SpringVersion;
import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.PutObjectRequest;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

@SpringBootTest
class GulimallProductApplicationTests {

    @Autowired
    BrandService brandService;

    @Test
    void contextLoads() {
        BrandEntity b = new BrandEntity();
    b.setName("test");
        brandService.save(b);
        System.out.println("=================================");
    }
    @Test
    public void getSpringVersion() throws FileNotFoundException {
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        // 阿里雲賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM用戶進行API訪問或日常運維,請登錄RAM控制台創建RAM用戶。
        String accessKeyId = "xxxxxxxxxxxx";
        String accessKeySecret = "xxxxxxxxxxxxxxxxxxxx";
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "edu8806";

        // 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
        String objectName = "test.png";
        // 填寫本地文件的完整路徑,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路徑,則默認從示例程序所屬項目對應本地路徑中上傳文件流。
        String filePath= "E:\\test.png";

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

        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 創建PutObject請求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } 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();
                System.out.println("============success===============");
            }
        }
    }
}

3、通過封裝好的代碼

參考地址:https://github.com/alibaba/spring-cloud-alibaba(這個目前可能存在版本兼容問題,可以參考下邊的文章解決)

上傳文件如果提示這個問題【解決Cannot resolve com.alibaba.cloud:aliyun-oss-spring-boot-starter:unknown 文件上傳報錯aliCloudEdasSdk解決】
可以參考這篇文章https://www.cnblogs.com/konglxblog/p/16100349.html

 

接入oss

修改pom文件,引入aliyun-oss-spring-boot-starter(注意上邊的是通過SDK,這里是通過starter)

        <!--引入阿里雲封裝好的cloud oss-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alicloud-oss</artifactId>
            <version>2.1.0.RELEASE</version>
        </dependency>

yml文件(注意這里的key和endpoint是阿里雲的子用戶)

#配置數據源
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://123.57xxx:3306/gulimall_pms?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    driver-class-name: com.mysql.jdbc.Driver
  cloud:
    nacos:
      discovery:
        server-addr: xxx:8848
    alicloud:
      access-key: xxx
      secret-key: xxx
      oss:
        endpoint: xxx

測試代碼

package com.stu.gulimall.product;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.OSSException;
import com.stu.gulimall.product.entity.BrandEntity;
import com.stu.gulimall.product.service.BrandService;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

@RunWith(SpringRunner.class)
@SpringBootTest
class GulimallProductApplicationTests {

    @Autowired
    BrandService brandService;
    @Autowired
    private OSSClient ossClient;
    @Test
    void contextLoads() {
        BrandEntity b = new BrandEntity();
        b.setName("test");
        brandService.save(b);
        System.out.println("=================================");
    }
    @Test
    public void getSpringVersion() throws FileNotFoundException {
// Endpoint以華東1(杭州)為例,其它Region請按實際情況填寫。
       /* String endpoint = "oss-cn-beijing.aliyuncs.com";
        // 阿里雲賬號AccessKey擁有所有API的訪問權限,風險很高。強烈建議您創建並使用RAM用戶進行API訪問或日常運維,請登錄RAM控制台創建RAM用戶。
        String accessKeyId = "xxxxxxxxxxxx";
        String accessKeySecret = "xxxxxxxxxxxxxxxxxxxx";
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "edu8806";

        // 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
        String objectName = "test.png";
        // 填寫本地文件的完整路徑,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路徑,則默認從示例程序所屬項目對應本地路徑中上傳文件流。
        String filePath= "E:\\test.png";

        // 創建OSSClient實例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);*/
        // 填寫Bucket名稱,例如examplebucket。
        String bucketName = "edu8806";

        // 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。
        String objectName = "test.png";
        // 填寫本地文件的完整路徑,例如D:\\localpath\\examplefile.txt。
        // 如果未指定本地路徑,則默認從示例程序所屬項目對應本地路徑中上傳文件流。
        String filePath= "E:\\test.png";
        try {
            InputStream inputStream = new FileInputStream(filePath);
            // 創建PutObject請求。
            ossClient.putObject(bucketName, objectName, inputStream);
        } 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();
                System.out.println("============success===============");
            }
        }
    }
}

作者:
出處:https://www.cnblogs.com/konglxblog//
版權:本文版權歸作者和博客園共有
轉載:歡迎轉載,文章中請給出原文連接,此文章僅為個人知識學習分享,否則必究法律責任

免責聲明:
    本文中使用的部分圖片來自於網絡,如有侵權,請聯系 博主進行刪除

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM