SpringBoot 整合 阿里雲OSS 儲存服務,快來免費搭建一個自己的圖床

SnailClimb發表於2018-12-10

Github 地址:github.com/Snailclimb/…(SpringBoot和其他常用技術的整合,可能是你遇到的講解最詳細的學習案例,力爭新手也能看懂並且能夠在看完之後獨立實踐。基於最新的 SpringBoot2.0+,是你學習SpringBoot 的最佳指南。) ,歡迎各位 Star。

筆主很早就開始用阿里雲OSS 儲存服務當做自己的圖床了。如果沒有用過阿里雲OSS 儲存服務或者不是很瞭解這個東西的可以看看官方文件,我這裡就不多做介紹了。阿里雲物件儲存 OSS文件,:

help.aliyun.com/product/318…

本篇文章會介紹到 SpringBoot 整合阿里雲OSS 儲存服務實現檔案上傳下載以及簡單的檢視。其實今天將的應該算的上是一個簡單的小案例了,涉及到的知識點還算是比較多。

一 開發前的準備

1.1 前置知識

具有 Java 基礎以及SpringBoot 簡單基礎知識即可。

1.2 環境引數

  • 開發工具:IDEA
  • 基礎工具:Maven+JDK8
  • 所用技術:SpringBoot+阿里雲OSS 儲存服務 Java 相關API
  • SpringBoot版本:2.1.0

1.3 你能學到什麼

  • SpringBoot 整合 阿里雲OSS 儲存服務並編寫相關工具類
  • SpringBoot 整合 thymeleaf 並實現前後端傳值
  • SpringBoot 從配置檔案讀取值並注入到類中
  • 如何自己搭建一個圖床使用(通過前端選擇圖片,支援預覽,但不支援修改圖片)

1.4 建立工程

建立一個基本的 SpringBoot 專案,我這裡就不多說這方面問題了,具體可以參考下面這篇文章:

blog.csdn.net/qq_34337272…

1.5 專案結構

專案結構

1.6 配置 pom 檔案中的相關依賴

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- Thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- 阿里雲OSS-->
        <dependency>
            <groupId>com.aliyun.oss</groupId>
            <artifactId>aliyun-sdk-oss</artifactId>
            <version>2.4.0</version>
        </dependency>
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>
複製程式碼

二 配置阿里雲 OSS 儲存相關屬性

我在專案中使用的通過常量類來配置,不過你也可以使用 .properties 配置檔案來配置,然後@ConfigurationProperties 註解注入到類中。

2.1 通過常量類配置(本專案使用的方式)

AliyunOSSConfigConstant.java

/**
 * @Auther: SnailClimb
 * @Date: 2018/12/4 15:09
 * @Description: 阿里雲OSS儲存的相關常量配置.我這裡通過常量類來配置的,當然你也可以通過.properties 配置檔案來配置,
 * 然後利用 SpringBoot 的@ConfigurationProperties 註解來注入
 */
public class AliyunOSSConfigConstant {
    //私有構造方法 禁止該類初始化
    private AliyunOSSConfigConstant() {
    }

    //倉庫名稱
    public static final String BUCKE_NAME = "my-blog-to-use";
    //地域節點
    public static final String END_POINT = "oss-cn-beijing.aliyuncs.com";
    //AccessKey ID
    public static final String AccessKey_ID = "你的AccessKeyID";
    //Access Key Secret
    public static final String AccessKey_Secret = "你的AccessKeySecret";
    //倉庫中的某個資料夾
    public static final String FILE_HOST = "test";
}
複製程式碼

到阿里雲 OSS 控制檯:oss.console.aliyun.com/overview獲取上述相關資訊:

獲取 BUCKE_NAME 和 END_POINT:

獲取BUCKE_NAME和END_POINT

獲取AccessKey ID和Access Key Secret第一步:

獲取AccessKey ID和Access Key Secret第一步

獲取AccessKey ID和Access Key Secret第二步:

獲取AccessKey ID和Access Key Secret第二步

2.2 通過.properties 配置

#OSS配置
aliyun.oss.bucketname=my-blog-to-use
aliyun.oss.endpoint=oss-cn-beijing.aliyuncs.com
#阿里雲主賬號AccessKey擁有所有API的訪問許可權,風險很高。建議建立並使用RAM賬號進行API訪問或日常運維,請登入 https://ram.console.aliyun.com 建立RAM賬號。
aliyun.oss.keyid=你的AccessKeyID
aliyun.oss.keysecret=你的AccessKeySecret
aliyun.oss.filehost=test
複製程式碼

然後新建一個類將屬性注入:

@Component
@PropertySource(value = "classpath:application-oss.properties")
@ConfigurationProperties(prefix = "aliyun.oss")
/**
 * 阿里雲oss的配置類
 */
public class AliyunOSSConfig {
    private String bucketname;
    private String endpoint;
    private String keyid;
    private String keysecret;
    private String filehost;
    ...
    此處省略getter、setter以及 toString方法
}    
複製程式碼

三 工具類相關方法編寫

