COSClient上傳圖片失敗

目錄java

一、準備配置git

 二、解決問題正則表達式


一、準備配置

任何一個東西,都是從0到1的過程,解決問題以前,咱們得先有一個帳號(已有帳號能夠跳過此步驟)算法

  • 首先,咱們準備一個騰訊雲(https://cloud.tencent.com/)的帳號(沒有就註冊一個),而後首頁選擇對象存儲,點擊當即使用跳轉;

  •  而後登陸進來後看到這個,能夠無償使用6個月,仍是感受不錯的,雖然買通常的也不貴,可是有便宜不佔是孫子,哈哈

  • 如今咱們就能夠來建立一個存儲桶了,這裏注意訪問權限選擇公有讀寫,否則圖片上傳成功後沒法預覽

  • 建立成功後,點擊列表的存儲桶名稱或配置管理,就能夠查看桶的一些配置,好比能夠新建個文件存放圖片啥的。而後咱們再選擇密鑰管理,新建一個密鑰(APPID),SecretId、SecretKey用於代碼裏面的配置。

廢話很少說,上代碼數據庫

public class QCloudUtil { public static ResponseVo writeFile(CloudStorageConfigVo cloudStorageConfig, String filePath, MultipartFile file) { String accessKey = cloudStorageConfig.getQcloudSecretId(); String secretKey = cloudStorageConfig.getQcloudSecretKey(); String bucket = cloudStorageConfig.getQcloudRegion(); // bucket的命名規則爲{name}-{appid} ,此處填寫的存儲桶名稱必須爲此格式
        String bucketName = cloudStorageConfig.getQcloudBucketName(); // 1 初始化用戶身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(accessKey, secretKey); // 2 設置bucket的區域, COS地域的簡稱請參照 https://cloud.tencent.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(bucket)); // 3 生成cos客戶端
        COSClient cosclient = new COSClient(cred, clientConfig); // 簡單文件上傳, 最大支持 5 GB, 適用於小文件上傳, 建議 20 M 如下的文件使用該接口 // 大文件上傳請參照 API 文檔高級 API 上傳
        File localFile = null; try { localFile = File.createTempFile("temp",null); file.transferTo(localFile); // 指定要上傳到 COS 上的路徑
            String key = filePath; PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, localFile); PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest); return new ResponseVo(CoreConst.SUCCESS_CODE,"上傳成功"); } catch (IOException e) { return new ResponseVo(CoreConst.FAIL_CODE,e.getMessage()); }finally { // 關閉客戶端(關閉後臺線程)
 cosclient.shutdown(); } } }

 

  • 雲配置類
/** * 雲存儲配置信息 */
public class CloudStorageConfigVo { //類型 1:七牛 2:阿里雲 3:騰訊雲
    private Integer type; //七牛綁定的域名
    private String qiniuDomain=""; //七牛路徑前綴
    private String qiniuPrefix=""; //七牛ACCESS_KEY
    private String qiniuAccessKey=""; //七牛SECRET_KEY
    private String qiniuSecretKey=""; //七牛存儲空間名
    private String qiniuBucketName=""; //阿里雲綁定的域名
    private String aliyunDomain=""; //阿里雲路徑前綴
    private String aliyunPrefix=""; //阿里雲EndPoint
    private String aliyunEndPoint=""; //阿里雲AccessKeyId
    private String aliyunAccessKeyId=""; //阿里雲AccessKeySecret
    private String aliyunAccessKeySecret=""; //阿里雲BucketName
    private String aliyunBucketName=""; //騰訊雲綁定的域名
    private String qcloudDomain=""; //騰訊雲路徑前綴
    private String qcloudPrefix=""; //騰訊雲AppId
    private Integer qcloudAppId; //騰訊雲SecretId
    private String qcloudSecretId=""; //騰訊雲SecretKey
    private String qcloudSecretKey=""; //騰訊雲BucketName
    private String qcloudBucketName=""; //騰訊雲COS所屬地區
    private String qcloudRegion=""; }

 

  • 上傳圖片代碼*(Java已經實現了MD五、SHA1算法。利用java.security.MessageDigest類就能夠獲取字符串和文件的MD5以及SHA1結果)
