1. 程式人生 > >Java中OSS儲存使用

Java中OSS儲存使用

本篇文章希望你先看完官方的API瞭解一下OSS基本語法和概念再來應該比較容易懂。

2018-02-03 更新,優化web直傳程式碼,加入註釋,新增生成資料夾、移動端臨時上傳下載、生成簽名url

2017-12-21 更新,修復上傳圖片OSS報錯,仍會返回url的BUG,操作是修改uploadFile()和uploadWebFile()方法,在catch列印日誌後return null。

2017-11-29 更新,加入web直傳需要的 StsServiceUtil,獲取檔名的改為擷取accessUrl部分,配置變數加入示例,測試類加入baseUrl,更簡潔。

一、上傳規範

主要用到了aliyun-sdk-oss,aliyun-java-sdk-core,aliyun-java-sdk-sts,joda-time等包。

1.上傳圖片主要分為本地檔案上傳(檔案流方式)和網路檔案上傳(如獲取微信頭像)上傳

1)上傳本地檔案需要引數有InputStraem流、directory目錄和fileName檔名,目錄是在專案底下的目錄,由於不建議直接在專案oss資料夾直接上傳圖片,所以目錄是一定要傳的。當傳入目錄為空時,會直接取檔名,一般是更新和替換的時候傳null。

上傳自定義格式本地檔案用upload(),png格式圖片用uploadImage()方法,mp4格式視訊用uploadVedio()方法檔名已封裝,如果想自己生成檔名直接呼叫底層uploadFile()方法

2)上傳網路圖片需要引數有fileUrl檔案地址、directory目錄和fileName檔名,png格式圖片用uploadWebImage()方法,檔名已封裝,如果想自定義檔名直接呼叫底層uploadWebFile()方法。

2.如果想更新檔案有兩種方式,一種是直接更新檔案,只更新內容,不更新檔名和檔案地址。另一種是替換檔案,刪除原檔案並上傳新檔案,檔名和地址同時替換。

引數傳入InputStream流和fileUrl原檔名。

1)直接更新檔案,這個可能存在瀏覽器原資料快取,呼叫updateFile()方法。

2)刪除替換檔案,由於地址更好,解決快取問題 ,呼叫replaceFile()方法。建議更新圖片用這種方式。

3.查詢檔案是否存在

引數傳入fileUrl檔案地址,通過呼叫doesObjectExist方法判斷返回值。

4.刪除檔案,分為單個刪除和批量刪除

引數傳入fileUrl檔案地址或fileUrls檔案地址集合

1.單個上傳,呼叫deleteObject方法。

2.批量上傳,呼叫deleteObjects()方法和deleteBatchObject()方法,deleteObjects()方法主要是用在同一個endpoint和bucketName ,底層是呼叫OSS的deleteObjects()方法,速度較快

而deleteBatchObject()還適用於不同的endPoint和bucketName ,底層呼叫的是我們封裝的deleteObject()方法,由於還是一個個去刪,速度較慢

5.Web直傳獲取簽名

注意:為了瀏覽安全,必須為bucket設定CORS。

主要用於網頁端上傳時,網頁端向服務端請求籤名,然後直接上傳,不用對服務端產生壓力。而且安全可靠。但是這個例子有一個特點,就是使用者上傳了多少檔案,使用者上傳了什麼檔案,使用者後端程式並不能馬上知道,如果想實時知曉使用者上傳了什麼檔案,可以採用上傳回調。本例子無法實現分片與斷點。

http://172.16.1.98:83/wordpress/2017/08/30/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E9%85%8D%E5%90%88web%E7%AB%AF%E4%B8%8A%E4%BC%A0%E8%A7%86%E9%A2%91/

http://172.16.1.98:83/wordpress/2017/08/23/%E6%9C%8D%E5%8A%A1%E7%AB%AF%E7%AD%BE%E5%90%8D%E5%90%8E%E4%B8%8A%E4%BC%A0%E6%96%87%E4%BB%B6%E5%88%B0oss/

二、對檔案的儲存操作

注意需要修改配置!!!

注意需要修改配置!!!

注意需要修改配置!!!