該工具類主要提供了三個方法:上傳檔案 upLoad(File file)、通過檔名下載檔案downloadFile(String objectName, String localFileName)、列出某個資料夾下的所有檔案listFile( )。筆主比較懶,程式碼可能還比較簡陋,各位可以懂懂自己的腦子,參考阿里雲官方提供的相關文件來根據自己的需求來優化。Java API文件地址如下:

help.aliyun.com/document_de…

/**
 * @Author: SnailClimb
 * @Date: 2018/12/1 16:56
 * @Description: 阿里雲OSS服務相關工具類.
 * Java API文件地址:https://help.aliyun.com/document_detail/32008.html?spm=a2c4g.11186623.6.703.238374b4PsMzWf
 */
@Component
public class AliyunOSSUtil {
    private static final org.slf4j.Logger logger = LoggerFactory.getLogger(AliyunOSSUtil.class);
    private static String FILE_URL;
    private static String bucketName = AliyunOSSConfigConstant.BUCKE_NAME;
    private static String endpoint = AliyunOSSConfigConstant.END_POINT;
    private static String accessKeyId = AliyunOSSConfigConstant.AccessKey_ID;
    private static String accessKeySecret = AliyunOSSConfigConstant.AccessKey_Secret;
    private static String fileHost = AliyunOSSConfigConstant.FILE_HOST;


    /**
     * 上傳檔案。
     *
     * @param file 需要上傳的檔案路徑
     * @return 如果上傳的檔案是圖片的話,會返回圖片的"URL",如果非圖片的話會返回"非圖片,不可預覽。檔案路徑為:+檔案路徑"
     */
    public static String upLoad(File file) {
        // 預設值為:true
        boolean isImage = true;
        // 判斷所要上傳的圖片是否是圖片,圖片可以預覽,其他檔案不提供通過URL預覽
        try {
            Image image = ImageIO.read(file);
            isImage = image == null ? false : true;
        } catch (IOException e) {
            e.printStackTrace();
        }

        logger.info("------OSS檔案上傳開始--------" + file.getName());

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        String dateStr = format.format(new Date());

        // 判斷檔案
        if (file == null) {
            return null;
        }
        // 建立OSSClient例項。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        try {
            // 判斷容器是否存在,不存在就建立
            if (!ossClient.doesBucketExist(bucketName)) {
                ossClient.createBucket(bucketName);
                CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName);
                createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead);
                ossClient.createBucket(createBucketRequest);
            }
            // 設定檔案路徑和名稱
            String fileUrl = fileHost + "/" + (dateStr + "/" + UUID.randomUUID().toString().replace("-", "") + "-" + file.getName());
            if (isImage) {//如果是圖片,則圖片的URL為:....
                FILE_URL = "https://" + bucketName + "." + endpoint + "/" + fileUrl;
            } else {
                FILE_URL = "非圖片,不可預覽。檔案路徑為:" + fileUrl;
            }

            // 上傳檔案
            PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, file));
            // 設定許可權(公開讀)
            ossClient.setBucketAcl(bucketName, CannedAccessControlList.PublicRead);
            if (result != null) {
                logger.info("------OSS檔案上傳成功------" + fileUrl);
            }
        } catch (OSSException oe) {
            logger.error(oe.getMessage());
        } catch (ClientException ce) {
            logger.error(ce.getErrorMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return FILE_URL;
    }


    /**
     * 通過檔名下載檔案
     *
     * @param objectName    要下載的檔名
     * @param localFileName 本地要建立的檔名
     */
    public static void downloadFile(String objectName, String localFileName) {

        // 建立OSSClient例項。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 下載OSS檔案到本地檔案。如果指定的本地檔案存在會覆蓋,不存在則新建。
        ossClient.getObject(new GetObjectRequest(bucketName, objectName), new File(localFileName));
        // 關閉OSSClient。
        ossClient.shutdown();
    }

    /**
     * 列舉 test 檔案下所有的檔案
     */
    public static void listFile() {
        // 建立OSSClient例項。
        OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
        // 構造ListObjectsRequest請求。
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);

        // 設定prefix引數來獲取fun目錄下的所有檔案。
        listObjectsRequest.setPrefix("test/");
        // 列出檔案。
        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        // 遍歷所有檔案。
        System.out.println("Objects:");
        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
            System.out.println(objectSummary.getKey());
        }
        // 遍歷所有commonPrefix。
        System.out.println("CommonPrefixes:");
        for (String commonPrefix : listing.getCommonPrefixes()) {
            System.out.println(commonPrefix);
        }
        // 關閉OSSClient。
        ossClient.shutdown();
    }
}

複製程式碼

四 Controller 層編寫相關測試方法

上傳檔案 upLoad(File file)、通過檔名下載檔案downloadFile(String objectName, String localFileName)、列出某個資料夾下的所有檔案listFile( ) 這三個方法都在下面有對應的簡單測試。另外,還有一個方法uploadPicture(@RequestParam("file") MultipartFile file, Model model)對應於我們等下要實現的圖床功能,該方法從前端接受到圖片之後上傳到阿里雲OSS儲存空間並返回上傳成功的圖片 URL 地址給前端。

