Le SDK OSS pour Java utilise la vérification MD5 et CRC-64 pour garantir l'intégrité des données lors du chargement, du téléchargement et de la copie d'objets.
Notes d'utilisation
Cette rubrique utilise l'endpoint public de la région Chine (Hangzhou). Pour accéder à OSS depuis d'autres services Alibaba Cloud dans la même région, utilisez un endpoint interne. Pour plus de détails sur les régions et endpoints pris en charge, consultez Régions et endpoints.
Dans cette rubrique, les identifiants d'accès sont obtenus à partir des variables d'environnement. Pour plus d'informations, consultez Configuration des identifiants d'accès.
Cette rubrique illustre la création d'une instance OSSClient avec un endpoint OSS. Pour d'autres configurations, telles que l'utilisation d'un domaine personnalisé ou l'authentification via des identifiants du Security Token Service (STS), consultez Configuration du client.
Vérification MD5
Lorsque vous incluez Content-MD5 dans une requête de chargement, OSS compare le hachage MD5 des données reçues à la valeur fournie. En cas de non-correspondance, OSS renvoie une erreur InvalidDigest et vous devez recharger l'objet.
Le chargement multipartie prend également en charge la vérification MD5. Appelez setMd5Digest dans UploadPartRequest pour définir le hachage MD5 de chaque partie.
La vérification MD5 est prise en charge par PutObject, GetObject, AppendObject, PostObject, le chargement multipartie et UploadPart.
-
Configurez la vérification MD5 dans une opération PutObject :
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.model.ObjectMetadata; import java.io.ByteArrayInputStream; public class Demo { public static void main(String[] args) throws Throwable { // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Specify the name of the bucket. Example: examplebucket. String bucketName = "examplebucket"; // Specify the full path of the object. Do not include the bucket name in the full path. String objectName = "exampledir/object"; // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. String region = "cn-hangzhou"; // Create an OSSClient instance. // Call the shutdown method to release resources when the OSSClient is no longer in use. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // Upload the string. String content = "Hello OSS"; ObjectMetadata meta = new ObjectMetadata(); // Configure MD5 verification. String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes())); meta.setContentMD5(md5); ossClient.putObject(bucketName, objectName, new ByteArrayInputStream(content.getBytes()), meta); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } } -
Configurez la vérification MD5 dans une opération de chargement multipartie :
import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.CredentialsProviderFactory; import com.aliyun.oss.common.auth.EnvironmentVariableCredentialsProvider; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.common.utils.BinaryUtil; import com.aliyun.oss.model.CompleteMultipartUploadRequest; import com.aliyun.oss.model.CompleteMultipartUploadResult; import com.aliyun.oss.model.InitiateMultipartUploadRequest; import com.aliyun.oss.model.InitiateMultipartUploadResult; import com.aliyun.oss.model.PartETag; import com.aliyun.oss.model.UploadPartRequest; import com.aliyun.oss.model.UploadPartResult; public class Demo { public static void main(String[] args) throws Exception { // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. String endpoint = "http://oss-cn-hangzhou.aliyuncs.com"; // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Specify the name of the bucket. Example: examplebucket. String bucketName = "examplebucket"; // Specify the full path of the object. Do not include the bucket name in the full path. String objectName = "exampledir/object"; // Specify the path of the local file that you want to upload. String localFile = "D:\\localpath\\examplefile.txt"; // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. String region = "cn-hangzhou"; // Create an OSSClient instance. // Call the shutdown method to release resources when the OSSClient is no longer in use. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); // Create an InitiateMultipartUploadRequest object. InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, objectName); // Optional. Specify the storage class. // ObjectMetadata metadata = new ObjectMetadata(); // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString()); // request.setObjectMetadata(metadata); // Initiate a multipart upload task. InitiateMultipartUploadResult upresult = ossClient.initiateMultipartUpload(request); // Obtain an upload ID. The upload ID uniquely identifies the multipart upload task. You can use the upload ID to initiate related requests such as canceling and querying a multipart upload task. String uploadId = upresult.getUploadId(); // partETags is a set of PartETags. The PartETag of a part consists of the part number and ETag value of the part. List<PartETag> partETags = new ArrayList<PartETag>(); // Calculate the total number of parts to upload. final long partSize = 1 * 1024 * 1024L; // 1MB final File sampleFile = new File(localFile); long fileLength = sampleFile.length(); int partCount = (int) (fileLength / partSize); if (fileLength % partSize != 0) { partCount++; } // Upload all parts. for (int i = 0; i < partCount; 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); String md5; if(i==partCount-1){ // The size of the last part is not necessarily equal to the specified part size. 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); // Specify the part size. Each part except the last part must be equal to or greater than 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); // Parts are not necessarily uploaded in order and can be uploaded from different OSS clients. OSS sorts the parts based on the part numbers and combines the parts into a complete object. UploadPartResult uploadPartResult = ossClient.uploadPart(uploadPartRequest); // System.out.println("server md5" +uploadPartResult.getETag()); // Each time a part is uploaded, OSS returns a result that contains a PartETag. The PartETag is stored in partETags. partETags.add(uploadPartResult.getPartETag()); } // Create a CompleteMultipartUploadRequest object. // When you call the CompleteMultipartUpload operation, you must provide all valid PartETags. After OSS receives the partETags, OSS verifies all parts one by one. After part verification is successful, OSS combines these parts into a complete object. CompleteMultipartUploadRequest completeMultipartUploadRequest = new CompleteMultipartUploadRequest(bucketName, objectName, uploadId, partETags); // Optional. Set the access control list (ACL) of the object. // completeMultipartUploadRequest.setObjectACL(CannedAccessControlList.PublicRead); // Complete the multipart upload task. CompleteMultipartUploadResult completeMultipartUploadResult = ossClient.completeMultipartUpload(completeMultipartUploadRequest); // Close your OSSClient. ossClient.shutdown(); } public static String md5(InputStream in , long length1) throws Exception{ byte[] bytes = new byte[(int) length1]; long length_tmp = length1; int readSize = in.read(bytes, (int) 0, (int) length_tmp); return BinaryUtil.toBase64String(BinaryUtil.calculateMd5(bytes)); } }
Vérification CRC-64
La vérification CRC-64 est activée par défaut pour les opérations de chargement, de téléchargement et de copie d'objets.
CRC-64 s'applique à PutObject, GetObject, AppendObject et UploadPart. Elle est activée par défaut. Si la somme de contrôle CRC-64 côté client diffère de celle côté serveur, une erreur InconsistentException est levée.
CRC-64 n'est pas pris en charge pour les téléchargements partiels (range downloads).
CRC-64 augmente l'utilisation du CPU et ralentit les chargements et les téléchargements.
-
CRC-64 pour le téléchargement d'objets
Effectuez une vérification CRC-64 lors du téléchargement d'un objet :
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.common.utils.IOUtils; import com.aliyun.oss.internal.OSSHeaders; import com.aliyun.oss.internal.OSSUtils; import com.aliyun.oss.model.GetObjectRequest; import com.aliyun.oss.model.OSSObject; import java.io.BufferedReader; import java.io.InputStreamReader; public class Demo { public static void main(String[] args) throws Throwable { // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Specify the name of the bucket. Example: examplebucket. String bucketName = "examplebucket"; // Specify the full path of the object. Do not include the bucket name in the full path. String objectName = "exampledir/object"; // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. String region = "cn-hangzhou"; // Create an OSSClient instance. // Call the shutdown method to release resources when the OSSClient is no longer in use. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // Download the object in streaming mode. GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, objectName); OSSObject ossObject = ossClient.getObject(bucketName, objectName); // Read the object from the stream to obtain clientCRC. System.out.println("Object content:"); BufferedReader reader = new BufferedReader(new InputStreamReader(ossObject.getObjectContent())); while (true) { String line = reader.readLine(); if (line == null) break; System.out.println("\n" + line); } // You must close the obtained stream after the object is read. Otherwise, connection leaks may occur. Consequently, no connections are available and an exception occurs. reader.close(); // Check whether CRC-64 is enabled on the client. By default, CRC-64 is enabled on the client. Boolean isCrcCheckEnabled = ((OSSClient)ossClient).getClientConfiguration().isCrcCheckEnabled(); // Check whether the download quest is a range download request. CRC-64 verification is not supported for range download. Boolean isRangGetRequest = getObjectRequest.getHeaders().get(OSSHeaders.RANGE) != null; // Check whether the CRC-64 value in the returned result is the same as that of the downloaded object. if (isCrcCheckEnabled && !isRangGetRequest) { Long clientCRC = IOUtils.getCRCValue(ossObject.getObjectContent()); OSSUtils.checkChecksum(clientCRC, ossObject.getServerCRC(), ossObject.getRequestId()); } } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } } -
CRC-64 pour le chargement par ajout (append upload)
Effectuez une vérification CRC-64 lors d'un chargement par ajout :
import com.aliyun.oss.*; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; import com.aliyun.oss.model.*; import java.io.ByteArrayInputStream; public class Demo { public static void main(String[] args) throws Exception { // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. String endpoint = "https://oss-cn-hangzhou.aliyuncs.com"; // Obtain access credentials from environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Specify the name of the bucket. Example: examplebucket. String bucketName = "examplebucket"; // Specify the full path of the object. Example: exampleobject.txt. Do not include the bucket name in the full path. String objectName = "exampleobject.txt"; // Enter the content of the first append upload, such as Hello. String firstAppendContent = "Hello"; // Enter the content of the second append upload, such as World. String secondAppendContent = "World"; // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. String region = "cn-hangzhou"; // Create an OSSClient instance. // Call the shutdown method to release resources when the OSSClient is no longer in use. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); OSS ossClient = OSSClientBuilder.create() .endpoint(endpoint) .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region(region) .build(); try { // Perform the first append operation. AppendObjectRequest appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(firstAppendContent.getBytes())); appendObjectRequest.setPosition(0L); // Set the initial CRC-64 value. OSS SDK for Java performs CRC-64 on the uploaded content by default. appendObjectRequest.setInitCRC(0L); AppendObjectResult appendObjectResult = ossClient.appendObject(appendObjectRequest); // Perform the second append upload operation. appendObjectRequest = new AppendObjectRequest(bucketName, objectName, new ByteArrayInputStream(secondAppendContent.getBytes())); appendObjectRequest.setPosition(appendObjectResult.getNextPosition()); // Set the CRC-64 value to that of the uploaded object. OSS SDK for Java performs CRC-64 on the uploaded content by default. appendObjectRequest.setInitCRC(appendObjectResult.getClientCRC()); ossClient.appendObject(appendObjectRequest); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message:" + oe.getErrorMessage()); System.out.println("Error Code:" + oe.getErrorCode()); System.out.println("Request ID:" + oe.getRequestId()); System.out.println("Host ID:" + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message:" + ce.getMessage()); } finally { if (ossClient != null) { ossClient.shutdown(); } } } }
Références
Le code d'exemple complet pour la vérification MD5 et CRC-64 est disponible sur GitHub.