Object Storage Service (OSS) SDK for Javaは、MD5の検証とCRC-64を使用して、オブジェクトのアップロード、ダウンロード、コピー時にデータの整合性を確保します。
使用上の注意
このトピックでは、中国 (杭州) リージョンのパブリックエンドポイントを使用します。 OSSと同じリージョンにある他のAlibaba Cloudサービスを使用してOSSにアクセスする場合は、内部エンドポイントを使用します。 OSSでサポートされているリージョンとエンドポイントの詳細については、「リージョンとエンドポイント」をご参照ください。
このトピックでは、アクセス資格情報は環境変数から取得します。 アクセス資格情報の設定方法の詳細については、「アクセス資格情報の設定」をご参照ください。
このトピックでは、OSSエンドポイントを使用してOSSClientインスタンスを作成します。 カスタムドメイン名またはSecurity Token Service (STS) を使用してOSSClientインスタンスを作成する場合は、「OSSClientインスタンスの作成」をご参照ください。
MD5検証
オブジェクトのアップロード要求でContent-MD5を設定すると、アップロードされたオブジェクトのMD5ハッシュが計算されます。 計算されたMD5ハッシュがアップロード要求で設定されたMD5ハッシュと異なる場合、InvalidDigestが返されます。 これにより、OSSはオブジェクトのアップロードのデータ整合性を確保できます。 InvalidDigestが返された場合は、オブジェクトを再度アップロードする必要があります。
MD5検証はマルチパートアップロードでもサポートされています。 マルチパートアップロードリクエストでは、アップロードするオブジェクトのメタデータを指定します。 MD5検証は、マルチパートアップロード中に各パートに対して実行されます。 setMd5Digest関数は、クライアントがMD5ハッシュを計算するためのUploadPartRequestリクエストで呼び出されます。
MD5検証は、PutObject、GetObject、AppendObject、PostObject、マルチパートアップロード、およびUploadPartでサポートされています。
次のサンプルコードは、PutObject操作でMD5検証を設定する方法の例を示しています。
com.aliyun.oss.*; impor t com.aliyun.oss.com mon.auth.*; impor t com.aliyun.oss.com mon.utils.BinaryUtil; com.aliyun.oss.mo del.ObjectMetadataをインポートします。java.io.ByteArrayInputStreamをインポートします。public classデモ { public static void main(String[] args) Throwable { // この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // バケットの名前を指定します。 例: examplebucket. String bucketName = "examplebucket"; // オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 String objectName = "exampledir/object"; // Create an OSSClient instance. OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // 文字列をアップロードします。 String content = "Hello OSS"; ObjectMetadata meta = new ObjectMetadata(); // MD5検証を設定します。 String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes())); meta.setContentMD5(md5); ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta); } catch (Exception e) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "しかし、何らかの理由でエラー応答で拒否されました。"); System.out.println("エラーメッセージ:" + oe.getErrorMessage()); System.out.println("エラーコード:" + oe.getErrorCode()); System.out.println("リクエストID:" + oe.getRequestId()); System.out.println("ホストID:" + oe.getHostId()); } catch (ClientException e) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + 「ネットワークにアクセスできないなど」; System.out.println("エラーメッセージ:" + ce.getMessage()); } 最後に{ if (ossClient != null) { ossClient.shutdown(); } } } }
次のサンプルコードは、マルチパートアップロード操作でMD5検証を設定する方法の例を示しています。
java.io.Fileをインポートします。java.io.FileInputStreamをインポートします。java.io.InputStreamをインポートします。java.util.ArrayListをインポートします。java.util.Listをインポートします。com.aliyun.oss.OSSをインポートします。com.aliyun.oss.OSSClientBuilderをインポートします。impor t com.aliyun.oss.com mon.auth.CredentialsProviderFactory; impor t com.aliyun.oss.com mon.auth.EnvironmentVariableCredentialsProvider; impor t com.aliyun.oss.com mon.utils.BinaryUtil; com.aliyun.oss.mo del.CompleteMultipartUploadRequestをインポートします。com.aliyun.oss.mo del.CompleteMultipartUploadResultをインポートします。import com.aliyun.oss.mo del.InitiateMultipartUploadRequest; com.aliyun.oss.mo delをインポートします。InitiateMultipartUploadResult; com.aliyun.oss.mo del.PartETagをインポートします。import com.aliyun.oss.mo del.UploadPartRequest; com.aliyun.oss.mo del.UploadPartResultをインポートします。public classデモ { public static void main(String[] args) throws Exception { // この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。 String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // バケットの名前を指定します。 例: examplebucket. String bucketName = "examplebucket"; // オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 String objectName = "exampledir/object"; // アップロードするローカルファイルのパスを指定します。 String localFile = "D :\\ localpath\\examplefile.txt"; // Create an OSSClient instance. OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); // InitiateMultipartUploadRequestオブジェクトを作成します。 InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName); // Optional. ストレージクラスを指定します。 // ObjectMetadata metadata=新しいObjectMetadata(); // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString()); // request.setObjectMetadata (メタデータ); // マルチパートアップロードタスクを開始します。 InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request); // アップロードIDを取得します。 アップロードIDは、マルチパートアップロードタスクを一意に識別します。 アップロードIDを使用して、マルチパートアップロードタスクのキャンセルやクエリなどの関連リクエストを開始できます。 String uploadId = upresult.getUploadId(); // partETags is a set of PartETags. 部品のPartETagは、部品番号と部品のETag値で構成されます。 List<PartETag> partETags = new ArrayList<PartETag>(); // アップロードする部品の総数を計算します。 final long partSize = 1 * 1024 * 1024L; // 1MB final File sampleFile=新しいファイル (localFile); long fileLength = sampleFile.length(); int partCount = (int) (fileLength / partSize); if (fileLength % partSize != 0) { partCount++; } // すべての部品をアップロードします。 for (int i = 0; i <recordCount; i ++ ) { long startPos = i * partSize; long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize; InputStream instream = new FileInputStream(sampleFile); InputStream instream1 = new FileInputStream(sampleFile); // Skip parts that have been uploaded. instream.skip(startPos); instream1.skip(startPos); 文字列md5; if(i==partCount-1){ // 最後のパーツのサイズは、指定されたパーツサイズと同じである必要はありません。 md5 = md5(instream1,fileLength - startPos); }else{ md5 = md5(instream1,partSize); } // instream1.skip(n) UploadPartRequest uploadPartRequest = new UploadPartRequest(); uploadPartRequest.setBucketName(bucketName); uploadPartRequest.setKey(objectName); uploadPartRequest.setUploadId(uploadId); uploadPartRequest.setInputStream(instream); uploadPartRequest.setMd5Digest(md5); // パーツサイズを指定します。 最後の部分を除く各部分は100 KB以上でなければなりません。 uploadPartRequest.setPartSize(curPartSize); // Configure part numbers. Each part is configured with a part number. The value ranges from 1 to 10000. If you configure a number beyond the range, OSS returns an InvalidArgument error code. uploadPartRequest.setPartNumber( i + 1); // パーツは必ずしも順番にアップロードされるとは限らず、異なるOSSクライアントからアップロードできます。 OSSは、部品番号に基づいて部品をソートし、部品を結合して完全なオブジェクトにします。 UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest); // System.out.println("server md5" + uploadPartResult.getETag()); // パーツがアップロードされるたびに、PartETagを含む結果が返されます。 The PartETag is stored in partETags. partETags.add(uploadPartResult.getPartETag()); } // CompleteMultipartUploadRequestオブジェクトを作成します。 // CompleteMultipartUpload操作を呼び出すときは、すべての有効なPartETagsを指定する必要があります。 OSSがpartETagsを受信すると、OSSはすべてのパーツを1つずつ検証します。 After part verification is successful, OSS combines these parts into a complete object. CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags); // Optional. オブジェクトのアクセス制御リスト (ACL) を設定します。 // completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.PublicRead); // マルチパートアップロードタスクを完了します。 CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest); // Close your OSSClient. ossClient.shutdown(); } public static String md5(InputStream in、long length 1) が例外 {をスローします byte[] bytes = new byte[(int) length 1]; long length_tmp = length1; int readSize = in.read (バイト, (int) 0, (int) length_tmp); BinaryUtil.toBase64String(BinaryUtil.ca lculateMd5 (バイト)) を返します。 } }
CRC-64検証
CRC-64検証は、オブジェクトのアップロード、ダウンロード、およびコピー操作でデフォルトで有効になり、データの整合性を確認します。
CRC-64は、PutObject、GetObject、AppendObject、およびUploadPart操作で使用できます。 デフォルトでは、オブジェクトをアップロードするとCRC-64が有効になります。 クライアントで計算されたCRC-64チェックサムが、OSSサーバーによって返されたCRC-64チェックサムと異なる場合、InconsistentExceptionエラーが返されます。
範囲のダウンロードではCRC-64検証はサポートされていません。
CRC-64はCPUリソースを消費し、アップロードとダウンロードを遅くします。
オブジェクトのダウンロードのCRC-64
次のサンプルコードは、オブジェクトをダウンロードするときにCRC-64を実行する方法の例を示しています。
com.aliyun.oss.*; impor t com.aliyun.oss.com mon.auth.*; impor t com.aliyun.oss.com mon.utils.IOUtils; com.aliyun.oss.int ernal.OSSHeadersをインポートします。com.aliyun.oss.int ernal.OSSUtilsをインポートします。com.aliyun.oss.mo del.GetObjectRequestをインポートします。com.aliyun.oss.mo del.OSSObjectをインポートします。java.io.BufferedReaderをインポートします。java.io.InputStreamReaderをインポートします。public classデモ { public static void main(String[] args) Throwable { // この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // バケットの名前を指定します。 例: examplebucket. String bucketName = "examplebucket"; // オブジェクトのフルパスを指定します。 バケット名をフルパスに含めないでください。 String objectName = "exampledir/object"; // Create an OSSClient instance. OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // ストリーミングモードでオブジェクトをダウンロードします。 GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName); OSSObject ossObject = ossClient.getObject(bucketName, objectName); // ストリームからオブジェクトを読み取り、clientCRCを取得します。 System.out.println("Object content:"); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); 一方、(TRUE){ String line = reader.readLine(); if (line == null) break; System.out.println("\n" + line); } // オブジェクトの読み取り後、取得したストリームを閉じる必要があります。 そうしないと、接続リークが発生する可能性があります。 Consequently, no connections are available and an exception occurs. reader.close(); // クライアントでCRC-64が有効になっているかどうかを確認します。 デフォルトでは、CRC-64はクライアントで有効になっています。 ブールisCrcCheckEnabled = ((OSSClient)ossClient).getClientConfiguration().isCrcCheckEnabled(); // ダウンロードクエストが範囲ダウンロード要求かどうかを確認します。 範囲のダウンロードではCRC-64検証はサポートされていません。 ブールisRangGetRequest = getObjectRequest.getHeaders().get(OSSHeaders.RANGE) ! =null; // 返された結果のCRC-64値がダウンロードされたオブジェクトの値と同じかどうかを確認します。 if (isCrcCheckEnabled && !isRangGetRequest) { Long clientCRC = IOUtils.getCRCValue(ossObject.getObjectContent()); OSSUtils. checksum (clientCRC, ossObject.getServerCRC(), ossObject.getRequestId()); } } catch (Exception e) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "しかし、何らかの理由でエラー応答で拒否されました。"); System.out.println("エラーメッセージ:" + oe.getErrorMessage()); System.out.println("エラーコード:" + oe.getErrorCode()); System.out.println("リクエストID:" + oe.getRequestId()); System.out.println("ホストID:" + oe.getHostId()); } catch (ClientException e) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + 「ネットワークにアクセスできないなど」; System.out.println("エラーメッセージ:" + ce.getMessage()); } 最後に{ if (ossClient != null) { ossClient.shutdown(); } } } }
追加アップロードのCRC-64
次のサンプルコードは、追加アップロードを使用してオブジェクトをアップロードするときにCRC-64を実行する方法の例を示しています。
com.aliyun.oss.ClientExceptionをインポートします。com.aliyun.oss.OSSをインポートします。impor t com.aliyun.oss.com mon.auth.*; com.aliyun.oss.OSSClientBuilderをインポートします。com.aliyun.oss.OSSExceptionをインポートします。com.aliyun.oss.mo delをインポートします。*; java.io.ByteArrayInputStreamをインポートします。public classデモ { public static void main(String[] args) throws Exception { // この例では、中国 (杭州) リージョンのエンドポイントが使用されます。 実際のエンドポイントを指定します。 String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // 環境変数からアクセス資格情報を取得します。 サンプルコードを実行する前に、OSS_ACCESS_KEY_IDおよびOSS_ACCESS_KEY_SECRET環境変数が設定されていることを確認してください。 EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // バケットの名前を指定します。 例: examplebucket. String bucketName = "examplebucket"; // オブジェクトのフルパスを指定します。 例: exampleobject.txt。 バケット名をフルパスに含めないでください。 文字列objectName = "exampleobject.txt"; // Helloなど、最初の追加アップロードのコンテンツを入力します。 String firstAppendContent = "Hello"; // Worldなどの2番目の追加アップロードのコンテンツを入力します。 String secondAppendContent = "World"; // Create an OSSClient instance. OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider); try { // 最初の追加操作を実行します。 AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(firstAppendContent.getBytes())); appendObjectRequest.setPosition(0L); // 初期CRC-64値を設定します。 OSS SDK for Javaは、デフォルトでアップロードされたコンテンツに対してCRC-64を実行します。 appendObjectRequest.setInitCRC(0L); AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest); // 2回目の追加アップロード操作を実行します。 appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(secondAppendContent.getBytes())); appendObjectRequest.setPosition(appendObjectResult.getNextPosition()); // CRC-64値をアップロードされたオブジェクトの値に設定します。 OSS SDK for Javaは、デフォルトでアップロードされたコンテンツに対してCRC-64を実行します。 appendObjectRequest.setInitCRC(appendObjectResult.getClientCRC()); ossClient.appendObject(appendObjectRequest); } catch (Exception e) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "しかし、何らかの理由でエラー応答で拒否されました。"); System.out.println("エラーメッセージ:" + oe.getErrorMessage()); System.out.println("エラーコード:" + oe.getErrorCode()); System.out.println("リクエストID:" + oe.getRequestId()); System.out.println("ホストID:" + oe.getHostId()); } catch (ClientException e) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + 「ネットワークにアクセスできないなど」; System.out.println("エラーメッセージ:" + ce.getMessage()); } 最後に{ if (ossClient != null) { ossClient.shutdown(); } } } }
参考資料
MD5の検証とCRC-64の完全なサンプルコードについては、GitHubをご覧ください。