package com.lemo.face.util.oss;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.common.utils.IOUtils;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.aliyun.oss.model.ListObjectsRequest;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.OSSObjectSummary;
import com.aliyun.oss.model.ObjectListing;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PolicyConditions;
import com.aliyuncs.sts.model.v20150401.AssumeRoleResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.joda.time.DateTime;
import org.joda.time.LocalDateTime;

import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import lombok.extern.slf4j.Slf4j;

/**
 * @author 楊小華
 * @desc 阿里檔案雲端儲存管理類
 * @create 2017/11/27 14:25
 **/
@Slf4j
public class OSSClientUtil {
    static final String ACCESS_KEY_ID = "";
    static final String ACCESS_KEY_SECRET = "";
    /**
     * 使用者的儲存空間(bucket)名稱
     */
    static final String BUCKET_NAME = "";
    /**
     * 對應的對映域名
     */
    private static final String ACCESS_URL = "http://test.rrzuzu.com/";
    /**
     * 使用者的儲存空間所在資料中心的訪問域名
     */
    private static final String ENDPOINT = "oss-cn-hangzhou.aliyuncs.com";
    /**
     * 指定專案資料夾
     */
    private static final String PIC_LOCATION = "face/";

    /**
     * 加密金鑰
     */
    private static final String KEY = "biaoqing";

    private static OSSClient ossClient;

    /**
     * @desc 靜態初始化ossClient
     * @author 楊小華
     * @create 2017/11/25 12:44
     **/
    static {
        ossClient = new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }

    /**
     * @desc 上傳自定義格式
     * @author 楊小華
     * @create 2017/11/24 11:09
     **/
    public static String upload(InputStream is, String directory, String fileType) {
        String fileName = getFileName() + "." + fileType;
        return uploadFile(is, directory, fileName);
    }

    /**
     * @desc 上傳視訊指定mp4格式
     * @author 楊小華
     * @create 2017/11/22 15:00
     **/
    public static String uploadVideo(InputStream is, String directory) {
        String fileName = getFileName() + ".mp4";
        return uploadFile(is, directory, fileName);
    }

    /**
     * @desc 上傳圖片指定png格式
     * @author 楊小華
     * @create 2017/11/22 14:59
     **/
    public static String uploadImage(InputStream is, String directory) {
        String fileName = getFileName() + ".png";
        return uploadFile(is, directory, fileName);
    }

    /**
     * @desc 上傳網路圖片指定png格式
     * @author 楊小華
     * @create 2017/11/25 13:37
     **/
    public static String uploadWebImage(String fileUrl, String directory) {
        String fileName = getFileName() + ".png";
        return uploadWebFile(fileUrl, directory, fileName);
    }

    /**
     * @desc 上傳本地檔案(檔案流上傳)
     * @author 楊小華
     * @create 2017/11/23 19:57
     **/
    public static String uploadFile(InputStream is, String directory, String fileName) {
        String key = PIC_LOCATION + directory + "/" + fileName;
        if (Objects.isNull(directory)) {
            key = fileName;
        }
        try {
            ObjectMetadata objectMetadata = getObjectMetadata(is.available());
            ossClient.putObject(BUCKET_NAME, key, is, objectMetadata);
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            IOUtils.safeClose(is);
        }
        return ACCESS_URL + key;
    }

    /**
     * @desc 上傳網路圖片
     * @author 楊小華
     * @create 2017/11/24 15:43
     **/
    public static String uploadWebFile(String fileUrl, String directory, String fileName) {
        String key = PIC_LOCATION + directory + "/" + fileName;
        InputStream is = null;
        try {
            Integer length = new URL(fileUrl).openConnection().getContentLength();
            is = new URL(fileUrl).openStream();
            ObjectMetadata objectMetadata = getObjectMetadata(length);
            ossClient.putObject(BUCKET_NAME, key, is, objectMetadata);
        } catch (Exception e) {
            log.error(e.getMessage());
            return null;
        } finally {
            IOUtils.safeClose(is);
        }
        return ACCESS_URL + key;
    }

    /**
     * @desc 更新檔案:只更新內容,不更新檔名和檔案地址。 (因為地址沒變,可能存在瀏覽器原資料快取,不能及時載入新資料,例如圖片更新,請注意)
     * @author 楊小華
     * @create 2017/11/23 20:40
     **/
    public static String updateFile(InputStream is, String fileUrl) {
        String key = getFileNameByUrl(fileUrl);
        return uploadFile(is, null, key);
    }

