Intégration rapide
Pour intégrer OSS Java SDK V1 :
Préparer l'environnement
Installez Java 7 ou une version ultérieure. Exécutez la commande java -version pour consulter votre version de Java. Si Java n'est pas installé ou si votre version est antérieure à Java 7, téléchargez Java.
Installer le SDK
Choisissez une méthode d'installation adaptée à votre environnement. Utilisez la dernière version d'OSS Java SDK V1.
Les exemples suivants utilisent OSS Java SDK V1 3.17.4.
Ajouter une dépendance Maven (recommandé)
Pour utiliser OSS Java SDK V1 dans un projet Maven, ajoutez la dépendance correspondante au fichier pom.xml.
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.18.4</version>
</dependency>
Si vous utilisez Java 9 ou une version ultérieure, ajoutez les dépendances JAXB suivantes.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency>
<dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.1.1</version>
</dependency>
<!-- no more than 2.3.3-->
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
Importer des packages JAR dans un projet Eclipse
Téléchargez OSS Java SDK V1.
Décompressez le package.
Copiez le fichier aliyun-sdk-oss-3.17.4.jar ainsi que tous les fichiers du dossier
libdu package décompressé vers votre projet.Dans Eclipse, cliquez avec le bouton droit sur votre projet et sélectionnez .
Sélectionnez tous les fichiers JAR copiés et importez-les dans Libraries.
Importer des packages JAR dans un projet IntelliJ IDEA
Téléchargez OSS Java SDK V1.
Décompressez le package.
Copiez le fichier aliyun-sdk-oss-3.17.4.jar ainsi que tous les fichiers JAR du dossier
libdu package décompressé vers votre projet.Dans IntelliJ IDEA, sélectionnez votre projet et choisissez .
Sélectionnez tous les fichiers JAR copiés et importez-les dans External Libraries.
Configurer les identifiants d'accès
Configurez les identifiants d'accès avec la paire AccessKey d'un utilisateur RAM.
Dans la console RAM, créez un utilisateur RAM avec une Permanent AccessKey Pair. Enregistrez la paire AccessKey et accordez l'autorisation
AliyunOSSFullAccessà cet utilisateur.-
Utilisez la paire AccessKey de l'utilisateur RAM pour configurer les variables d'environnement.
Linux
-
Exécutez les commandes suivantes dans l'interface en ligne de commande pour ajouter les paramètres des variables d'environnement au fichier
~/.bashrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc -
Exécutez la commande suivante pour appliquer les modifications.
source ~/.bashrc -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
-
Exécutez la commande suivante dans le terminal pour consulter le type de shell par défaut.
echo $SHELL -
Effectuez les opérations suivantes selon le type de shell par défaut.
Zsh
-
Exécutez les commandes suivantes pour ajouter les paramètres des variables d'environnement au fichier
~/.zshrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc -
Exécutez la commande suivante pour appliquer les modifications.
source ~/.zshrc -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
Exécutez les commandes suivantes pour ajouter les paramètres des variables d'environnement au fichier
~/.bash_profile.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile -
Exécutez la commande suivante pour appliquer les modifications.
source ~/.bash_profile -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
-
Windows
CMD
-
Exécutez les commandes suivantes dans CMD.
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET" -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
-
Exécutez les commandes suivantes dans PowerShell.
[Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User) -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
Initialiser le client
L'exemple de code suivant utilise l'endpoint public de la région China (Hangzhou) pour initialiser le client. Il liste ensuite tous les buckets appartenant au compte afin de vérifier la configuration. Pour obtenir la liste complète des régions et des endpoints, consultez Régions et endpoints.
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.model.Bucket;
import java.util.List;
/**
* OSS SDK quick integration example
* Shows how to initialize an OSS client and list all buckets
*/
public class Test {
public static void main(String[] args) {
// Obtain access credentials from environment variables
String accessKeyId = System.getenv("OSS_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("OSS_ACCESS_KEY_SECRET");
// Set the OSS region and endpoint
String region = "cn-hangzhou";
String endpoint = "oss-cn-hangzhou.aliyuncs.com";
// Create a credential provider
DefaultCredentialProvider provider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
// Configure client parameters
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Explicitly declare the use of the V4 signature algorithm
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// Initialize the OSS client
OSS ossClient = OSSClientBuilder.create()
.credentialsProvider(provider)
.clientConfiguration(clientBuilderConfiguration)
.region(region)
.endpoint(endpoint)
.build();
// List all buckets of the current user
List<Bucket> buckets = ossClient.listBuckets();
System.out.println("Successfully connected to OSS. Buckets under the current account:");
if (buckets.isEmpty()) {
System.out.println("No buckets found under the current account.");
} else {
for (Bucket bucket : buckets) {
System.out.println("- " + bucket.getName());
}
}
// Release resources
ossClient.shutdown();
System.out.println("OSS client has been shut down.");
}
}
Après l'exécution du code, les buckets du compte actuel dans toutes les régions s'affichent :
Successfully connected to OSS. Buckets under the current account:
- example-bucket
OSS client has been shut down.
Configuration du client
Utilisez la classe ClientConfiguration pour configurer les paramètres d'OSSClient, tels que les délais d'expiration, les tentatives de nouvelle exécution et les serveurs proxy.
Utiliser un nom de domaine personnalisé
Le nom de domaine OSS par défaut peut entraîner des refus d'accès ou des échecs de prévisualisation en raison des politiques de sécurité d'OSS. Associer un nom de domaine personnalisé permet de contourner ces restrictions, d'activer la prévisualisation directe des fichiers et de prendre en charge l'intégration CDN pour l'accélération mondiale du contenu.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Enable the CNAME option to support access through a custom domain name
clientBuilderConfiguration.setSupportCname(true);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
// Use your custom domain name as the endpoint, such as https://static.example.com
.endpoint("https://static.example.com")
.build();
Utiliser un endpoint interne
Lorsque votre application s'exécute sur des services Alibaba Cloud tels qu'ECS ou Container Service, utilisez un endpoint interne pour bénéficier d'un transfert de données interne gratuit, de vitesses plus élevées et d'une meilleure stabilité. L'accès interne convient aux téléchargements de fichiers volumineux, au traitement de données par lots et aux accès fréquents. Consultez Régions et endpoints.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
// Use an internal endpoint. The China (Hangzhou) region is used as an example. For other regions, specify the actual endpoint.
.endpoint("oss-cn-hangzhou-internal.aliyuncs.com")
.build();
Contrôle des délais d'expiration
Ajustez les paramètres de délai d'expiration selon votre cas d'utilisation. Augmentez les délais pour les transferts de fichiers volumineux ou les réseaux instables. Privilégiez des délais plus courts pour les opérations légères à haute concurrence afin de libérer rapidement les ressources.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Set the maximum number of allowed open HTTP connections. The default is 1024.
clientBuilderConfiguration.setMaxConnections(1024)
// Set the timeout period for data transfers at the socket layer, in milliseconds. The default is 50000 ms.
.setSocketTimeout(50000)
// Set the timeout period for establishing a connection, in milliseconds. The default is 50000 ms.
.setConnectionTimeout(50000)
// Set the timeout period for obtaining a connection from the connection pool, in milliseconds. By default, there is no timeout limit.
.setConnectionRequestTimeout(60 * 60 * 24 * 1000)
// Set the idle timeout period for a connection, in milliseconds. If a connection is idle for longer than this period, it is closed. The default is 60000 ms.
.setIdleConnectionTime(60000);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
.build();
Nombre maximal de tentatives en cas d'erreur
Par défaut, le client OSS tente trois fois les requêtes ayant échoué. Dans des environnements à haute concurrence ou sur des réseaux instables, utilisez setMaxErrorRetry pour augmenter le nombre de tentatives. Ajustez cette valeur en fonction des exigences de latence et de la qualité du réseau.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Set the maximum number of retries for a failed request. Adjust this based on your network environment and business needs.
clientBuilderConfiguration.setMaxErrorRetry(5);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
.build();
Politique de nouvelle tentative
N'utilisez pas setRetryStrategy pour définir une politique de nouvelle tentative personnalisée. Des politiques personnalisées peuvent provoquer des comportements inattendus. Le client OSS applique des stratégies éprouvées selon le type de requête :
Requêtes POST : Aucune nouvelle tentative n'est effectuée par défaut afin d'éviter les incohérences de données dues à des soumissions répétées.
-
Requêtes non-POST : Jusqu'à trois tentatives sont effectuées si les conditions suivantes sont remplies.
Une exception
ClientExceptionsurvient avec l'un des codes d'erreur suivants :ConnectionTimeout,SocketTimeout,ConnectionRefused,UnknownHostouSocketException.Une exception
OSSExceptionsurvient avec un code d'erreur autre queInvalidResponse.Une erreur temporaire côté serveur survient avec un code d'état HTTP 500, 502 ou 503.
Serveur proxy
Les réseaux d'entreprise acheminent souvent le trafic via des serveurs proxy. Une fois le proxy configuré, le client OSS transmet toutes les requêtes HTTP par son intermédiaire.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Set the user agent, which is the User-Agent header in HTTP. The default value is aliyun-sdk-java.
clientBuilderConfiguration.setUserAgent("aliyun-sdk-java");
// Set the IP address of the proxy server. Replace "" with the actual IP address of the proxy server, such as "196.128.xxx.xxx".
clientBuilderConfiguration.setProxyHost("");
// Set the port of the proxy server, such as 8080.
clientBuilderConfiguration.setProxyPort(8080);
// Set the username for proxy server authentication. Replace "" with the actual username, such as "admin".
clientBuilderConfiguration.setProxyUsername("");
// Set the password for proxy server authentication. Replace "" with the corresponding password.
clientBuilderConfiguration.setProxyPassword("");
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
.build();
Protocole HTTP/HTTPS
Utilisez setProtocol pour définir le protocole de communication. La valeur par défaut est HTTP. En production, privilégiez HTTPS pour garantir un transfert sécurisé des données et prévenir les attaques de type « homme du milieu ».
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Set the communication protocol to HTTPS to ensure secure data transfer.
clientBuilderConfiguration.setProtocol(Protocol.HTTPS);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
.build();
Version de signature
La Signature V1 d'Alibaba Cloud Object Storage Service sera progressivement abandonnée selon le calendrier suivant. Nous vous recommandons de passer à la Signature V4 dès que possible afin d'éviter toute interruption de service.
À partir du 1er mars 2025, les nouveaux utilisateurs ne pourront plus utiliser la Signature V1.
À partir du 1er septembre 2025, la Signature V1 ne sera plus mise à jour ni maintenue, et les nouveaux buckets ne pourront plus l'utiliser.
Vous pouvez utiliser setSignatureVersion pour configurer la version de l'algorithme de signature. Lors de l'utilisation de la Signature V4, vous devez spécifier l'ID de région correct via le paramètre region. L'algorithme de signature V4 offre une sécurité renforcée. OSS Java SDK V1 3.15.0 et les versions ultérieures prennent en charge la Signature V4.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Set the signature algorithm version to V4 for higher security.
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
// You must specify the region ID when using Signature V4.
.region("cn-hangzhou")
.clientConfiguration(clientBuilderConfiguration)
.build();
Utiliser une adresse IP
Utilisez une adresse IP comme endpoint pour l'accès au réseau interne et les environnements réseau spécifiques. Après l'établissement d'une connexion via CEN, Express Connect, une ligne louée ou un VPN, l'accès direct par IP contourne la résolution DNS et améliore l'efficacité. Pour les configurations de routage, consultez Endpoints internes et blocs CIDR VIP pour OSS.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Enable access to OSS through a second-level domain. This feature is disabled by default.
// This value must be set for OSS Java SDK V1 2.1.2 and earlier.
// Versions 2.1.2 and later automatically detect the IP address, so this value is no longer required.
clientBuilderConfiguration.setSLDEnabled(true);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
// When you access OSS using an IP address, use the HTTP protocol to avoid SSL certificate verification issues.
.endpoint("http://10.10.10.10")
.build();
Vérification CRC
Les vérifications de données CRC sont activées par défaut pour garantir l'intégrité des transferts. Maintenez le CRC activé en production. N'envisagez de le désactiver que pour les scénarios où une perte mineure de données est tolérable, tels que les flux de prévisualisation en direct, les données d'appareils IoT, les vidéos de surveillance de faible qualité ou les transferts par lots sur des réseaux internes hautement fiables. Évaluez minutieusement les risques liés à la cohérence des données avant toute désactivation.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Disable the CRC data check feature. Use this with caution and fully assess the risks.
clientBuilderConfiguration.setCrcCheckEnabled(false);
OSS ossClient = new OSSClientBuilder()
// Other configurations...
.clientConfiguration(clientBuilderConfiguration)
.build();
Modèle singleton
Adoptez le modèle singleton pour créer et gérer les instances OSSClient.
OSSClient est thread-safe. Le modèle singleton permet de réutiliser une seule instance OSSClient, évitant ainsi la surcharge liée à des créations et destructions fréquentes.
OSSClient gère un pool de connexions interne. Lorsqu'il n'est plus nécessaire, appelez la méthode shutdown pour libérer les ressources.
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.CredentialsProviderFactory;
import com.aliyun.oss.common.comm.SignVersion;
import com.aliyun.oss.internal.OSSHeaders;
import com.aliyun.oss.model.*;
import java.io.ByteArrayInputStream;
public class OssClientSingleton {
private OssClientSingleton() {}
// Implement singleton with a static inner class (thread-safe)
private static class SingletonHolder {
private static final OSS INSTANCE = create();
private static OSS create() {
try {
// The China (Hangzhou) region is used as an example. For other regions, specify the actual endpoint.
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Enter the region where the bucket is located. The China (Hangzhou) region is used as an example. Set the region to cn-hangzhou.
String region = "cn-hangzhou";
ClientBuilderConfiguration config = new ClientBuilderConfiguration();
// Explicitly declare the use of the V4 signature algorithm.
config.setSignatureVersion(SignVersion.V4);
// Obtain access credentials from environment variables. Before running this sample code, make sure the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are set.
CredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// Build the OSS client.
return OSSClientBuilder.create()
.endpoint(endpoint)
.credentialsProvider(credentialsProvider)
.clientConfiguration(config)
.region(region)
.build();
} catch (Exception e) {
throw new RuntimeException("Failed to initialize OSS client", e);
}
}
}
// Get the singleton instance.
public static OSS getInstance() {
return SingletonHolder.INSTANCE;
}
// Test the PutObject operation in the main function.
public static void main(String[] args) {
// Get the singleton OSS client.
OSS ossClient = OssClientSingleton.getInstance();
// Enter the bucket name, such as examplebucket.
String bucketName = "examplebucket";
// Enter the full path of the object, excluding the bucket name, such as testfolder/exampleobject.txt.
String objectKey = "testfolder/exampleobject.txt";
try {
// Enter the string.
String content = "Hello OSS";
// Create a PutObjectRequest object.
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, new ByteArrayInputStream(content.getBytes()));
// To set the storage class and access permissions during upload, see the following sample code.
ObjectMetadata metadata = new ObjectMetadata();
metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
metadata.setObjectAcl(CannedAccessControlList.Private);
putObjectRequest.setMetadata(metadata);
// Upload the string.
PutObjectResult result = ossClient.putObject(putObjectRequest);
// Print the upload result.
System.out.println("File uploaded successfully!");
System.out.println("ETag: " + result.getETag());
System.out.println("Request ID: " + result.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 {
// In singleton mode, do not close the client after each operation (to reuse the connection), as this may affect subsequent use.
// When the OSSClient instance is no longer needed (for example, before the application exits), call the shutdown method once to release resources.
// ossClient.shutdown();
}
}
}
Gestion des exceptions
OSS Java SDK V1 génère deux types d'exceptions : ClientException et OSSException, qui étendent toutes deux RuntimeException.
Exceptions client (ClientException)
Les exceptions client surviennent lors de la construction de la requête, de son envoi ou du transfert de données. Voici les scénarios courants :
La connexion réseau est indisponible, empêchant l'envoi de la requête au serveur.
Une exception d'E/S se produit lors du téléchargement d'un fichier.
Des exceptions réseau sous-jacentes surviennent, telles qu'un délai d'expiration de requête ou un échec de vérification de certificat.
Une ClientException signifie que la requête n'a pas été envoyée au serveur OSS ou qu'une erreur est survenue lors du traitement côté client. Vérifiez la connexion réseau et la configuration du client.
Exceptions serveur (OSSException)
Les exceptions serveur indiquent que la requête a atteint OSS mais a été rejetée. OSSException fournit :
Des codes d'erreur et messages détaillés permettant une identification précise du problème.
Parmi les erreurs fréquentes figurent SignatureDoesNotMatch, AccessDenied et NoSuchKey.
Le traitement de ces exceptions basé sur le code d'erreur améliore considérablement la robustesse du programme et l'expérience utilisateur.
Capturez ces deux types d'exceptions séparément pour identifier et traiter les erreurs avec précision.
// Create client operation...
try {
// Perform OSS operations, such as uploading a file, downloading a file, or listing objects.
// These operations may throw OSS-related exceptions.
ossClient.putObject(...);
} catch (OSSException oe) {
// Catch exceptions returned by the OSS server.
// This exception is thrown when a request successfully reaches the OSS server, but the server rejects the request.
// Common causes: insufficient permissions, incorrect parameters, resource does not exist, etc.
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
// Output detailed error information for problem location and debugging.
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) {
// Catch client exceptions.
// This exception is thrown when the client encounters a serious internal problem while communicating with OSS.
// Common causes: network connection issues, SSL certificate issues, DNS resolution failure, etc.
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.");
// Output detailed information about the client exception.
System.out.println("Error Message: " + ce.getMessage());
} finally {
// Release client resources regardless of whether the operation succeeded or failed.
// This is a best practice to avoid resource leaks and connection pool exhaustion.
if (ossClient != null) {
ossClient.shutdown(); // Close the client to release network connections and other resources.
}
}
Exemples de code
Le SDK Java V1 pour OSS fournit des exemples de code couvrant la gestion des buckets, les opérations sur les fichiers, le contrôle d'accès et le transfert chiffré :
|
Fichier d'exemple |
Contenu de l'exemple |
|
Téléversement par formulaire (SDK Java V1 pour OSS) Remarque
L'implémentation de PostObject ne dépend pas du SDK Java. |
|
|
Convertir la classe de stockage d'un fichier (SDK Java V1 pour OSS) |
|
|
Empêcher l'écrasement d'un fichier portant le même nom (SDK Java V1 pour OSS) |
|
|
Limitation de bande passante par connexion unique (SDK Java V1 pour OSS) |
|
Configuration des identifiants d'accès
OSS prend en charge plusieurs méthodes d'initialisation des identifiants. Choisissez celle qui correspond à vos besoins d'authentification.
Utiliser la paire d'AccessKey d'un utilisateur RAM
Cette méthode convient aux applications situées dans un environnement sécurisé qui nécessitent un accès OSS à long terme sans rotation fréquente des identifiants. Initialisez le fournisseur d'identifiants avec la paire d'AccessKey d'un utilisateur RAM (AccessKey ID et AccessKey secret). Cette approche requiert une maintenance manuelle de la paire d'AccessKey, ce qui accroît les risques de sécurité.
Un compte Alibaba Cloud dispose de toutes les permissions sur ses ressources. En cas de fuite de la paire d'AccessKey, votre système est exposé à un risque majeur. Nous vous déconseillons d'utiliser la paire d'AccessKey d'un compte Alibaba Cloud. Privilégiez plutôt la paire d'AccessKey d'un utilisateur RAM doté des permissions minimales requises.
Pour créer une paire d'AccessKey pour un utilisateur RAM, consultez Créer une paire d'AccessKey. L'AccessKey ID et l'AccessKey secret d'un utilisateur RAM s'affichent uniquement lors de la création de la paire d'AccessKey. Si vous les oubliez, vous devez créer une nouvelle paire d'AccessKey pour remplacer l'ancienne.
Variables d'environnement
-
Configurez les variables d'environnement à l'aide de la paire d'AccessKey d'un utilisateur RAM.
Linux
-
Exécutez les commandes suivantes dans l'interface en ligne de commande pour ajouter les paramètres de variables d'environnement au fichier
~/.bashrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc -
Exécutez la commande suivante pour appliquer les modifications.
source ~/.bashrc -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
-
Exécutez la commande suivante dans le terminal pour afficher le type de shell par défaut.
echo $SHELL -
Effectuez les opérations suivantes selon le type de shell par défaut.
Zsh
-
Exécutez les commandes suivantes pour ajouter les paramètres de variables d'environnement au fichier
~/.zshrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc -
Exécutez la commande suivante pour appliquer les modifications.
source ~/.zshrc -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
Exécutez les commandes suivantes pour ajouter les paramètres de variables d'environnement au fichier
~/.bash_profile.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile -
Exécutez la commande suivante pour appliquer les modifications.
source ~/.bash_profile -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
-
Windows
CMD
-
Exécutez les commandes suivantes dans CMD.
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET" -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
-
Exécutez les commandes suivantes dans PowerShell.
[Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User) -
Exécutez les commandes suivantes pour vérifier que les variables d'environnement sont configurées.
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
Après avoir modifié les variables d'environnement système, redémarrez ou actualisez votre environnement de développement, y compris votre IDE, l'interface en ligne de commande, les autres applications de bureau et les services backend, afin de garantir le chargement correct des dernières variables d'environnement système.
-
Utilisez les variables d'environnement pour transmettre les informations d'identification.
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; public class AkDemoTest { public static void main(String[] args) throws Exception { // Obtain credentials from environment variables. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Use credentialsProvider for subsequent operations... ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Identifiants statiques
L'exemple de code suivant montre comment coder en dur les identifiants d'accès et définir explicitement la paire d'AccessKey à utiliser.
N'intégrez pas d'identifiants d'accès directement dans les applications en environnement de production. Cette méthode est réservée aux tests.
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
public class AkDemoTest {
public static void main(String[] args) throws Exception {
// Enter the AccessKey ID and AccessKey secret of the RAM user.
String accessKeyId = "yourAccessKeyID";
String accessKeySecret = "yourAccessKeySecret";
// Use the DefaultCredentialProvider method to directly set the AccessKey ID and AccessKey secret.
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret);
// Use credentialsProvider to initialize the client.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Explicitly declare the use of the V4 signature algorithm.
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// Create an OSSClient instance.
// When the OSSClient instance is no longer needed, call the shutdown method to release resources.
OSS ossClient = OSSClientBuilder.create()
.endpoint("endpoint")
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region("region")
.build();
ossClient.shutdown();
}
}
Utiliser un token STS
Cette méthode convient aux applications nécessitant un accès temporaire à OSS. Initialisez le fournisseur d'identifiants avec des identifiants temporaires (AccessKey ID, AccessKey secret et security token) provenant du service STS. Vous devez actualiser manuellement le token STS pour les accès ultérieurs.
Pour obtenir rapidement un token STS via une OpenAPI, consultez AssumeRole - Obtenir des identifiants temporaires pour un rôle RAM.
Pour obtenir un token STS à l'aide d'un SDK, reportez-vous à Utiliser un token STS pour accéder à OSS.
Spécifiez une date d'expiration lors de la génération d'un token STS. Le token devient invalide et inutilisable une fois expiré.
Pour consulter la liste des endpoints du service STS, voir Endpoints de service.
Variables d'environnement
-
Définissez les variables d'environnement à l'aide des identifiants temporaires.
Mac OS/Linux/Unix
ImportantVeuillez noter que les identifiants temporaires (AccessKey ID, AccessKey secret et security token) obtenus auprès du service STS sont utilisés ici, et non la paire AccessKey d'un utilisateur RAM.
Notez que l'AccessKey ID fourni par le service STS commence par « STS », par exemple « STS. ».
export OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> export OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> export OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>Windows
ImportantVeuillez noter que les identifiants temporaires (AccessKey ID, AccessKey secret et security token) obtenus auprès du service STS sont utilisés ici, et non la paire AccessKey (AccessKey ID et AccessKey secret) d'un utilisateur RAM.
Notez que l'AccessKey ID fourni par le service STS commence par « STS », par exemple « STS. ».
set OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> set OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> set OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN> -
Transmettez les informations d'identification via les variables d'environnement.
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; public class StsDemoTest { public static void main(String[] args) throws Exception { // Obtain credentials from environment variables. EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider(); // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Identifiants statiques
Vous pouvez coder en dur les identifiants dans votre application et définir explicitement la clé d'accès temporaire à utiliser.
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.aliyun.oss.common.comm.SignVersion;
public class StsDemoTest {
public static void main(String[] args) throws Exception {
// Set this to the temporary AccessKey ID, AccessKey secret, and security token obtained from the STS service, not the credential information of a RAM user.
// Note that the AccessKey ID obtained from the STS service starts with "STS", as shown below.
String accessKeyId = "STS.****************";
String accessKeySecret = "yourAccessKeySecret";
String stsToken= "yourSecurityToken";
// Use the DefaultCredentialProvider method to directly set the AccessKey ID and AccessKey secret.
CredentialsProvider credentialsProvider = new DefaultCredentialProvider(accessKeyId, accessKeySecret, stsToken);
// Use credentialsProvider to initialize the client.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Explicitly declare the use of the V4 signature algorithm.
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// Create an OSSClient instance.
// When the OSSClient instance is no longer needed, call the shutdown method to release resources.
OSS ossClient = OSSClientBuilder.create()
.endpoint("endpoint")
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region("region")
.build();
ossClient.shutdown();
}
}
Utiliser un RAMRoleARN
Recommandé pour les applications nécessitant un accès autorisé à OSS, notamment pour les accès inter-comptes. Initialisez le fournisseur d'identifiants en spécifiant l'ARN d'un rôle RAM. Le SDK obtient et actualise automatiquement les tokens STS en appelant l'API AssumeRole. Utilisez également le paramètre policy pour restreindre les permissions du rôle RAM.
Un compte Alibaba Cloud dispose de toutes les permissions sur ses ressources. La fuite d'une paire AccessKey représente un risque majeur pour votre système. Nous déconseillons l'utilisation de la paire AccessKey d'un compte Alibaba Cloud. Privilégiez plutôt la paire AccessKey d'un utilisateur RAM doté des permissions minimales requises.
Pour créer une paire AccessKey pour un utilisateur RAM, consultez Créer une paire AccessKey. L'AccessKey ID et l'AccessKey secret d'un utilisateur RAM ne s'affichent qu'au moment de la création de la paire. Enregistrez-les immédiatement. En cas d'oubli, vous devrez créer une nouvelle paire AccessKey pour remplacer l'ancienne.
Pour obtenir un RAMRoleARN, reportez-vous à Créer un rôle RAM.
-
Ajoutez la dépendance relative aux identifiants.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configurez la paire AccessKey et le RAMRoleARN comme identifiants d'accès.
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class RamRoleArnAkDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // Type of access credential. Set to ram_role_arn. config.setType("ram_role_arn"); // The ARN of the RAM role to assume. Example: acs:ram::123456789012****:role/adminrole. You can set RoleArn through the ALIBABA_CLOUD_ROLE_ARN environment variable. config.setRoleArn("<RoleArn>"); // Obtain the AccessKey ID from the environment variable. config.setAccessKeyId(System.getenv().get("ALIBABA_CLOUD_ACCESS_KEY_ID")); // Obtain the AccessKey secret from the environment variable. config.setAccessKeySecret(System.getenv().get("ALIBABA_CLOUD_ACCESS_KEY_SECRET")); // The name of the role session. You can set RoleSessionName through the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable. config.setRoleName("<RoleSessionName>"); // Set a smaller permission policy. This is optional. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"} config.setPolicy("<Policy>"); // Set the validity period of the role session. This is optional. config.setRoleSessionExpiration(3600); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Utiliser un ECSRAMRole
Conçu pour les applications hébergées sur des instances ECS, des instances ECI ou des nœuds workers Container Service for Kubernetes. En attachant un rôle RAM à l'instance, les tokens STS sont automatiquement obtenus et actualisés au sein de Container Service for Kubernetes ou d'ECS, sans gestion manuelle des identifiants. Pour obtenir un ECSRAMRole, consultez Créer un rôle RAM. Pour attacher un rôle, voir Rôles RAM d'instance.
-
Ajoutez la dépendance relative aux identifiants.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configurez l'ECSRAMRole comme identifiant d'accès.
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class EcsRamRoleDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // Type of access credential. Set to ecs_ram_role. config.setType("ecs_ram_role"); // The name of the RAM role assigned to the ECS instance. config.setRoleName("<RoleName>"); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Utiliser un OIDCRoleARN
Une fois le rôle RAM du nœud worker configuré dans Container Service for Kubernetes, les applications situées dans les pods de ce nœud peuvent obtenir le token STS du rôle attaché via le service de métadonnées global, à l'instar des applications déployées sur ECS. Toutefois, si des applications non fiables sont déployées sur le cluster de conteneurs (par exemple, des applications soumises par vos clients dont le code ne vous est pas accessible), vous souhaiterez probablement empêcher l'accès au token STS du rôle RAM d'instance du nœud worker via le service de métadonnées global. Afin de préserver la sécurité de vos ressources cloud tout en permettant à ces applications non fiables d'obtenir sécurisément les tokens STS nécessaires et d'appliquer le principe du moindre privilège au niveau applicatif, utilisez la fonctionnalité RAM Roles for Service Accounts (RRSA). Cette méthode repose techniquement sur un token STS. Le cluster de conteneurs Alibaba Cloud crée et monte le fichier de token OIDC du compte de service correspondant pour chaque pod d'application, puis injecte les informations de configuration associées dans les variables d'environnement. Le SDK récupère le token STS du rôle lié en appelant l'opération API AssumeRoleWithOIDC du service STS, à l'aide des informations de configuration issues des variables d'environnement. Cette approche élimine les risques liés à la maintenance manuelle d'une paire AccessKey ou d'un token STS, car aucune fourniture explicite n'est requise. Pour plus d'informations, consultez Configurer les permissions RAM pour un ServiceAccount via RRSA afin d'isoler les permissions des pods.
-
Ajoutez la dépendance relative aux identifiants.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configurez le rôle RAM OIDC comme identifiant d'accès.
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class OidcRoleArnDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // Specify the Credential type. Set to oidc_role_arn. config.setType("oidc_role_arn"); // The ARN of the RAM role. You can set RoleArn through the ALIBABA_CLOUD_ROLE_ARN environment variable. config.setRoleArn("<RoleArn>"); // The ARN of the OIDC provider. You can set OidcProviderArn through the ALIBABA_CLOUD_OIDC_PROVIDER_ARN environment variable. config.setOidcProviderArn("<OidcProviderArn>"); // The path to the OIDC token file. You can set OidcTokenFilePath through the ALIBABA_CLOUD_OIDC_TOKEN_FILE environment variable. config.setOidcTokenFilePath("<OidcTokenFilePath>"); // The name of the role session. You can set RoleSessionName through the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable. config.setRoleSessionName("<RoleSessionName>"); // Set a smaller permission policy. This is optional. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"} config.setPolicy("<Policy>"); // Set the session expiration time. config.setRoleSessionExpiration(3600); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Utiliser les identifiants du contexte Function Compute
Cette méthode s'applique aux fonctions des applications déployées dans Function Compute. Initialisez le fournisseur d'identifiants avec les identifiants issus du contexte Function Compute. L'implémentation sous-jacente repose sur un token STS. Function Compute obtient un token STS en assumant le rôle de service configuré pour la fonction, puis transmet ce token à votre application via le paramètre Credentials du contexte. Ce token STS est valide pendant 36 heures et ne peut pas être modifié. La durée d'exécution maximale d'une fonction étant de 24 heures, le token STS n'expirera pas durant l'exécution ; son actualisation n'est donc pas nécessaire. Cette approche supprime les risques liés à la maintenance manuelle d'une paire AccessKey ou d'un token STS, puisque vous n'avez pas besoin d'en fournir. Pour accorder à Function Compute les permissions d'accès à OSS, consultez Utiliser un rôle de fonction pour accorder à Function Compute des permissions d'accès à d'autres services Alibaba Cloud.
-
Ajoutez la dépendance du contexte Function Compute.
<!-- https://mvnrepository.com/artifact/com.aliyun.fc.runtime/fc-java-core --> <dependency> <groupId>com.aliyun.fc.runtime</groupId> <artifactId>fc-java-core</artifactId> <version>1.4.1</version> </dependency> -
Initialisez le fournisseur d'identifiants avec les identifiants du contexte Function Compute.
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.*; import com.aliyun.oss.common.comm.SignVersion; public class App implements StreamRequestHandler { @Override public void handleRequest( InputStream inputStream, OutputStream outputStream, Context context) throws IOException { // Obtain key information. Before execution, ensure that the service where the function resides is configured with role information, and the role has the necessary OSS permissions. We recommend using the AliyunFCDefaultRole role. Credentials creds = context.getExecutionCredentials(); // Use the obtained credentials to create a credential provider instance. CredentialsProvider credentialsProvider = new DefaultCredentialProvider(creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); outputStream.write(new String("done").getBytes()); } }
Utiliser un CredentialsURI
Plus adapté aux scénarios où les applications récupèrent des identifiants depuis un système externe pour une gestion flexible. Initialisez le fournisseur d'identifiants avec une URI retournant des tokens STS. Le SDK obtient et actualise automatiquement les tokens à partir de l'URI spécifiée.
-
Pour que le SDK puisse analyser et utiliser correctement le token STS, l'URI doit respecter le protocole de réponse suivant :
Code de statut de la réponse : 200
-
Structure du corps de la réponse :
{ "Code": "Success", "AccessKeySecret": "AccessKeySecret", "AccessKeyId": "AccessKeyId", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
-
Ajoutez la dépendance relative aux identifiants.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configurez le CredentialsURI comme identifiant d'accès.
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class CredentialsUriDemoTest { public static void main(String[] args) { com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config(); // Type of access credential. Set to credentials_uri. config.setType("credentials_uri"); // The URI of the credential, which is the address of your server that generates STS tokens, in the format http://local_or_remote_uri/. You can set CredentialsUri through the ALIBABA_CLOUD_CREDENTIALS_URI environment variable. config.setCredentialsUri("<CredentialsUri>"); final com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(config); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Utiliser une paire AccessKey à rotation automatique
Idéal pour les applications nécessitant un accès OSS à long terme dans des environnements présentant un risque de fuite d'AccessKey. Initialisez le fournisseur d'identifiants avec une ClientKey. KMS fait tourner automatiquement la paire AccessKey de l'utilisateur RAM géré, transformant ainsi des identifiants statiques en identifiants dynamiques et réduisant le risque de fuite. KMS prend également en charge la rotation immédiate. Pour obtenir une ClientKey, consultez Créer un point d'accès d'application.
-
Ajoutez la dépendance du client d'identifiants.
<!-- https://mvnrepository.com/artifact/com.aliyun/alibabacloud-secretsmanager-client --> <dependency> <groupId>com.aliyun</groupId> <artifactId>alibabacloud-secretsmanager-client</artifactId> <version>1.3.7</version> </dependency> <!-- https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core --> <dependency> <groupId>com.aliyun</groupId> <artifactId>aliyun-java-sdk-core</artifactId> <version>4.7.0</version> </dependency> -
Créez le fichier de configuration
secretsmanager.properties.# Type of access credential, fixed as client_key credentials_type=client_key # Decryption password for reading the Client Key: supports reading from an environment variable or a file, only one needs to be set client_key_password_from_env_variable=<your client key private key password environment variable name> client_key_password_from_file_path=<your client key private key password file path> # Path to the Client Key's private key file client_key_private_key_path=<your client key private key file path> # Associated KMS service region cache_client_region_id=[{"regionId":"<regionId>"}] -
Utilisez le fichier de configuration pour transmettre les informations d'identification.
import com.aliyun.oss.ClientBuilderConfiguration; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; import com.aliyuncs.kms.secretsmanager.client.SecretCacheClient; import com.aliyuncs.kms.secretsmanager.client.SecretCacheClientBuilder; import com.aliyuncs.kms.secretsmanager.client.exception.CacheSecretException; import com.aliyuncs.kms.secretsmanager.client.model.SecretInfo; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; public class ClientKeyDemoTest { public static void main(String[] args) throws CacheSecretException { final SecretCacheClient client = SecretCacheClientBuilder.newClient(); CredentialsProvider credentialsProvider = new CredentialsProvider() { @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { try { SecretInfo secretInfo = client.getSecretInfo("<secretName>"); JSONObject jsonObject = new JSONObject(secretInfo.getSecretValue()); String accessKeyId = jsonObject.getString("AccessKeyId"); String accessKeySecret = jsonObject.getString("AccessKeySecret"); return new DefaultCredentials(accessKeyId, accessKeySecret); } catch (CacheSecretException | JSONException e) { return null; } } }; // Use credentialsProvider to initialize the client. ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
Utiliser un identifiant d'accès personnalisé
Si aucune des méthodes de configuration précédentes ne répond à vos besoins, personnalisez le fournisseur d'identifiants en implémentant l'interface Credential Providers. Notez que si l'implémentation sous-jacente repose sur un token STS, vous devez prévoir la prise en charge de l'actualisation des identifiants.
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.auth.Credentials;
import com.aliyun.oss.common.auth.CredentialsProvider;
import com.aliyun.oss.common.auth.DefaultCredentials;
import com.aliyun.oss.common.comm.SignVersion;
public class CustomCredentialProviderDemoTest {
public static void main(String[] args) {
CredentialsProvider credentialsProvider = new CredentialsProvider(){
// Initialize variable
String accessKeyId = null;
// Initialize variable
String accessKeySecrect = null;
// Initialize variable
// String token = null;
@Override
public void setCredentials(Credentials credentials) {
}
@Override
public Credentials getCredentials() {
//TODO
//Customize the method for obtaining access credentials.
// Return long-term credentials: access_key_id, access_key_secrect
return new DefaultCredentials(accessKeyId, accessKeySecrect);
// Return temporary credentials: access_key_id, access_key_secrect, token
// For temporary credentials, you need to refresh them based on their expiration time.
// return new DefaultCredentials(accessKeyId, accessKeySecrect, token);
}
};
// Use credentialsProvider to initialize the client.
ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
// Explicitly declare the use of the V4 signature algorithm.
clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);
// Create an OSSClient instance.
// When the OSSClient instance is no longer needed, call the shutdown method to release resources.
OSS ossClient = OSSClientBuilder.create()
.endpoint("endpoint")
.credentialsProvider(credentialsProvider)
.clientConfiguration(clientBuilderConfiguration)
.region("region")
.build();
ossClient.shutdown();
}
}
Utiliser la chaîne d'identifiants par défaut
Lorsque vous initialisez le client d'identifiants sans paramètres, le SDK utilise la chaîne d'identifiants par défaut. Pour plus de détails sur la logique de cette chaîne, consultez Chaîne d'identifiants par défaut.
-
Ajoutez la dépendance relative aux identifiants.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configurez Credentials comme identifiant d'accès.
import com.aliyun.credentials.models.CredentialModel; import com.aliyun.oss.*; import com.aliyun.oss.common.auth.Credentials; import com.aliyun.oss.common.auth.CredentialsProvider; import com.aliyun.oss.common.auth.DefaultCredentials; import com.aliyun.oss.common.comm.SignVersion; public class Demo { public static void main(String[] args) { com.aliyun.credentials.Client credentialsClient = new com.aliyun.credentials.Client(); CredentialsProvider credentialsProvider = new CredentialsProvider(){ @Override public void setCredentials(Credentials credentials) { } @Override public Credentials getCredentials() { CredentialModel credential = credentialsClient.getCredential(); return new DefaultCredentials(credential.getAccessKeyId(), credential.getAccessKeySecret(), credential.getSecurityToken()); } }; ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration(); // Explicitly declare the use of the V4 signature algorithm. clientBuilderConfiguration.setSignatureVersion(SignVersion.V4); // Use credentialsProvider to initialize the client. // Create an OSSClient instance. // When the OSSClient instance is no longer needed, call the shutdown method to release resources. OSS ossClient = OSSClientBuilder.create() .endpoint("endpoint") .credentialsProvider(credentialsProvider) .clientConfiguration(clientBuilderConfiguration) .region("region") .build(); ossClient.shutdown(); } }
FAQ
Conflits de packages
-
Cause
Lors de l'utilisation du SDK Java OSS V1, une erreur similaire à celle ci-dessous indique un conflit de packages dans votre projet.
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/ssl/TrustStrategy at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:77) Caused by: java.lang.ClassNotFoundException: org.apache.http.ssl.TrustStrategy at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 3 moreou
Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:52) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<init>(DefaultHttpRequestWriterFactory.java:56) at org.apache.http.impl.io.DefaultHttpRequestWriterFactory.<clinit>(DefaultHttpRequestWriterFactory.java:46) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:82) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:95) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<init>(ManagedHttpClientConnectionFactory.java:104) at org.apache.http.impl.conn.ManagedHttpClientConnectionFactory.<clinit>(ManagedHttpClientConnectionFactory.java:62) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$InternalConnectionFactory.<init>(PoolingHttpClientConnectionManager.java:572) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:174) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:158) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:149) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.<init>(PoolingHttpClientConnectionManager.java:125) at com.aliyun.oss.common.comm.DefaultServiceClient.createHttpClientConnectionManager(DefaultServiceClient.java:237) at com.aliyun.oss.common.comm.DefaultServiceClient.<init>(DefaultServiceClient.java:78) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at OSSManagerImpl.upload(OSSManagerImpl.java:42) at OSSManagerImpl.main(OSSManagerImpl.java:63)Cette erreur survient car le SDK Java OSS V1 utilise Apache HttpClient 4.4.1, alors que votre projet emploie une version conflictuelle d'Apache HttpClient ou un package JAR commons-httpclient. Exécutez la commande
mvn dependency:treedans le répertoire de votre projet pour afficher les packages JAR utilisés ainsi que leurs versions. Le projet utilise ici Apache HttpClient 4.3, ce qui crée un conflit avec la version standard :[INFO] --- maven-dependency-plugin:2.2:tree (default-cli) @ maven-demo --- [INFO] com.aliyun.oss:maven-demo:jar:0.1.1-SNAPSHOT [INFO] +- junit:junit:jar:4.10:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.1:test [INFO] +- org.apache.httpcomponents:httpclient:jar:4.3:compile [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.3:compile [INFO] | +- commons-logging:commons-logging:jar:1.1.3:compile [INFO] | \- commons-codec:commons-codec:jar:1.6:compile [INFO] \- com.aliyun.oss:aliyun-sdk-oss:jar:2.2.1:compile [INFO] +- org.jdom:jdom:jar:1.1:compile [INFO] \- net.sf.json-lib:json-lib:jar:jdk15:2.4:compile [INFO] +- commons-beanutils:commons-beanutils:jar:1.8.0:compile [INFO] +- commons-collections:commons-collections:jar:3.2.1:compile [INFO] +- commons-lang:commons-lang:jar:2.5:compile [INFO] \- net.sf.ezmorph:ezmorph:jar:1.0.6:compile -
Solution
Résolvez les conflits de packages selon l'une des deux méthodes suivantes :
Uniformiser la version : Si votre projet utilise une version entrant en conflit avec Apache HttpClient 4.4.1, mettez-le à jour vers la version 4.4.1 et supprimez les dépendances vers d'autres versions d'Apache HttpClient dans le fichier
pom.xml. L'utilisation de commons-httpclient peut également provoquer un conflit ; supprimez alors cette dépendance.Résoudre les conflits de dépendances : Si votre projet dépend de plusieurs packages tiers qui requièrent eux-mêmes différentes versions d'Apache HttpClient, des conflits de dépendances apparaîtront. Utilisez la balise d'exclusion pour les résoudre. Pour plus d'informations, consultez Guides Maven.
Le SDK Java OSS V1 dépend des versions de packages suivantes. La méthode de résolution des conflits est identique à celle décrite pour HttpClient.
[INFO] com.aliyun.oss:maven-demo:jar:0.1.1-SNAPSHOT [INFO] +- junit:junit:jar:4.10:test [INFO] | \- org.hamcrest:hamcrest-core:jar:1.1:test [INFO] \- com.aliyun.oss:aliyun-sdk-oss:jar:2.2.1:compile [INFO] +- org.apache.httpcomponents:httpclient:jar:4.4.1:compile [INFO] | +- org.apache.httpcomponents:httpcore:jar:4.4.1:compile [INFO] | +- commons-logging:commons-logging:jar:1.2:compile [INFO] | \- commons-codec:commons-codec:jar:1.9:compile [INFO] +- org.jdom:jdom:jar:1.1:compile [INFO] \- net.sf.json-lib:json-lib:jar:jdk15:2.4:compile [INFO] +- commons-beanutils:commons-beanutils:jar:1.8.0:compile [INFO] +- commons-collections:commons-collections:jar:3.2.1:compile [INFO] +- commons-lang:commons-lang:jar:2.5:compile [INFO] \- net.sf.ezmorph:ezmorph:jar:1.0.6:compile
Packages manquants
-
Cause
Lors de l'utilisation d'OSS Java SDK V1, une erreur similaire à celle ci-dessous indique que des packages nécessaires à la compilation ou à l'exécution du SDK sont probablement absents de votre projet.
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/auth/Credentials at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:76) Caused by: java.lang.ClassNotFoundException: org.apache.http.auth.Credentials at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 3 moreou
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/http/protocol/HttpContext at com.aliyun.oss.OSSClient.<init>(OSSClient.java:268) at com.aliyun.oss.OSSClient.<init>(OSSClient.java:193) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:76) Caused by: java.lang.ClassNotFoundException: org.apache.http.protocol.HttpContext at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 3 moreou
Exception in thread "main" java.lang.NoClassDefFoundError: org/jdom/input/SAXBuilder at com.aliyun.oss.internal.ResponseParsers.getXmlRootElement(ResponseParsers.java:645) at … … at com.aliyun.oss.OSSClient.doesBucketExist(OSSClient.java:471) at com.aliyun.oss.OSSClient.doesBucketExist(OSSClient.java:465) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:82) Caused by: java.lang.ClassNotFoundException: org.jdom.input.SAXBuilder at java.net.URLClassLoader$1.run(URLClassLoader.java:366) at java.net.URLClassLoader$1.run(URLClassLoader.java:355) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:354) at java.lang.ClassLoader.loadClass(ClassLoader.java:425) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) at java.lang.ClassLoader.loadClass(ClassLoader.java:358) ... 11 moreOSS Java SDK V1 dépend des packages suivants :
aliyun-sdk-oss-2.2.1.jar
hamcrest-core-1.1.jar
jdom-1.1.jar
commons-codec-1.9.jar
httpclient-4.4.1.jar
commons-logging-1.2.jar
httpcore-4.4.1.jar
log4j-1.2.15.jar
Parmi ceux-ci, log4j-1.2.15.jar est une dépendance facultative. N'ajoutez ce package que si vous avez besoin des fonctionnalités de journalisation. Les autres packages sont obligatoires.
-
Solution
Ajoutez les packages dont dépend OSS Java SDK V1 à votre projet. Utilisez l'une des méthodes suivantes :
Projet Eclipse : consultez Installer le SDK.
Projet Ant : placez les packages requis par OSS Java SDK V1 dans le répertoire lib de votre projet.
Compilation directe : utilisez la commande
-classpathou-cppour spécifier le chemin des packages dont dépend OSS Java SDK V1, ou placez ces packages dans le classpath.
Expiration de la connexion
-
Cause
Lors de l'exécution d'un programme OSS Java SDK V1, une erreur similaire à celle ci-dessous peut survenir en raison d'un endpoint incorrect ou de problèmes de connectivité réseau.
com.aliyun.oss.ClientException: SocketException at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:71) at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:116) at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:121) at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:67) at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:92) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:140) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:111) at com.aliyun.oss.internal.OSSBucketOperation.getBucketInfo(OSSBucketOperation.java:1152) at com.aliyun.oss.OSSClient.getBucketInfo(OSSClient.java:1220) at com.aliyun.oss.OSSClient.getBucketInfo(OSSClient.java:1214) at com.aliyun.oss.demo.HelloOSS.main(HelloOSS.java:94) Caused by: org.apache.http.conn.HttpHostConnectException: Connect to oss-test.oss-cn-hangzhou-internal.aliyuncs.com:80 [oss-test.oss-cn-hangzhou-internal.aliyuncs.com/10.84.135.99] failed: Connection timed out: connect at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:151) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:353) at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:380) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:113) ... 9 more -
Solution
Utilisez l'outil ossutil pour identifier rapidement la cause de l'erreur et résoudre le problème.
Erreur SignatureDoesNotMatch
-
Cause 1 : Informations de paire AccessKey incompatibles
L'AccessKey ID et l'AccessKey secret ne correspondent pas. Pour savoir comment obtenir une paire AccessKey, consultez Créer une paire AccessKey.
-
Cause 2 : Utilisation incorrecte d'une URL signée
Voici un exemple incorrect d'utilisation d'une URL signée :
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, object); request.setExpiration( new Date(new Date().getTime() + 3600 * 1000)); request.addUserMetadata("author"); URL url = ossClient.generatePresignedUrl(request); Map<String, String> header = new HashMap<String, String>(); header.put("author"); ossClient.putObject(url, new ByteArrayInputStream("Hello OSS".getBytes()), -1, header);Si le paramètre Method n'est pas spécifié, la méthode GET est utilisée par défaut. Or, l'exemple précédent correspond à une requête PutObject. Par conséquent, le paramètre Method doit être spécifié et défini sur PUT.
Lors de l'envoi d'une requête PutObject, les métadonnées personnalisées dans l'en-tête de la requête doivent être préfixées par
x-oss-meta-. Dans l'exemple ci-dessus, la métadonnée personnalisée devrait être modifiée enx-oss-meta-author.Solution : Spécifiez le paramètre Method et modifiez le préfixe de l'en-tête.
request.addUserMetadata("author"); request.setMethod(HttpMethod.PUT); URL url = ossClient.generatePresignedUrl(request); Map<String, String> header = new HashMap<String, String>(); header.put("x-oss-meta-" + "author"); ossClient.putObject(url, new ByteArrayInputStream("Hello OSS".getBytes()), -1, header); -
Cause 3 : Problème de compatibilité de version HttpClient
Une version d'OSS SDK antérieure à 3.7.0 est utilisée, tandis que HttpClient 4.5.9 ou ultérieur a été introduit dans le projet.
Le nom du fichier téléchargé contient un caractère
+, or HttpClient 4.5.9 n'encode pas l'URL du caractère+. Cela entraîne une incohérence entre les signatures calculées par le client et le serveur.
320 POST /a HTTP/1.1 (application/json) 107 HTTP/1.1 200 (application/json) 453 PUT /%E4%B8%AD%E6%96%87%2B%E6%B5%8B%E8%AF%95 HTTP/1.1 375 HTTP/1.1 200 OK 364 POST /p HTTP/1.1 (application/json) 1108 HTTP/1.1 200 (application/json) 1017 POST /a HTTP/1.1 (application/json) 107 HTTP/1.1 200 (application/json) 450 PUT /%E4%B8%AD%E6%96%87+%E6%B5%8B%E8%AF%95 HTTP/1.1 1183 HTTP/1.1 403 Forbidden 325 POST /a HTTP/1.1 (application/json) 107 HTTP/1.1 200 (application/json)Solution : Adoptez l'une des méthodes suivantes.
Mettez à niveau OSS SDK vers la version 3.11.1 ou ultérieure pour assurer la compatibilité avec HttpClient 4.5.9.
Supprimez les dépendances HttpClient redondantes. L'introduction d'OSS SDK inclut automatiquement la dépendance HttpClient. Si une bibliothèque tierce introduit également HttpClient, reportez-vous à la solution décrite dans Conflits de packages.
-
Cause 4 : Problème de compatibilité de jeu de caractères HttpClient
HttpClient 4.5.10 ne prend pas en charge les caractères hors norme ISO-8859-1 dans l'en-tête. Dans un projet utilisant une version de HttpClient postérieure à 4.5.10, un problème survient si l'en-tête de la requête contient des caractères non conformes à la norme ISO-8859-1, tels que des caractères chinois dans des métadonnées personnalisées commençant par
x-oss-meta-.String content = "123"; ObjectMetadata metadata = new ObjectMetadata(); metadata.setHeader("x-oss-meta-filename", "xxx"); PutObjectRequest request = new PutObjectRequest(bucketName, objectName, new ByteArrayInputStream(content.getBytes())); request.setMetadata(metadata); ossClient.putObject(request);Solution : Appliquez l'une des méthodes suivantes.
Suivez la procédure indiquée dans Conflits de packages pour supprimer la version conflictuelle de HttpClient.
N'utilisez que des caractères conformes à la norme ISO-8859-1 dans l'en-tête de la requête.
Exception « Failed to parse the response result »
com.aliyun.oss.OSSException: Failed to parse the response result.
[ErrorCode]: InvalidResponse
[RequestId]: null
[HostId]: null
at com.aliyun.oss.common.utils.ExceptionFactory.createOSSException(ExceptionFactory.java:109)
at com.aliyun.oss.common.utils.ExceptionFactory.createInvalidResponseException(ExceptionFactory.java:91)
at com.aliyun.oss.common.utils.ExceptionFactory.createInvalidResponseException(ExceptionFactory.java:81)
at com.aliyun.oss.internal.OSSErrorResponseHandler.handle(OSSErrorResponseHandler.java:71)
at com.aliyun.oss.common.comm.ServiceClient.handleResponse(ServiceClient.java:248)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:130)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:149)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:273)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:301)
at com.aliyun.oss.OSSClient.getObject(OSSClient.java:545)
-
Cause
Un logiciel spécifique côté client intercepte la requête HTTP, ou bien un routage sur le réseau public détourne cette requête.
Vous utilisez OSS Java SDK V1 sur Java 9 ou ultérieur sans avoir ajouté les dépendances liées à JAXB dans le fichier pom.xml.
-
Solution
Passez à une requête HTTPS.
Ajoutez les dépendances relatives à JAXB. Pour connaître la procédure, consultez Installer le SDK.
org.apache.http.NoHttpResponseException : Le serveur cible n'a pas répondu
-
Cause
L'exécution d'un programme OSS Java SDK V1 génère une erreur semblable à celle-ci :
com.aliyun.oss.ClientException: Unknown at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:68) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:115) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:121) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:67) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:92) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:140) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:111) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.internal.OSSMultipartOperation.initiateMultipartUpload(OSSMultipartOperation.java:206) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.aliyun.oss.OSSClient.initiateMultipartUpload(OSSClient.java:765) ~[aliyun-sdk-oss-2.1.0.jar:na] at com.taobao.agoo.dump.client.OssTools.multipartUpload(OssTools.java:79) ~[agoo-dump-client-2.0.0-SNAPSHOT.jar:na] at com.taobao.agoo.dump.biz.manager.TaskExecutorManager$UploadTask.run(TaskExecutorManager.java:114) ~[agoo-dump-biz-2.0.0-SNAPSHOT.jar:na] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [na:1.7.0_51] at java.util.concurrent.FutureTask.run(FutureTask.java:262) [na:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [na:1.7.0_51] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [na:1.7.0_51] at java.lang.Thread.run(Thread.java:744) [na:1.7.0_51] Caused by: org.apache.http.NoHttpResponseException: The target server failed to respond at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:143) ~[httpclient-4.4.jar:4.4] at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:57) ~[httpclient-4.4.jar:4.4] at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:261) ~[httpcore-4.4.jar:4.4] at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:165) ~[httpcore-4.4.jar:4.4] at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:167) ~[httpclient-4.4.jar:4.4] at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:272) ~[httpcore-4.4.jar:4.4]Cette erreur provient de l'utilisation d'une connexion expirée. Elle ne se produit que dans les versions de Java SDK antérieures à 2.1.2.
-
Solution
Mettez à niveau OSS Java SDK V1 vers la version 2.1.2 ou ultérieure.
Présence de nombreuses instances org.apache.http.impl.conn.PoolingHttpClientConnectionManager dans la JVM
-
Cause
L'ossClient n'a pas été fermé correctement.
-
Solution
Fermez l'ossClient une fois son exécution terminée, ou adoptez le modèle singleton.
Absence de réponse lors d'un appel OSS Java SDK V1
-
Cause
Un appel OSS Java SDK V1 ne répond pas. En exécutant la commande
jstack -l pidpour inspecter la pile, vous pouvez localiser le problème à l'emplacement suivant :"main" prio=6 tid=0x000000000291e000 nid=0xc40 waiting on condition [0x0000000002dae000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007d85697f8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043) at org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:138) at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:306) at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64) at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:192) at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:185) at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:107) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:276) at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:263) at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:190) at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184) at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110) at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184) at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82) at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:113) at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:123) at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68) at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:146) at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113) at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:229) at com.aliyun.oss.OSSClient.getObject(OSSClient.java:629) at com.aliyun.oss.OSSClient.getObject(OSSClient.java:617) at samples.HelloOSS.main(HelloOSS.java:49)La cause est une fuite de connexions dans le pool, probablement due à une fermeture incorrecte de l'ossObject après utilisation.
-
Solution
Vérifiez votre programme afin de garantir l'absence de fuites de connexions. Utilisez la méthode suivante pour fermer correctement la connexion :
// Read the file. OSSObject ossObject = ossClient.getObject(bucketName, objectName); // OSS operation // Close ossObject. ossObject.close();Pour des étapes détaillées de dépannage, consultez Dépanner l'absence de réponse d'OSS Java SDK V1.
Connexion fermée
-
Cause
Si vous rencontrez une erreur similaire à celle ci-dessous lors de l'utilisation de ossClient.getObject :
Exception in thread "main" org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 11990526; received: 202880) at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:180) at org.apache.http.impl.io.ContentLengthInputStream.read(ContentLengthInputStream.java:200) at org.apache.http.impl.io.ContentLengthInputStream.close(ContentLengthInputStream.java:103) at org.apache.http.impl.execchain.ResponseEntityProxy.streamClosed(ResponseEntityProxy.java:128) at org.apache.http.conn.EofSensorInputStream.checkClose(EofSensorInputStream.java:228) at org.apache.http.conn.EofSensorInputStream.close(EofSensorInputStream.java:174) at java.io.FilterInputStream.close(FilterInputStream.java:181) at java.io.FilterInputStream.close(FilterInputStream.java:181) at com.aliyun.oss.event.ProgressInputStream.close(ProgressInputStream.java:147) at java.io.FilterInputStream.close(FilterInputStream.java:181) at samples.HelloOSS.main(HelloOSS.java:39)Cela s'explique par un intervalle supérieur à 1 minute entre deux lectures de données. OSS ferme en effet les connexions inactives depuis plus d'une minute.
-
Solution
Si vous ne lisez qu'une partie des données à chaque fois et que le temps de traitement varie, utilisez le téléchargement par plage pour éviter la fermeture de la connexion. La connexion se ferme automatiquement une fois le téléchargement par plage terminé. Téléchargement par plage (OSS Java SDK V1).
Fuite de mémoire
-
Cause
Un programme appelant OSS Java SDK V1 présente une fuite de mémoire après une certaine période d'exécution (de quelques heures à quelques jours, selon le volume d'activité). Nous vous recommandons d'utiliser Eclipse Memory Analyzer (MAT) pour analyser l'utilisation de la mémoire. Pour plus d'informations, consultez Analyser les fichiers de vidage de tas avec MAT.
Si le résultat de l'analyse ressemble à la figure ci-dessous (PoolingHttpClientConnectionManager occupe 96 % de la mémoire), cela signifie que
new OSSClienta probablement été exécuté plusieurs fois dans le programme sans appel àossClient.shutdown, ce qui a provoqué la fuite de mémoire.
-
Solution
Une fois l'opération
new OSSClientterminée, appelez la méthodeshutdownpour le fermer. Assurez-vous d'utilisernew OSSClientetossClient.shutdownpar paires.
InterruptedException signalée lors de l'appel à ossClient.shutdown
-
Cause
Les versions d'OSS Java SDK V1 antérieures à 2.3.0 renvoient l'exception suivante lors de l'appel à
ossClient.shutdown:java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.aliyun.oss.common.comm.IdleConnectionReaper.run(IdleConnectionReaper:76)Cela est dû au fait que le thread d'arrière-plan IdleConnectionReaper de l'ossClient ferme périodiquement les connexions inactives. Si ossClient.shutdown est appelé alors qu'IdleConnectionReaper est en veille (Sleep), l'exception ci-dessus est levée.
-
Solution
Utilisez le code suivant pour ignorer l'exception :
try { ossClient.shutdown(); } catch(Exception e) { }
Exception « SDK.ServerUnreachable : Speicified endpoint or uri is not valid »
SunshineE/android/01040181-2018-05-07173747-860769-online=1.jpg</cloudUrl><fileSize>4096</fileSize><lossName/><loss
...skipping...
com.aliyuncs.exceptions.ClientException: SDK.ServerUnreachable : Speicified endpoint or uri is not valid.
at com.aliyuncs.DefaultAcsClient.doAction(DefaultAcsClient.java:201)
at com.aliyuncs.DefaultAcsClient.doAction(DefaultAcsClient.java:151)
at com.aliyuncs.DefaultAcsClient.doAction(DefaultAcsClient.java:59)
at com.aliyuncs.DefaultAcsClient.getAcsResponse(DefaultAcsClient.java:103)
at com.sunyard.insurance.oss.aliyun.GetSts.assumeRole(GetSts.java:50)
at com.sunyard.insurance.oss.aliyun.GetSts.getSts(GetSts.java:60)
at com.sunyard.insurance.ecm.web.action.oss.OssInfoAction.getUpOssInfo(OssInfoAction.java:259)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
-
Cause
Le client envoie trop de requêtes simultanées à STS.
La connexion réseau au serveur expire.
Le SDK STS et le noyau SDK utilisés ne sont pas aux dernières versions.
-
Solution
Réduisez la concurrence OSS. Si le client envoie trop de requêtes simultanées à STS, il est possible que l'instance ECS du client ou l'ordinateur local ne puisse pas gérer la charge.
La connexion réseau entre l'utilisateur et le serveur a expiré. Vous pouvez effectuer une capture de paquets pour le vérifier.
Mettez à niveau le SDK STS et le noyau SDK vers leurs dernières versions.
NoSuchKey
case:java.lang.Exception: com.aliyun.oss.OSSException:
Not Foundn[ErrorCode]: NoSuchKeyn
-
Cause
Le fichier source n'existe pas.
-
Solution
Consultez Erreur 404.
SocketException
2018-10-10 16:21:11,127 ERROR com.qunhe.instdeco.plan.maxservice.convert.Converter
downloadOssObject:taskId:LO63HXQKN4BMWM4BAU888888:
com.aliyun.oss.ClientException: SocketException
at com.aliyun.oss.common.utils.ExceptionFactory.createNetworkException(ExceptionFactory.java:71)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:128)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:123)
at com.aliyun.oss.common.comm.ServiceClient.sendRequest(ServiceClient.java:68)
at com.aliyun.oss.internal.OSSOperation.send(OSSOperation.java:94)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:149)
at com.aliyun.oss.internal.OSSOperation.doOperation(OSSOperation.java:113)
at com.aliyun.oss.internal.OSSObjectOperation.getObject(OSSObjectOperation.java:273)
-
Cause
Le socket a pu rencontrer une défaillance lors de la phase d'initialisation, entraînant l'échec de la requête avant même qu'elle n'atteigne OSS.
-
Solution
Nous vous recommandons de vérifier les points suivants :
Des instabilités réseau sont-elles survenues au moment du problème ?
Le nombre de connexions socket sur l'hôte a-t-il atteint sa limite ?
Vérifiez si le nombre de connexions dépassait le paramètre maxconnection du SDK lorsque le problème est survenu. Un dépassement de cette limite provoque également une exception socket.
Si aucun problème n'est détecté parmi les points ci-dessus, nous vous conseillons de déployer tcpdump ou Wireshark pour capturer les paquets, puis d'analyser ces données après la reproduction du problème.
Le callback d'OSS PostObject ne se déclenche pas
Le callback d'OSS PostObject ne se déclenche pas, alors que le même callback fonctionne avec PutObject. En général, si le format JSON est incorrect ou si le callback échoue, un message correspondant est renvoyé. Dans ce cas, vous devez tester séparément le comportement des callbacks Put et Post :
La capture Wireshark suivante montre une requête HTTP POST de callback OSS ainsi que la réponse du serveur :
POST /RevIce.ashx HTTP/1.1
Host: 47.xx.xxx.168
Connection: close
Content-Length: xxx
Authorization: xxx
Content-MD5: KdeBTxxx
Content-Type: appli...
User-Agent: aliyun-xxx
x-oss-additional-he...
x-oss-bucket: null8
x-owner: A4A64...
x-oss-pub-key-url: xxx
x-oss-request-id: xxx
x-oss-signature-ver...
x-oss-tag: CALLBACK
eagleye-rpcid: 0.1
bucket: xxx
HTTP/1.1 200 OK
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/plain
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 12 Feb 2018 02:52:44 GMT
Connection: close
{"a":"b"}
-
Cause
Lors de l'envoi de la requête, le paramètre
callbackest incorrectement placé à l'intérieur du paramètrefile.LTAI*xxx --94311149156168 Content-Disposition: form-data; name="policy" eyjleHBpcmF0aW9UIjogIjIxMjAtMDEtMDFU --94311149156168 Content-Disposition: form-data; name="Signature" gncf07Apde0vqaMWBto18XxzoH0= --94311149156168 Content-Disposition: form-data; name="file"; filename="1.txt" Content-Type: text/plain --94311149156168 Content-Disposition: form-data; name="callback" eyJ3YWxsYmFja1VybCI6Imh0dHA6Ly9vc3MtZGVtby5hbGl5dW5jcy5jb20eyJ3YWxsYmFja1VybCI6ImhxMTYxMTYxNjE2MTYxNjE2 12345678910 --94311149156168-- HTTP/1.1 204 No Content Server: AliyunOSS Date: xxx -
Solution
Ajustez la position des paramètres callback et file.
Content-Disposition: form-data; name="policy" eyjleHBpcmF0aW9uIjogIjIxMjAtMDEtMDFUMTI6MDA6MDAuMDAwWiIs]xxx --9431149156168 Content-Disposition: form-data; name="Signature" gncf07Apde0vqaMWBtol8XxzoH0= --9431149156168 Content-Disposition: form-data; name="callback" eyJjYWxsYmFja1VybCI6Imh0dHA6Ly80xxx MTYuMTY4LjFxxxIn0= --9431149156168 Content-Disposition: form-data; name="file"; filename="1.txt" Content-Type: text/plain 12345678910 --9431149156168-- HTTP/1.1 200 OK Server: AliyunOSS Date: Mon, 12 Feb 2018 06:39:22 GMT Content-Type: application/jsonÀ ce stade, le résultat du test montre que le serveur métier a bien capturé la requête.
POST /Revice.ashx HTTP/1.1 Host: 47.93.116.168 Connection: close Content-Length: 26 Authorization: kn8kVDJOdte9CHcRX1=xxx Content-Type: application/x-www-xxx Date: Mon, 12 Feb 2018 06:40:54 User-Agent: aliyun-oss-callback x-oss-additional-headers: x-oss-bucket: ruide x-oss-owner: 44414 x-oss-pub-key-url: aHR0cHM6Ly9nb2xxx...SuZN= x-oss-request-id: 5A8136F6002618Hxxx x-oss-requester: 232379785371xxx x-oss-signature-version: 1.0 x-oss-tag: CALLBACK eagleeye-rpcid: 0.1 {"bucket"=ruide,"size"=11} HTTP/1.1 200 OK Cache-Control: private Transfer-Encoding: chunked Content-Type: text/plain Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Mon, 12 Feb 2018 06:40:54 GMT Connection: close {"a":"b"}
Connection pool shut down
Caused by: java.lang.IllegalStateException: Connection pool shut down
at org.apache.http.util.Asserts.check(Asserts.java:34)
at org.apache.http.pool.AbstractConnPool.lease(AbstractConnPool.java:184)
at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.requestConnection(PoolingHttpClientConnectionManager.java:251)
at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:175)
at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:184)
at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
at com.aliyun.oss.common.comm.DefaultServiceClient.sendRequestCore(DefaultServiceClient.java:124)
at com.aliyun.oss.common.comm.ServiceClient.sendRequestImpl(ServiceClient.java:133)
... 8 more
-
Cause
Vous continuez à envoyer des requêtes via ossClient après avoir appelé la méthode
ossClient.shutdown(). -
Solution
Vérifiez votre logique d'appel pour vous assurer qu'après l'appel à la méthode
ossClient.shutdown(), vous n'envoyez plus de requêtes via ossClient.
Erreur « Request has expired » pour les requêtes générées par generatePresignedUrl du SDK Java
-
Cause
Un débordement d'entier entraîne un problème d'horodatage lié au bogue de l'an 2038.
Une requête de téléchargement est lancée après l'heure d'expiration définie pour l'URL.
-
Solution
En cas de débordement d'entier, nous vous recommandons de ne pas définir une durée d'expiration dans le SDK Java au-delà de l'année 2038.
Si une requête de téléchargement est initiée après l'heure d'expiration définie pour l'URL, définissez une heure d'expiration appropriée afin qu'elle soit postérieure à l'heure de lancement de la requête.
Erreur « Invalid Response » ou « Implementation of JAXB-API has not been found on module path or classpath »
-
Cause
Vous utilisez Java 9 ou une version ultérieure et n'avez pas ajouté la dépendance JAXB.
-
Solution
Pour savoir comment ajouter la dépendance JAXB, consultez Installer le SDK.
OSSClient dans OSS Java SDK V1 est-il thread-safe ?
OSSClient est thread-safe, ce qui permet à plusieurs threads d'accéder à la même instance. Selon vos besoins métier, vous pouvez réutiliser une seule instance OSSClient ou en créer plusieurs.
Une instance OSSClient gère un pool de connexions en interne. Lorsqu'une instance OSSClient n'est plus nécessaire, vous devez appeler la méthode shutdown pour la fermer et éviter l'épuisement des ressources lié à la création d'un trop grand nombre d'instances.
Signalement de l'erreur « AccessDenied Hierarchical namespace is disabled »
-
Cause
Le hierarchical namespace n'était pas activé avant l'appel à l'opération d'API CreateDirectory, Rename ou DeleteDirectory.
-
Solution
Activez le hierarchical namespace lors de la création d'un bucket. Pour connaître la procédure détaillée, consultez Créer un bucket.
Le réseau client est normal, mais une erreur « Connection reset » survient lors de l'accès HTTP. Comment procéder ?
Les opérateurs de certaines régions peuvent détourner le nom de domaine OSS. Configurez HTTPS via l'endpoint. Configurer le client.
Java 17 Impossible d'invoquer « java.lang.reflect.Method.invoke(Object, Object[]) » car « com.sun.xml.bind.v2.runtime.reflect.opt.Injector.defineClass » est nul
-
Cause
JAXB a été marqué comme obsolète dans Java 9 et supprimé dans Java 11.
-
Solution
Ajoutez les dépendances suivantes :
<dependency> <groupId>com.sun.xml.bind</groupId> <artifactId>jaxb-impl</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>com.sun.xml.messaging.saaj</groupId> <artifactId>saaj-impl</artifactId> <version>1.5.1</version> </dependency>
Comment configurer l'impression des journaux internes pour le SDK Java ?
Le SDK Java s'appuie sur le framework Apache Commons Logging (JCL) pour l'impression des journaux. JCL prend en charge plusieurs frameworks d'implémentation de journalisation. Pour plus d'informations, consultez la section JCL-Configuration. Les implémentations les plus courantes sont JCL over log4j et JCL over SLF4j. Voici leurs méthodes de mise en œuvre :
JCL over log4j : Ajoutez la dépendance log4j (log4j 2.x propose plusieurs frameworks d'implémentation, dont log4j-api+log4j-core par défaut), puis configurez-la selon la méthode propre à log4j. Pour connaître la procédure détaillée, reportez-vous à APACHE LOG4J-API Separation.
JCL over slf4j : Intégrez les dépendances jcl-over-slf4j et slf4j (slf4j offre également plusieurs choix d'implémentation, tels que slf4j-api+logback-classic) et appliquez la configuration correspondante. Consultez SJF4J-Bridging legacy APIs pour obtenir les instructions complètes.
Apache Log4j définit différents niveaux de journalisation : OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE et ALL.
Configurez les propriétés log4j pour activer ou désactiver les journaux du SDK :
#
log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender
log4j.appender.DRFA.File=${ossdemo.log.dir}/${ossdemo.log.file}
# Rollver at midnight
log4j.appender.DRFA.DatePattern=.yyyy-MM-dd
# 30-day backup
#log4j.appender.DRFA.MaxBackupIndex=30
log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout
# Pattern format: Date LogLevel LoggerName LogMessage
log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
# Debugging Pattern format
#log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n
#
# console
# Add "console" to rootlogger above if you want to use this
#
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n
log4j.logger.org.apache.http=off
# oss log level
log4j.logger.com.aliyun.oss=DEBUG
Mise à niveau vers OSS Java SDK V2
OSS Java SDK V2 est désormais disponible. Cette version offre une API simplifiée ainsi que des mécanismes de nouvelle tentative améliorés. Pour migrer de la V1 vers la V2, consultez le Guide de migration de Java SDK V1 vers V2.