//騰訊雲對象存儲
 @ResponseBody @PostMapping(value = "/upload") public UploadResponse upload(@RequestParam(value = "file", required = false) MultipartFile file) throws Exception { if(file == null || file.isEmpty()) { throw new UploadFileNotFoundException(UploadResponse.Error.FILENOTFOUND); } try { String originalFileName = file.getOriginalFilename(); String suffix = originalFileName.substring(originalFileName.lastIndexOf(".")).toLowerCase(); // 數據庫查詢雲配置
            String value = sysConfigService.selectAll().get(SysConfigKey.CLOUD_STORAGE_CONFIG.getValue()); Gson gson = new Gson(); // 轉換爲一個配置對象
            CloudStorageConfigVo cloudStorageConfig = gson.fromJson(value, CloudStorageConfigVo.class); //獲取騰訊雲路徑前綴
            String dir = cloudStorageConfig.getQcloudPrefix(); // 獲取字符串的MD5結果,file.getBytes()--輸入的字符串轉換成字節數組
            String md5 = MD5.getMessageDigest(file.getBytes()); String filePath = String.format("%1$s/%2$s%3$s", dir, md5, suffix); ResponseVo responseVo = QCloudUtil.writeFile(cloudStorageConfig, filePath, file); String qCloudDomain = cloudStorageConfig.getQcloudDomain(); String url = String.format("%1$s/%2$s", qCloudDomain, filePath); if(responseVo.getStatus().equals(CoreConst.SUCCESS_CODE)){ return  new UploadResponse(url,originalFileName, suffix, url, CoreConst.SUCCESS_CODE); }else{ return  new UploadResponse(originalFileName, CoreConst.FAIL_CODE,responseVo.getMsg()); } } catch (Exception e) { logger.error(String.format("UploadController.upload%s", e)); throw e; } }

 

  • MD5api

  • (Java中的 << 、<<、 >>>表示:)

    數組

  • <<  表示左移,不分正負數,低位補0
  • >>  表示右移,若是該數爲正,則高位補0,若爲負數,則高位補1
  • >>> 表示無符號右移,也叫邏輯右移,即若該數爲正,則高位補0,而若該數爲負數,則右移後高位一樣補0
public class MD5 { private MD5() { } public final static String getMessageDigest(byte[] buffer) { //首先初始化一個字符數組,用來存放每一個16進制字符
        char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; try { // 拿到一個MD5轉換器(若是想要SHA1參數換成"SHA1")
            MessageDigest mdTemp = MessageDigest.getInstance ("MD5"); // buffer 是輸入字符串轉換獲得的字節數組
 mdTemp.update (buffer); // 轉換並返回結果,也是字節數組,包含16個元素
            byte[] md = mdTemp.digest (); int j = md.length; // new一個字符數組,這個就是用來組成結果字符串的(解釋一下:一個byte是八位二進制,也就是2位十六進制字符(2的8次方等於16的2次方))
            char str[] = new char[j * 2]; int k = 0; //遍歷字節數組,經過位運算(位運算效率高),轉換成字符放到字符數組中去
            for (int i = 0; i < j; i++) { byte byte0 = md[i]; str[k++] = hexDigits[byte0 >>> 4 & 0xf]; str[k++] = hexDigits[byte0 & 0xf]; } //字符數組轉換成字符串返回
            return new String (str); } catch (Exception e) { return null; } } public static String hex(byte[] array) { StringBuffer sb = new StringBuffer (); for (int i = 0; i < array.length; ++i) { sb.append (Integer.toHexString ((array[i] & 0xFF) | 0x100).substring (1, 3)); } return sb.toString (); } public static String md5Hex(String message) { try { MessageDigest md = MessageDigest.getInstance ("MD5"); return hex (md.digest (message.getBytes ("CP1252"))); } catch (NoSuchAlgorithmException e) { } catch (UnsupportedEncodingException e) { } return null; } }

 

 

 二、解決問題

  • 重現問題,上傳圖片的時候提示上傳失敗,顯示異常信息
com.qcloud.cos.exception.CosClientException: please make sure bucket name must contain legal appid when appid is missing. example: music-1251122334

 

這個是什麼意思,就是說咱們的桶名稱不符合,爲何呢,咱們查看一下 COSClient類 的源碼,咱們直接經過快捷鍵搜索一下 報錯信息中的 music-1251122334,找到這麼一個方法,app

// 格式化bucket, 是bucket返回帶appid 
private String formatBucket(String bucketName, String appid) throws CosClientException { String parrtern; if (appid == null) { // 正則表達式匹配
            parrtern = ".*-(125|100)[0-9]{3,}$"; if (Pattern.matches(parrtern, bucketName)) { return bucketName; } else { throw new CosClientException("please make sure bucket name must contain legal appid when appid is missing. example: music-1251122334"); } } else { parrtern = "-" + appid; return bucketName.endsWith(parrtern) ? bucketName : bucketName + parrtern; } }

 

Pattern與Matcher一塊兒合做.Matcher類提供了對正則表達式的分組支持,以及對正則表達式的屢次匹配支持. 單獨用Pattern只能使用Pattern.matches(String regex,CharSequence input)一種最基礎最簡單的匹配。ui

  • 報異常的緣由那就是咱們的bucketName沒有跟提供的規則匹配上,那規則是什麼呢,就是這句,只匹配了12五、100開頭,可是咱們的是130開頭的,好比個人:wxb-1301890880
String parrtern = ".*-(125|100)[0-9]{3,}$";

 

解決的辦法就是更新依賴包,以前使用的是5.2.4版本,如今替換爲5.6.8版本。阿里雲

<!--騰訊雲存儲依賴-->
        <dependency>
            <groupId>com.qcloud</groupId>
            <artifactId>cos_api</artifactId>
            <version>5.6.8</version>
        </dependency>

 

相關文章
相關標籤/搜索