    /**
     * @desc 替換檔案:刪除原檔案並上傳新檔案,檔名和地址同時替換 解決原資料快取問題,只要更新了地址,就能重新載入資料)
     * @author 楊小華
     * @create 2017/11/24 14:19
     **/
    public static String replaceFile(InputStream is, String fileUrl) {
        boolean flag = deleteObject(fileUrl);
        String fileName = getFileNameByUrl(fileUrl);
        if (!flag) {
            return null;
        }
        return uploadFile(is, null, fileName);
    }

    /**
     * @desc 查詢檔案是否存在
     * @author 楊小華
     * @create 2017/11/24 10:09
     **/
    public static boolean doesObjectExist(String key) {
        boolean result = false;
        try {
            //如果帶http,提取key值
            if (key.indexOf("http") != -1) {
                key = getFileNameByUrl(key);
            }
            result = ossClient.doesObjectExist(BUCKET_NAME, key);
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return result;
    }

    /**
     * @desc 刪除Object。 注意:以下所有刪除如果檔案不存在返回的是true,如果需要先判斷是否存在先呼叫doesObjectExist()方法
     * @author 楊小華
     * @create 2017/11/24 10:06
     **/
    public static boolean deleteObject(String fileUrl) {
        try {
            String key = getFileNameByUrl(fileUrl);
            ossClient.deleteObject(BUCKET_NAME, key);
        } catch (Exception e) {
            log.error(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @desc 批量刪除object(適用於相同的endpoint和bucketName)
     * @author 楊小華
     * @create 2017/11/24 10:02
     **/
    public static int deleteObjects(List<String> fileUrls) {
        int count = 0;
        List<String> keys = getFileNamesByUrl(fileUrls);
        try {
            // 刪除Objects
            DeleteObjectsRequest deleteRequest = new DeleteObjectsRequest(BUCKET_NAME);
            deleteRequest.withKeys(keys);
            count = ossClient.deleteObjects(deleteRequest).getDeletedObjects().size();
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return count;
    }

    /**
     * @desc 批量檔案刪除(較慢, 適用於不同endpoint和bucketName)
     * @author 楊小華
     * @create 2017/11/24 13:03
     **/
    public static int deleteBatchObject(List<String> fileUrls) {
        int count = 0;
        for (String url : fileUrls) {
            if (deleteObject(url)) {
                count++;
            }
        }
        return count;
    }

    /**
     * @desc web直傳獲取簽名
     * @author 楊小華
     * @create 2017/9/11 13:01
     **/
    public static Map<String, Object> getWebSign(String callbackUrl, int seconds) {
        Map<String, Object> data = Maps.newHashMap();
        // 儲存目錄
        String dir = PIC_LOCATION + "web/" + getDirectory();
        //回撥內容
        Map<String, String> callback = Maps.newHashMap();
        callback.put("callbackUrl", callbackUrl);
        callback.put("callbackBody", "filename=${object}&size=${size}&mimeType=${mimeType}&height" +
                "=${imageInfo.height}&width=${imageInfo.width}");
        callback.put("callbackBodyType", "application/x-www-form-urlencoded");
        //簽名有效期30秒過期
        Date expiration = DateTime.now().plusSeconds(seconds).toDate();
        // 提交節點
        String host = "http://" + BUCKET_NAME + "." + ENDPOINT;
        try {
            PolicyConditions policyConds = new PolicyConditions();
            // 設定上傳檔案的大小限制
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0,
                    1048576000);
            //指定此次上傳的檔名必須是dir變數的值開頭
            policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            //policy
            String policy = BinaryUtil.toBase64String(postPolicy.getBytes("utf-8"));
            //簽名
            String signature = ossClient.calculatePostSignature(postPolicy);
            //回撥
            String callbackData = BinaryUtil.toBase64String(callback.toString().getBytes("utf-8"));
            data.put("policy", policy);
            data.put("signature", signature);
            data.put("callback", callbackData);
            data.put("dir", dir);
            data.put("accessKeyId", ACCESS_KEY_ID);
            data.put("accessUrl", ACCESS_URL);
            data.put("host", host);
            data.put("expire", expiration);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
        return data;
    }

    /**
     * 移動端臨時授權上傳
     *
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author 楊小華
     * @date 2018/1/29 14:11
     * @since 1.0.0
     */
    public static Map<String, Object> getSTSWrite() {
        Map<String, Object> data = Maps.newHashMap();
        // 設定檔案目錄
        String folder = PIC_LOCATION + "app/" + getDirectory();
        //許可權驗證
        AssumeRoleResponse.Credentials credentials = STSUtil.createSTSForPutObject(folder);
        Preconditions.checkState(Objects.nonNull(credentials), "許可權獲取失敗,請重試");
        AssumeRoleResponse.Credentials encryptCredentials = DESUtil.encrypt(credentials, KEY);
        //完整檔名
        data.put("oss", encryptCredentials);
        data.put("folder", folder);
        data.put("endpoint", ENDPOINT);
        data.put("buckName", BUCKET_NAME);
        data.put("accessUrl", ACCESS_URL);
        return data;
    }

    /**
     * 移動端臨時授權下載
     *
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @author 楊小華
     * @date 2018/1/31 15:33
     * @since 1.0.0
     */
    public static Map<String, Object> getSTSRead() {
        Map<String, Object> data = Maps.newHashMap();
        //許可權驗證
        AssumeRoleResponse.Credentials credentials = STSUtil.createSTSForReadOnly();
        Preconditions.checkState(Objects.nonNull(credentials), "許可權獲取失敗,請重試");
        AssumeRoleResponse.Credentials encryptCredentials = DESUtil.encrypt(credentials, KEY);
        //完整檔名
        data.put("oss", encryptCredentials);
        data.put("endpoint", ENDPOINT);
        data.put("buckName", BUCKET_NAME);
        return data;
    }

    /**
     * 私有型bucket,生成簽名URL
     *
     * @param key     表情地址,如face/zip/test.zip
     * @param seconds 多少秒後過期
     * @return java.lang.String
     * @author 楊小華
     * @date 2018/2/2 14:32
     * @since 1.0.0
     */
    public static String getSignUrl(String key, int seconds) {
        //如果key值不存在
        Preconditions.checkArgument(doesObjectExist(key), "key值不存在");
        Date expire = DateTime.now().plusSeconds(seconds).toDate();
        GeneratePresignedUrlRequest generatePresignedUrlRequest =
                new GeneratePresignedUrlRequest(BUCKET_NAME, key);
        generatePresignedUrlRequest.setExpiration(expire);
        URL url = ossClient.generatePresignedUrl(generatePresignedUrlRequest);
        return url.toString();
    }


    /**
     * 單個下載檔案
     *
     * @param key     檔案key值
     * @param fileUrl 目標檔案路徑名稱
     * @return boolean
     * @author 楊小華
     * @date 2018/2/2 18:08
     * @since 1.0.0
     */
    public static boolean getObject(String key, String fileUrl) {
        ObjectMetadata object = ossClient.getObject(new GetObjectRequest(BUCKET_NAME, key), new
                File(fileUrl));
        if (Objects.nonNull(object)) {
            return true;
        }
        return false;
    }

    /**
     * 批量下載檔案
     *
     * @param preFix 下載某個資料夾中的所有
     * @param dir    目標目錄
     * @return java.lang.String
     * @author 楊小華
     * @date 2018/2/2 17:33
     * @since 1.0.0
     */
    public static String listObject(String preFix, String dir) {
        // 構造ListObjectsRequest請求
        ListObjectsRequest listObjectsRequest = new ListObjectsRequest(BUCKET_NAME);
        //Delimiter 設定為 “/” 時,羅列該資料夾下的檔案
        listObjectsRequest.setDelimiter("/");
        //Prefix 設為某個資料夾名,羅列以此 Prefix 開頭的檔案
        listObjectsRequest.setPrefix(preFix);

        ObjectListing listing = ossClient.listObjects(listObjectsRequest);
        //如果改目錄下沒有檔案返回null
        if (CollectionUtils.isEmpty(listing.getObjectSummaries())) {
            return null;
        }
        // 取第一個目錄的key
        File file = new File(dir + listing.getObjectSummaries().get(0).getKey());
        //判斷檔案所在本地路徑是否存在,若無,新建目錄
        File fileParent = file.getParentFile();
        if (!fileParent.exists()) {
            fileParent.mkdirs();
        }
        // 遍歷所有Object:目錄下的檔案
        for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
            //Bucket中儲存檔案的路徑
            String key = objectSummary.getKey();
            //下載object到檔案
            ossClient.getObject(new GetObjectRequest(BUCKET_NAME, key), file);
        }
        return file.getParent();
    }

    /**
     * @desc 生成檔名
     * @author 楊小華
     * @create 2017/11/24 11:15
     **/
    public static String getFileName() {
        return LocalDateTime.now().toString("yyyyMMddHHmmssSSS_") + RandomStringUtils
                .randomNumeric(6);
    }

    /**
     * 生成目錄
     *
     * @return java.lang.String
     * @author 楊小華
     * @date 2018/1/29 19:00
     * @since 1.0.0
     */
    public static String getDirectory() {
        return LocalDateTime.now().toString("yyyy-MM-dd");
    }


    /**
     * @desc 根據url獲取fileName
     * @author 楊小華
     * @create 2017/11/23 20:40
     **/
    private static String getFileNameByUrl(String fileUrl) {
        int beginIndex = fileUrl.indexOf(ACCESS_URL);
        //針對單個圖片處理的圖片
        int endIndex = fileUrl.indexOf("?");
        //針對使用模板圖片處理的圖片
        int endIndex2 = fileUrl.indexOf("@!");
        if (beginIndex == -1) {
            return null;
        }
        if (endIndex != -1) {
            return fileUrl.substring(beginIndex + ACCESS_URL.length(), endIndex);
        }
        if (endIndex2 != -1) {
            return fileUrl.substring(beginIndex + ACCESS_URL.length(), endIndex2);
        }
        return fileUrl.substring(beginIndex + ACCESS_URL.length());
    }

    /**
     * @desc 根據url獲取fileNames集合
     * @author 楊小華
     * @create 2017/11/23 20:42
     **/
    private static List<String> getFileNamesByUrl(List<String> fileUrls) {
        List<String> fileNames = Lists.newArrayList();
        for (String url : fileUrls) {
            fileNames.add(getFileNameByUrl(url));
        }
        return fileNames;
    }

    /**
     * @desc ObjectMetaData是使用者對該object的描述,
     * 由一系列name-value對組成;其中ContentLength是必須設定的,以便SDK可以正確識別上傳Object的大小
     * @author 楊小華
     * @create 2017/11/23 20:12
     **/
    private static ObjectMetadata getObjectMetadata(long length) {
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(length);
        // 被下載時網頁的快取行為
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        return objectMetadata;
    }
}

臨時授權:

http://172.16.1.98:83/wordpress/2018/02/01/oss%E7%9A%84%E4%B8%B4%E6%97%B6%E6%8E%88%E6%9D%83%E8%AE%B0%E5%BD%95/

三、Junit4單元測試程式碼

package com.lemo.erp.base;

import com.google.common.collect.Lists;
import com.lemo.erp.plugins.oss.OSSClientUtil;
import org.junit.Assert;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.List;
import java.util.Map;


/**
 * @author 楊小華
 * @desc Oss測試類
 * @create 2017/11/27 8:56
 **/
public class OSSClientUtilTest {
    private String baseUrl = "http://pic.pingpingapp.com/duduerp/";

    /**
     * @desc 測試上傳任意格式的檔案(如xml)
     * @author 楊小華
     * @create 2017/11/25 12:49
     **/
    @Test
    public void testUpload() throws Exception {
        File file = new File("C:\\Users\\leimo\\Desktop\\test\\test.xml");
        InputStream is = new FileInputStream(file);
        String result = OSSClientUtil.upload(is, "test", "xml");
        Assert.assertTrue(result.contains("xml"));
    }

    /**
     * @desc 測試上傳視訊
     * @author 楊小華
     * @create 2017/11/25 13:28
     **/
    @Test
    public void testUploadVideo() throws Exception {
        File file = new File("C:\\Users\\leimo\\Desktop\\test\\test.mp4");
        InputStream is = new FileInputStream(file);
        String result = OSSClientUtil.uploadVideo(is, "test");
        Assert.assertTrue(result.contains("mp4"));
    }

    /**
     * @desc 測試上傳圖片
     * @author 楊小華
     * @create 2017/11/25 13:25
     **/
    @Test
    public void testUploadImage() throws Exception {
        File file = new File("C:\\Users\\leimo\\Desktop\\test\\test.jpg");
        InputStream is = new FileInputStream(file);
        String result = OSSClientUtil.uploadImage(is, "test");
        Assert.assertTrue(result.contains("png"));
    }

    /**
     * @desc 測試上傳網路圖片
     * @author 楊小華
     * @create 2017/11/24 16:01
     **/
    @Test
    public void testUploadWebImage() throws Exception {
        String headImg = "http://web.rrzuzu.com/WebStatic/duduerp/static/images/logo.png";
        String result = OSSClientUtil.uploadWebImage(headImg, "test");
        Assert.assertTrue(result.contains("png"));
    }

    /**
     * @desc 測試上傳網路圖片指定名稱abc.png
     * @author 楊小華
     * @create 2017/11/25 13:41
     **/
    @Test
    public void testUploadWebFile() throws Exception {
        String headImg = "http://web.rrzuzu.com/WebStatic/duduerp/static/images/logo.png";
        String result = OSSClientUtil.uploadWebFile(headImg, "test", "abc.png");
        Assert.assertTrue(result.contains("test/abc.png"));
    }

    /**
     * @desc 用來測試批量刪除的圖片123.png
     * @author 楊小華
     * @create 2017/11/25 15:20
     **/
    @Test
    public void testUploadWebFile2() throws Exception {
        String headImg = "http://web.rrzuzu.com/WebStatic/duduerp/static/images/logo.png";
        String result = OSSClientUtil.uploadWebFile(headImg, "test", "123.png");
        Assert.assertTrue(result.contains("test/123.png"));
    }

    /**
     * @desc 測試更新圖片
     * @author 楊小華
     * @create 2017/11/24 16:03
     **/
    @Test
    public void testUpdate() throws Exception {
        String url = baseUrl + "test/abc.png";
        File file = new File("C:\\Users\\leimo\\Desktop\\test\\test.jpg");
        InputStream is = new FileInputStream(file);
        String result = OSSClientUtil.updateFile(is, url);
        Assert.assertEquals(url, result);
    }

    /**
     * @desc 測試替換圖片
     * @author 楊小華
     * @create 2017/11/24 16:22
     **/
    @Test
    public void testReplaceFile() throws Exception {
        String url = baseUrl + "test/abc.png";
        File file = new File("C:\\Users\\leimo\\Desktop\\test\\test.jpg");
        InputStream is = new FileInputStream(file);
        String result = OSSClientUtil.replaceFile(is, url);
        Assert.assertEquals(url, result);
    }

    /**
     * @desc 測試查詢
     * @author 楊小華
     * @create 2017/11/24 17:31
     **/
    @Test
    public void testDoesObjectExist() throws Exception {
        String url = baseUrl + "test/abc.png?200";
        boolean result = OSSClientUtil.doesObjectExist(url);
        Assert.assertTrue(result);
    }

    /**
     * @desc 測試單個刪除
     * @author 楊小華
     * @create 2017/11/24 17:33
     **/
    @Test
    public void testDeleteObject() throws Exception {
        String url = baseUrl + "test/abc.png";
        boolean result = OSSClientUtil.deleteObject(url);
        System.out.println(result);
        Assert.assertTrue(result);
    }

    /**
     * @desc 測試批量刪除(同一endpoint和buckName)
     * @author 楊小華
     * @create 2017/11/25 13:45
     **/
    @Test
    public void testDeleteObjects() throws Exception {
        List<String> fileUrls = Lists.newArrayList();
        fileUrls.add(baseUrl + "test/abc.png");
        fileUrls.add(baseUrl + "test/123.png");
        int count = OSSClientUtil.deleteObjects(fileUrls);
        Assert.assertEquals(fileUrls.size(), count);
    }

    /**
     * @desc 測試批量刪除(適用不同endpoint和buckName)
     * @author 楊小華
     * @create 2017/11/25 15:18
     **/
    @Test
    public void testDeleteBatchObject() {
        List<String> fileUrls = Lists.newArrayList();
        fileUrls.add(baseUrl + "test/abc.png");
        fileUrls.add(baseUrl + "test/123.png");
        int count = OSSClientUtil.deleteBatchObject(fileUrls);
        Assert.assertEquals(fileUrls.size(), count);
    }

    /**
     * @desc 測試獲取web直傳簽名
     * @author 楊小華
     * @create 2017/11/27 9:38
     **/
    @Test
    public void testGetSign() {
        Map<String, Object> sign = OSSClientUtil.getSign();
        Assert.assertTrue(sign.containsKey("endpoint"));
    }

}

四、圖片處理

1.單張不同的圖片格式處理可採用直接在後面拼接或用程式碼去請求,如:

// 縮放
String style = "image/resize,m_fixed,w_100,h_100";  
GetObjectRequest request = new GetObjectRequest(bucketName, key);
request.setProcess(style);

ossClient.getObject(request, new File("example-resize.jpg"));

// 裁剪
style = "image/crop,w_100,h_100,x_100,y_100,r_1"; 
request = new GetObjectRequest(bucketName, key);
request.setProcess(style);

ossClient.getObject(request, new File("example-crop.jpg"));

2.多張圖片共用同一種格式,採用模板的方式,如使用者頭像框,可能有多個使用者上傳,他們的圖片格式是一樣的。

http://pic.pingpingapp.com/dudu/1511501970656.png?image/crop,w_100,h_100,x_100,y_100,r_1讓凌霄配置這種格式的模板名稱如@!crop,使用的時候在圖片後面加上這個模板名稱如http://pic.pingpingapp.com/dudu/[email protected]!crop以下是示例圖片:

相關推薦

JavaOSS儲存使用

本篇文章希望你先看完官方的API瞭解一下OSS基本語法和概念再來應該比較容易懂。2018-02-03 更新,優化web直傳程式碼,加入註釋,新增生成資料夾、移動端臨時上傳下載、生成簽名url2017-12-21 更新,修復上傳圖片OSS報錯,仍會返回url的BUG,操作是修改

Java呼叫儲存過程 -- Mybatis

Java中呼叫儲存過程 -- Mybatis public interface XXXMapper { ​ /* * 1.沒有出參(返回值,void) 返回不了值,返回值都封裝在入參的實體類或Map中(引用型別) * 原因:存過的入參、出參都在java呼叫的入參中

Java呼叫儲存過程(詳細)

本文闡述了怎麼使用DBMS儲存過程。我闡述了使用儲存過程的基本的和高階特性,比如返回ResultSet。本文假設你對DBMS和JDBC已經非常熟悉,也假設你能夠毫無障礙地閱讀其它語言寫成的程式碼(即不是Java的語言),但是,並不要求你有任何儲存過程的程式設計經歷。  儲

Javamemcached 儲存 json與map相互轉化

1.Java通過memcache進行內容儲存public String getSysDict(String key) { String memKey = "_getSysDict_key_" + key; String dictionaryStr = (String) mem

java呼叫儲存過程並傳遞list集合引數的方法

sql: CREATE OR REPLACE TYPE test as object( FID NUMBER,  NUM nVARCHAR2(30),  TESKID NUMBER,  CID NUMBER, USERCODE nVARCHAR2(100) ) CREA

JAVA儲存過程的呼叫方法

一:Java如何實現對儲存過程的呼叫:    A:不帶輸出引數的    ---------------不帶輸出引數的---------------------------------- create procedure getsum @n int =0<--此處為引

java使用儲存過程

以前用的是Statement 和 PreparedStatement 呼叫儲存過程就用到 CallableStatement cstmt =conn.prepareCall("call p(?,?,?,?)"); 宣告 一個叫p的儲存過程,需要4個引數 其中1,2為輸入引數

java 變數儲存位置的區別

1.暫存器:最快的儲存區, 由編譯器根據需求進行分配,我們在程式中無法控制.  2. 棧:存放基本型別的變數資料和物件的引用,但物件本身不存放在棧中,而是存放在堆(new 出來的物件)或者常量池中(字串常量物件存放在常量池中。)  3. 堆:存放所有new出來的物件。 

Java物件儲存位置

1. 棧(stack)與堆(heap)都是Java用來在Ram中存放資料的地方。與C++不同,Java自動管理棧和堆,程式設計師不能直接地設定棧或堆。 2. 棧的優勢是,存取速度比堆要快,僅次於直接位於CPU中的暫存器。但缺點是,存在棧中的資料大小與生存期必須是確定的,缺乏靈活性。另外,棧資料可以共享,詳見第

淺談JAVA字符串常量的儲存位置

數據 每一個 [] jit 返回 inf post 符號 boolean 在講述這些之前我們需要一些預備知識: Java的內存結構我們可以通過兩個方面去看待它。 一、從抽象的JVM的角度去看。相關定義請參考JVM規範:Chapter 2. The Structure o

java資料的5種儲存位置(堆與棧)

任何語言所編寫的程式,其中的各型別的資料都需要一個儲存位置,Java中資料的儲存位置分為以下5種: 1.暫存器 最快的儲存區,位於處理器內部,但是數量極其有限。所以暫存器根據需求進行自動分配,無法直接人為控制。 2.棧記憶體 位於RAM當中,通過堆疊指標可以從處理器獲得直接支援。堆疊指標向下

Java一維陣列和二維陣列儲存佔用記憶體大小問題

問題:在java中,一維陣列和二維陣列在資料量一樣的情況下,開闢的記憶體大小是怎樣的? 一、嘗試階段: 1、程式碼一: public class OneArrayMemory{ public static void main(String[] args){ int num1 = 1

MySql儲存過程傳參和不傳參以及java呼叫程式碼

資料庫表結構 1.mysql不傳參寫儲存過程 create procedure product() -- product為儲存過程名稱 begin select * from book; end 呼叫此儲存過程為 CALL product

java 使用logback日誌,並實現日誌按天分類壓縮儲存

以maven專案作為構建工具為例,首先引入使用logback需要的3個依賴,需要注意使用logback是需要引入slf4j-api的,因為logback是基於slf4j的 <!--logback--> <dependency> <groupId>ch.qo

java使用poi把從資料庫取出的資料寫入到excel檔案儲存到指定檔案路徑

  有時候我們要把從資料庫中取出的資料匯入到excel中,使取到的資料看起來更加的直觀和方便,在java中如何實現取到的資料匯入到excel中呢?以下就是使用poi工具吧資料寫入excel檔案中的解決方法: Excel表格副檔名有.xlsx和.xls兩種格式     &n

Java架構-Spring mvc+oss儲存+fileupload多檔案上傳實現SSO單點登入模板管理

之前給大家介紹了sso的相關知識點和整合方案,考慮到每個系統所屬行業的不同,這邊針對於不同行業做了一些統一的sso單點登入介面模板,使用fileupload多檔案上傳+OSS阿里雲端儲存方案。 1. 阿里雲oss儲存Utils Java程式碼 2. 阿里雲配

Java呼叫sqlServer的儲存過程(CallableStatement)的幾種簡單情況

一、呼叫不帶引數的儲存過程 --建立儲存過程 create procedure testselect as begin select bno from book; end package com.nc.dao; import java.sql.*; public class test

String在記憶體如何儲存Java

JDK1.8中JVM把String常量池移入了堆中,同時取消了“永久代”,改用元空間代替(Metaspace)java中對String物件特殊對待,所以在heap區域分成了兩塊,一塊是字串常量池(String constant pool),用於儲存java字串常量物件,另一塊用於儲存普通物件及字串物件。str

Java順序表儲存ID的設計

我定義了一個ArrayId類,內部封裝了一個數組和對陣列的操作方法。 主要實現了陣列的自動擴容,註冊時返回一個沒有空的id,前面如果有空位置優先前面的,對空位做記錄,犧牲部分空間來提高執行效率。 下圖size就是實際儲存的大小,size和end之間是曾經刪除過的記錄。 publi

java呼叫Oracle儲存過程時,出現異常:java.sql.SQLException: ORA-00928: 缺失 SELECT 關鍵字(已解決)

在java中呼叫Oracle儲存過程時,出現異常:java.sql.SQLException: ORA-00928: 缺失 SELECT 關鍵字 //java程式碼 @Test public void testProcedure(){