1. 程式人生 > 實用技巧 >Springboot整合七牛雲端儲存實現圖片上傳(詳細)

Springboot整合七牛雲端儲存實現圖片上傳(詳細)

目錄

本文參考:https://blog.csdn.net/weixin_41922289/article/details/90315999

建立Springboot工程

配置依賴

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.duck.code</groupId>
    <artifactId>Springboot Qiniu</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!-- springboot web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- springboot test -->
        <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>
            <version>2.2.5.RELEASE</version>
        </dependency>

        <!--七牛-->
        <dependency>
            <groupId>com.qiniu</groupId>
            <artifactId>qiniu-java-sdk</artifactId>
            <version>7.2.7</version>
        </dependency>

        <!--工具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
        </dependency>
        <!-- hutool工具類-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.3.3</version>
        </dependency>
    </dependencies>

</project>

配置yml配置檔案

server:
  port: 8082

# 七牛雲端儲存
oss:
  qiniu:
    domain: http://qdnolc9h2.bkt.clouddn.com # 訪問域名(預設使用七牛雲測試域名)
    accessKey: LbO-QxxxxxxxxoF4H3p # 公鑰
    secretKey: TyJAtXx7xxxx_gxbA5k # 私鑰
    bucketName: codeduck  #儲存空間名稱

建立配置類獲取yml配置檔案資訊

package com.duck.code.config;


import lombok.Data;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;


/**
 * CloudStorageConfig
 * @description 雲端儲存配置類
 */
@Data
@Configuration
public class CloudStorageConfig {

    /**
     * 七牛域名domain
     */
    @Value("${oss.qiniu.domain}")
    private String qiniuDomain;
    /**
     * 七牛ACCESS_KEY
     */
    @Value("${oss.qiniu.accessKey}")
    private String qiniuAccessKey;
    /**
     * 七牛SECRET_KEY
     */
    @Value("${oss.qiniu.secretKey}")
    private String qiniuSecretKey;
    /**
     * 七牛空間名
     */
    @Value("${oss.qiniu.bucketName}")
    private String qiniuBucketName;

}

建立工具類StringUtil

StringUtil中建立方法getRandomImgName(String fileName) 根據上傳檔名稱,使用UUID生成唯一的圖片名稱,防止命名衝突

package com.duck.code.utils;

import cn.hutool.core.date.DateUtil;

import java.util.UUID;

/**
 * @program: codeduck
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 09:39
 **/
public class StringUtil {

    /**
     * @Description: 生成唯一圖片名稱
     * @Param: fileName
     * @return: 雲伺服器fileName
     */
    public static String getRandomImgName(String fileName) {

        int index = fileName.lastIndexOf(".");

        if ((fileName == null || fileName.isEmpty()) || index == -1){
            throw new IllegalArgumentException();
        }
        // 獲取檔案字尾
        String suffix = fileName.substring(index);
        // 生成UUID
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        // 生成上傳至雲伺服器的路徑
        String path = "code/duck/" + DateUtil.today() + "-" + uuid + suffix;
        return path;
    }
}

建立抽象類UploadImageService

package com.duck.code.service;

import com.duck.code.config.CloudStorageConfig;

import java.io.FileInputStream;

/**
 * @program: Springboot Qiniu
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 19:48
 **/
public abstract class UploadImageService {

    protected CloudStorageConfig config;

    public abstract String uploadQNImg(FileInputStream file, String path);
}

實現抽象類UploadImageService

實現抽象類的具體功能

package com.duck.code.service.impl;

import com.duck.code.config.CloudStorageConfig;
import com.duck.code.service.UploadImageService;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.stereotype.Service;

import java.io.FileInputStream;


/**
 * @program: Springboot Qiniu
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 19:51
 **/
@Service
public class UploadImageServiceImpl extends UploadImageService {

    // 七牛檔案上傳管理器
    private UploadManager uploadManager;
    private String token;
    // 七牛認證管理
    private Auth auth;

    public UploadImageServiceImpl(CloudStorageConfig config){
        this.config = config;
        init();
    }

    private void init(){
        // 構造一個帶指定Zone物件的配置類, 注意這裡的Zone.zone0需要根據主機選擇
        uploadManager = new UploadManager(new Configuration(Zone.zone0()));
        auth = Auth.create(config.getQiniuAccessKey(), config.getQiniuSecretKey());
        // 根據名稱空間生成的上傳token
        token = auth.uploadToken(config.getQiniuBucketName());
    }

    @Override
    public String uploadQNImg(FileInputStream file, String key) {
        try{
            // 上傳圖片檔案
            Response res = uploadManager.put(file, key, token, null, null);
            if (!res.isOK()) {
                throw new RuntimeException("上傳七牛出錯:" + res.toString());
            }
            // 解析上傳成功的結果
            DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);

            String path = config.getQiniuDomain() + "/" + putRet.key;
            // 這個returnPath是獲得到的外鏈地址,通過這個地址可以直接開啟圖片
            return path;
        }catch (QiniuException e){
            e.printStackTrace();
        }
        return "";
    }
}

建立Web訪問空間實現檔案上傳

package com.duck.code.controller;


import com.duck.code.service.UploadImageService;
import com.duck.code.utils.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @program: SpringBoot Qiniu
 * @description:
 * @author: CodeDuck
 * @create: 2020-07-30 16:12
 **/
@Slf4j
@RestController
@RequestMapping("/qiniu")
public class UploadController {

    @Resource
    UploadImageService uploadImageService;

    @PostMapping(value = "/image")
    private String upLoadImage(@RequestParam("file") MultipartFile file) throws IOException {

        // 獲取檔案的名稱
        String fileName = file.getOriginalFilename();

        // 使用工具類根據上傳檔案生成唯一圖片名稱
        String imgName = StringUtil.getRandomImgName(fileName);

        if (!file.isEmpty()) {

            FileInputStream inputStream = (FileInputStream) file.getInputStream();

            String path = uploadImageService.uploadQNImg(inputStream, imgName);
            System.out.print("七牛雲返回的圖片連結:" + path);
            return path;
        }
        return "上傳失敗";
    }

}

建立靜態訪問Web頁面index.html

<!DOCTYPE html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
    <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body>
<script>
    /**
     * 上傳圖片
     */
    function uploadImg() {

        /**
         * formData在jquey中使用需要設定:
         * processData: false, // 告訴jQuery不要去處理髮送的資料
         * contentType: false // 告訴jQuery不要去設定Content-Type請求頭
         * @type {null}
         */
        var fd = new FormData();

        // 第一個引數為controller 接收的引數名稱 , input的id
        fd.append("file", document.getElementById("inputId").files[0]);
        $.ajax({
            url: "http://localhost:8082/qiniu/image",
            type: "post",
            data: fd,
            processData: false,
            contentType: false,
            success: function (res) {
                console.log(res);

                if (res.status.code == 0) {
                    if (!$('#img').empty()) {
                        $('#img').empty();
                    }
                    // 這一串程式碼複製不上來 ,截圖在下面
                    $('#img').append(" ![](+res.result[0]+)");
                } else {
                    alert("圖片上傳失敗");
                }
            },
            dataType: "json"
        })
    }
</script>
    <div id="img" style="margin: 200px">
        <input type="file" name="text" id="inputId">
        <br/><br/>
        <input type="submit" onclick="uploadImg()">
    </div>
</body>
</html>

測試

web訪問:

後臺列印上傳路徑