注意將下面的相關路徑改成自己的,不然會報錯!!!

/**
 * @Author: SnailClimb
 * @Date: 2018/12/2 16:56
 * @Description: 阿里雲OSS服務Controller
 */
@Controller
@RequestMapping("/oss")
public class AliyunOSSController {

    private final org.slf4j.Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private AliyunOSSUtil aliyunOSSUtil;

    /**
     * 測試上傳檔案到阿里雲OSS儲存
     *
     * @return
     */
    @RequestMapping("/testUpload")
    @ResponseBody
    public String testUpload() {
        File file = new File("E:/Picture/test.jpg");
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        String url = aliyunOSSUtil.upLoad(file);
        System.out.println(url);
        return "success";
    }
    /**
     * 通過檔名下載檔案
     */
    @RequestMapping("/testDownload")
    @ResponseBody
    public String testDownload() {
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        aliyunOSSUtil.downloadFile(
                "test/2018-12-04/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg","E:/Picture/e3f892c27f07462a864a43b8187d4562-rawpixel-600782-unsplash.jpg");
        return "success";
    }
    /**
     * 列出某個資料夾下的所有檔案
     */
    @RequestMapping("/testListFile")
    @ResponseBody
    public String testListFile() {
        AliyunOSSUtil aliyunOSSUtil = new AliyunOSSUtil();
        aliyunOSSUtil.listFile();
        return "success";
    }

    /**
     * 檔案上傳(供前端呼叫)
     */
    @RequestMapping(value = "/uploadFile")
    public String uploadPicture(@RequestParam("file") MultipartFile file, Model model) {
        logger.info("檔案上傳");
        String filename = file.getOriginalFilename();
        System.out.println(filename);
        try {

            if (file != null) {
                if (!"".equals(filename.trim())) {
                    File newFile = new File(filename);
                    FileOutputStream os = new FileOutputStream(newFile);
                    os.write(file.getBytes());
                    os.close();
                    file.transferTo(newFile);
                    // 上傳到OSS
                    String uploadUrl = aliyunOSSUtil.upLoad(newFile);
                    model.addAttribute("url",uploadUrl);
                }

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return "success";
    }
}
複製程式碼

五 啟動類

@SpringBootApplication
public class SpringbootOssApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootOssApplication.class, args);
    }
}

複製程式碼

六 上傳圖片相關前端頁面

注意引入jquery ,避免前端出錯。

index.html

JS 的內容主要是讓我們上傳的圖片可以預覽,就像我們在網站更換頭像的時候一樣。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>基於阿里雲OSS儲存的圖床</title>
    <script th:src="@{/js/jquery-3.3.1.js}"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        #submit {
            margin-left: 15px;
        }

        .preview_box img {
            width: 200px;
        }
    </style>
</head>
<body>

<form action="/oss/uploadFile" enctype="multipart/form-data" method="post">
    <div class="form-group" id="group">
        <input type="file" id="img_input" name="file" accept="image/*">
        <label for="img_input" ></label>
    </div>
    <button type="submit" id="submit">上傳</button>
    <!--預覽圖片-->
    <div class="preview_box"></div>
</form>
<script type="text/javascript">

    $("#img_input").on("change", function (e) {
        var file = e.target.files[0]; //獲取圖片資源
        // 只選擇圖片檔案
        if (!file.type.match('image.*')) {
            return false;
        }
        var reader = new FileReader();
        reader.readAsDataURL(file); // 讀取檔案
        // 渲染檔案
        reader.onload = function (arg) {

            var img = '<img class="preview" src="' + arg.target.result + '" alt="preview"/>';
            $(".preview_box").empty().append(img);
        }
    });
</script>
</body>
</html>

複製程式碼

success.html

通過 <span th:text="${url}"></span> 引用後端傳過來的值。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>上傳結果</title>
</head>
<body>
<h1>上傳成功!</h1>
圖片地址為:<span th:text="${url}"></span>
</body>
</html>
複製程式碼

七 測試我們的圖床

訪問 :http://localhost:8080/

① 上傳圖片

SpringBoot 整合 阿里雲OSS 儲存服務,快來免費搭建一個自己的圖床

② 圖片上傳成功返回圖片地址

SpringBoot 整合 阿里雲OSS 儲存服務,快來免費搭建一個自己的圖床

③ 通過圖片 URL 訪問圖片

通過圖片 URL 訪問圖片

我們終於能夠獨立利用阿里雲 OSS 完成一個自己的圖床服務,但是其實如果你想用阿里雲OSS當做圖床可以直接使用極簡圖床:jiantuku.com 上傳圖片,比較方便!大家可能心裡在想那你特麼讓我實現個圖床幹嘛?我覺得通過學習,大家以後可以做很多事情,比如 利用阿里雲OSS 儲存服務存放自己網站的相關圖片。

ThoughtWorks准入職Java工程師。專注Java知識分享!開源 Java 學習指南——JavaGuide(12k+ Star)的作者。公眾號多篇文章被各大技術社群轉載。公眾號後臺回覆關鍵字“1”可以領取一份我精選的Java資源哦!

我的公眾號

相關文章