Integração rápida
Para integrar o OSS Java SDK V1:
Prepare o ambiente
Instale o Java 7 ou superior. Execute o comando java -version para verificar sua versão do Java. Caso o Java não esteja instalado ou sua versão seja anterior à 7, baixe o Java.
Instale o SDK
Escolha um método de instalação adequado ao seu ambiente. Utilize a versão mais recente do OSS Java SDK V1.
Os exemplos a seguir utilizam o OSS Java SDK V1 3.17.4.
Adicionar uma dependência Maven (recomendado)
Para usar o OSS Java SDK V1 em um projeto Maven, adicione a dependência correspondente ao arquivo pom.xml.
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.18.4</version>
</dependency>
Se você utilizar Java 9 ou superior, adicione as seguintes dependências relacionadas ao JAXB.
<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>
Importar pacotes JAR para um projeto Eclipse
Baixe o OSS Java SDK V1.
Descompacte o pacote.
Copie o arquivo aliyun-sdk-oss-3.17.4.jar e todos os arquivos da pasta
libdo pacote descompactado para o seu projeto.No Eclipse, clique com o botão direito no projeto e selecione .
Selecione todos os arquivos JAR copiados e importe-os em Libraries.
Importar pacotes JAR para um projeto IntelliJ IDEA
Baixe o OSS Java SDK V1.
Descompacte o pacote.
Copie o arquivo aliyun-sdk-oss-3.17.4.jar e todos os arquivos JAR da pasta
libdo pacote descompactado para o seu projeto.No IntelliJ IDEA, selecione seu projeto e escolha .
Selecione todos os arquivos JAR copiados e importe-os em External Libraries.
Configure as credenciais de acesso
Configure as credenciais de acesso com um par de AccessKey de um usuário RAM.
No console RAM, crie um usuário RAM com um Permanent AccessKey Pair. Salve o par de AccessKey e conceda a permissão
AliyunOSSFullAccessao usuário.-
Use o par de AccessKey do usuário RAM para configurar as variáveis de ambiente.
Linux
-
Execute os comandos abaixo na interface de linha de comando para anexar as definições das variáveis de ambiente ao arquivo
~/.bashrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc -
Execute o comando a seguir para aplicar as alterações.
source ~/.bashrc -
Execute os comandos abaixo para verificar se as variáveis de ambiente foram configuradas corretamente.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
-
Execute o comando seguinte no terminal para visualizar o tipo de shell padrão.
echo $SHELL -
Realize as operações abaixo conforme o tipo de shell padrão.
Zsh
-
Execute os comandos a seguir para anexar as definições das variáveis de ambiente ao arquivo
~/.zshrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc -
Execute o comando abaixo para aplicar as alterações.
source ~/.zshrc -
Execute os comandos seguintes para verificar se as variáveis de ambiente estão configuradas.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
Execute os comandos abaixo para anexar as definições das variáveis de ambiente ao arquivo
~/.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 -
Execute o comando a seguir para aplicar as alterações.
source ~/.bash_profile -
Execute os comandos abaixo para confirmar que as variáveis de ambiente foram configuradas.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
-
Windows
CMD
-
Execute os comandos a seguir no CMD.
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET" -
Execute os comandos abaixo para verificar se as variáveis de ambiente estão configuradas.
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
-
Execute os comandos seguintes no 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) -
Execute os comandos abaixo para validar a configuração das variáveis de ambiente.
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
Inicialize o cliente
O código de exemplo a seguir usa o endpoint público da região China (Hangzhou) para inicializar o cliente. Em seguida, ele lista todos os buckets pertencentes à conta para validar a configuração. Para obter a lista completa de regiões e endpoints, consulte Regiões e 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.");
}
}
Após executar o código, os buckets da conta atual em todas as regiões serão exibidos:
Successfully connected to OSS. Buckets under the current account:
- example-bucket
OSS client has been shut down.
Configuração do cliente
Utilize a classe ClientConfiguration para definir parâmetros do OSSClient, como tempos limite, tentativas de nova execução e servidores proxy.
Use um nome de domínio personalizado
O nome de domínio padrão do OSS pode causar negação de acesso ou falhas na pré-visualização devido às políticas de segurança do OSS. Vincular um nome de domínio personalizado contorna essas restrições, permite a pré-visualização direta de arquivos e oferece suporte à integração com CDN para aceleração global de conteúdo.
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();
Use um endpoint interno
Quando sua aplicação for executada em serviços da Alibaba Cloud, como ECS ou Container Service, utilize um endpoint interno para garantir transferência de dados interna gratuita, maior velocidade e estabilidade superior. O acesso interno é ideal para uploads de arquivos grandes, processamento de dados em lote e acessos frequentes. Consulte Regiões e 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();
Controle de tempo limite
Ajuste os parâmetros de tempo limite conforme seu caso de uso. Aumente os tempos limite para transferências de arquivos grandes ou redes instáveis. Utilize tempos mais curtos para operações leves e de alta concorrência, liberando recursos rapidamente.
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();
Tentativas máximas de erro
Por padrão, o cliente OSS tenta repetir solicitações com falha três vezes. Em ambientes de alta concorrência ou com rede instável, use setMaxErrorRetry para aumentar o número de tentativas. Faça ajustes conforme os requisitos de latência e a qualidade da rede.
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();
Política de repetição
Evite usar setRetryStrategy para definir uma política de repetição personalizada, pois isso pode causar comportamentos inesperados. O cliente OSS emprega políticas de repetição comprovadas para diferentes tipos de solicitação:
Solicitações POST: Não são repetidas por padrão para evitar inconsistência de dados causada por envios duplicados.
-
Solicitações não-POST: São repetidas até três vezes quando as condições abaixo forem atendidas.
Ocorre uma exceção
ClientExceptioncom um dos seguintes códigos de erro:ConnectionTimeout,SocketTimeout,ConnectionRefused,UnknownHostouSocketException.Ocorre uma exceção
OSSExceptioncom um código de erro diferente deInvalidResponse.Ocorre um erro temporário no servidor com código de status HTTP 500, 502 ou 503.
Servidor proxy
Redes corporativas frequentemente roteiam o tráfego por servidores proxy. Após configurar um proxy, o cliente OSS encaminha todas as solicitações HTTP através dele.
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();
Protocolo HTTP/HTTPS
Utilize setProtocol para definir o protocolo de comunicação. O padrão é HTTP. Em ambientes de produção, prefira HTTPS para garantir a transferência segura de dados e prevenir ataques man-in-the-middle.
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();
Versão da assinatura
A Assinatura V1 do Object Storage Service da Alibaba Cloud será descontinuada conforme o cronograma abaixo. Recomendamos que você atualize para a Assinatura V4 o quanto antes para evitar impactos nos seus serviços.
A partir de 1º de março de 2025, novos usuários não poderão utilizar a Assinatura V1.
A partir de 1º de setembro de 2025, a Assinatura V1 não receberá mais atualizações nem manutenção, e novos buckets não poderão utilizá-la.
É possível usar setSignatureVersion para configurar a versão do algoritmo de assinatura. Ao utilizar a Assinatura V4, é obrigatório especificar o ID da região correto por meio do parâmetro region. O algoritmo de assinatura V4 oferece maior segurança. O OSS Java SDK V1 3.15.0 e versões posteriores suportam a Assinatura 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();
Use um endereço IP
Utilize um endereço IP como endpoint para acesso via rede interna e ambientes de rede especiais. Após estabelecer uma conexão via CEN, Express Connect, linha dedicada ou VPN, o acesso direto por IP ignora a resolução DNS e melhora a eficiência. Para configurações de roteamento, consulte Endpoints internos e blocos CIDR VIP para 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();
Verificação CRC
As verificações de dados CRC estão habilitadas por padrão para garantir a integridade da transferência. Mantenha o CRC ativado em produção. Considere desativá-lo apenas em cenários onde pequena perda de dados seja tolerável, como streams de pré-visualização ao vivo, dados de dispositivos IoT, vídeos de vigilância de baixa qualidade ou transferências em lote em redes internas altamente confiáveis. Avalie completamente os riscos de consistência de dados antes de desativar.
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();
Padrão Singleton
Adote o padrão singleton para criar e gerenciar instâncias do OSSClient.
O OSSClient é thread-safe. Utilize o padrão singleton para reutilizar uma única instância do OSSClient, evitando a sobrecarga de criação e destruição frequentes.
O OSSClient mantém um pool de conexões interno. Quando não for mais necessário, chame o método shutdown para liberar recursos.
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();
}
}
}
Tratamento de exceções
O OSS Java SDK V1 lança dois tipos de exceção: ClientException e OSSException, ambas estendendo RuntimeException.
Exceções de cliente (ClientException)
Exceções de cliente ocorrem durante a construção da solicitação, envio ou transferência de dados. Os cenários comuns incluem:
A conexão de rede está indisponível, impedindo o envio da solicitação ao servidor.
Uma exceção de IO ocorre durante o upload do arquivo.
Ocorrem exceções de rede subjacentes, como tempo limite de solicitação ou falha na verificação de certificado.
Uma ClientException indica que a solicitação não foi enviada ao servidor OSS ou que ocorreu um erro durante o processamento no lado do cliente. Verifique a conexão de rede e a configuração do cliente.
Exceções de servidor (OSSException)
Exceções de servidor significam que a solicitação chegou ao OSS, mas foi rejeitada. A OSSException fornece:
Códigos de erro detalhados e mensagens de erro para identificação precisa do problema.
Erros comuns incluem SignatureDoesNotMatch, AccessDenied e NoSuchKey.
Tratar essas exceções com base no código de erro pode melhorar significativamente a robustez do programa e a experiência do usuário.
Capture esses dois tipos de exceção separadamente para identificar e tratar erros com precisão.
// 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.
}
}
Código de exemplo
O OSS Java SDK V1 oferece códigos de exemplo que abrangem gerenciamento de buckets, operações com arquivos, controle de acesso e transferência criptografada:
|
Arquivo de exemplo |
Conteúdo do exemplo |
|
Upload via formulário (OSS Java SDK V1) Nota
A implementação do PostObject não depende do Java SDK. |
|
|
Converter a classe de armazenamento de um arquivo (OSS Java SDK V1) |
|
|
Evitar substituição de arquivo com o mesmo nome (OSS Java SDK V1) |
|
|
Limitação de largura de banda de conexão única (OSS Java SDK V1) |
|
Configuração de credenciais de acesso
O OSS suporta diversos métodos de inicialização de credenciais. Escolha um deles com base nas suas necessidades de autenticação.
Usar o par de AccessKey de um usuário RAM
Indicado para aplicações em ambiente seguro que necessitam de acesso prolongado ao OSS sem rotação frequente de credenciais. Inicialize o provedor de credenciais com o par de AccessKey de um usuário RAM (AccessKey ID e AccessKey secret). Este método exige manutenção manual do par de AccessKey, o que aumenta os riscos de segurança.
Uma conta Alibaba Cloud possui permissões totais sobre seus recursos. O vazamento do par de AccessKey representa um risco significativo para o seu sistema. Não recomendamos o uso do par de AccessKey da conta Alibaba Cloud. Em vez disso, utilize o par de AccessKey de um usuário RAM com as permissões mínimas necessárias.
Para criar um par de AccessKey para um usuário RAM, consulte Criar um par de AccessKey. O AccessKey ID e o AccessKey secret de um usuário RAM são exibidos apenas no momento da criação do par. Caso os esqueça, será necessário criar um novo par de AccessKey para substituir o anterior.
Variáveis de ambiente
-
Configure as variáveis de ambiente utilizando o par de AccessKey de um usuário RAM.
Linux
-
Execute os comandos abaixo na interface de linha de comando para adicionar as definições das variáveis de ambiente ao arquivo
~/.bashrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc -
Execute o comando a seguir para aplicar as alterações.
source ~/.bashrc -
Execute os comandos abaixo para verificar se as variáveis de ambiente foram configuradas corretamente.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
-
Execute o comando seguinte no terminal para identificar o tipo de shell padrão.
echo $SHELL -
Realize as operações correspondentes ao tipo de shell padrão.
Zsh
-
Execute os comandos a seguir para anexar as configurações das variáveis de ambiente ao arquivo
~/.zshrc.echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc -
Execute este comando para efetivar as mudanças.
source ~/.zshrc -
Valide a configuração das variáveis de ambiente executando os comandos abaixo.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
Utilize os comandos seguintes para gravar as definições das variáveis de ambiente no arquivo
~/.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 -
Aplique as alterações executando o comando abaixo.
source ~/.bash_profile -
Confirme se as variáveis de ambiente estão definidas através dos comandos a seguir.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
-
Windows
CMD
-
No CMD, execute os comandos listados abaixo.
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET" -
Verifique a configuração das variáveis de ambiente com os seguintes comandos.
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
-
Execute os comandos abaixo no 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) -
Para validar as variáveis de ambiente, execute os comandos a seguir.
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
Após modificar as variáveis de ambiente do sistema, reinicie ou atualize seu ambiente de desenvolvimento — incluindo IDE, interface de linha de comando, outros aplicativos de desktop e serviços de back-end — para garantir o carregamento correto das novas variáveis.
-
Transmita as informações de credenciais por meio das variáveis de ambiente.
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(); } }
Credenciais estáticas
O código de exemplo a seguir demonstra como codificar as credenciais de acesso diretamente e definir explicitamente o par de AccessKey a ser utilizado.
Não incorpore credenciais de acesso em aplicações de produção. Este método destina-se exclusivamente a testes.
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();
}
}
Usar um token STS
Indicado para aplicações que precisam de acesso temporário ao OSS. Inicialize o provedor de credenciais com credenciais temporárias (AccessKey ID, AccessKey secret e security token) obtidas do STS. É necessário atualizar manualmente o token STS para acessos recorrentes.
Para obter rapidamente um token STS por meio de uma OpenAPI, consulte AssumeRole - Obter credenciais de identidade temporárias para uma função RAM.
Para obter um token STS usando um SDK, consulte Usar um token STS para acessar o OSS.
Especifique um tempo de expiração ao gerar um token STS. O token torna-se inválido e não pode ser utilizado após o vencimento.
Para obter a lista de endpoints do serviço STS, consulte Endpoints de serviço.
Variáveis de ambiente
-
Utilize credenciais de identidade temporárias para definir as variáveis de ambiente.
Mac OS/Linux/Unix
ImportanteObserve que as credenciais de identidade temporárias (AccessKey ID, AccessKey secret e security token) obtidas do serviço STS são usadas aqui, e não o par AccessKey de um usuário RAM.
Note que o AccessKey ID obtido do serviço STS começa com "STS", como em "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
ImportanteObserve que as credenciais de identidade temporárias (AccessKey ID, AccessKey secret e security token) obtidas do serviço STS são usadas aqui, e não o par AccessKey (AccessKey ID e AccessKey secret) de um usuário RAM.
Note que o AccessKey ID obtido do serviço STS começa com "STS", como em "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> -
Transmita as informações de credencial por meio de variáveis de ambiente.
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(); } }
Credenciais estáticas
É possível codificar as credenciais diretamente na aplicação e definir explicitamente a chave de acesso temporária a ser utilizada.
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();
}
}
Usar um RAMRoleARN
Recomendado para aplicações que necessitam de acesso autorizado ao OSS, como em cenários de acesso entre contas. Inicialize o provedor de credenciais especificando o ARN de uma função RAM. O SDK obtém e atualiza automaticamente os tokens STS chamando a API AssumeRole. Também é possível utilizar o parâmetro policy para restringir as permissões da função RAM.
Uma conta Alibaba Cloud possui permissões totais sobre seus recursos. Caso o par AccessKey seja comprometido, isso representa um risco significativo ao sistema. Não recomendamos o uso do par AccessKey de uma conta Alibaba Cloud. Em vez disso, utilize o par AccessKey de um usuário RAM com as permissões mínimas necessárias.
Para criar um par AccessKey para um usuário RAM, consulte Criar um par AccessKey. O AccessKey ID e o AccessKey secret de um usuário RAM são exibidos apenas no momento da criação do par AccessKey. Salve-os imediatamente. Se você os perder, será necessário criar um novo par AccessKey para substituir o anterior.
Para obter um RAMRoleARN, consulte Criar uma função RAM.
-
Adicione a dependência de credenciais.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configure o par AccessKey e o RAMRoleARN como credenciais de acesso.
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(); } }
Usar um ECSRAMRole
Ideal para aplicações em instâncias ECS, instâncias ECI ou nós de trabalho do Container Service for Kubernetes. Ao anexar uma função RAM à instância, os tokens STS são obtidos e atualizados automaticamente dentro do Container Service for Kubernetes ou ECS, eliminando o gerenciamento manual de credenciais. Para obter um ECSRAMRole, consulte Criar uma função RAM. Para anexar uma função, consulte Funções RAM de instância.
-
Adicione a dependência de credenciais.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configure o ECSRAMRole como credencial de acesso.
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(); } }
Usar um OIDCRoleARN
Após configurar uma função RAM de nó de trabalho no Container Service for Kubernetes, as aplicações nos pods do nó correspondente podem obter o token STS da função anexada por meio do serviço global de metadados, assim como ocorre com aplicações implantadas em ECS. No entanto, se aplicações não confiáveis forem implantadas no cluster de contêineres (por exemplo, aplicações enviadas por clientes cujo código não está acessível a você), talvez não seja desejável que elas obtenham o token STS da função RAM de instância anexada ao nó de trabalho via serviço global de metadados. Para evitar comprometer a segurança dos seus recursos na nuvem e, ao mesmo tempo, permitir que essas aplicações não confiáveis obtenham com segurança os tokens STS necessários — alcançando a minimização de permissões no nível da aplicação — utilize o recurso RAM Roles for Service Accounts (RRSA). A implementação subjacente desse método baseia-se em um token STS. O cluster de contêineres da Alibaba Cloud cria e monta o arquivo de token OIDC da conta de serviço correspondente para diferentes pods de aplicação e injeta as informações de configuração relevantes nas variáveis de ambiente. O SDK obtém o token STS da função vinculada chamando a operação de API AssumeRoleWithOIDC do serviço STS, utilizando as informações de configuração das variáveis de ambiente. Esse método elimina o risco de manter manualmente um par AccessKey ou um token STS, pois não é necessário fornecer nenhum deles. Para mais informações, consulte Configurar permissões RAM para um ServiceAccount via RRSA para alcançar isolamento de permissões de pod.
-
Adicione a dependência de credenciais.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configure a função RAM OIDC como credencial de acesso.
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(); } }
Usar credenciais do contexto do Function Compute
Este método destina-se a funções de aplicações implantadas no Function Compute. É possível inicializar o provedor de credenciais com as credenciais provenientes do contexto do Function Compute. A implementação subjacente baseia-se em um token STS. O Function Compute obtém um token STS assumindo a função de serviço configurada para a função e, em seguida, transmite esse token STS à sua aplicação por meio do parâmetro Credentials no contexto. Esse token STS tem validade de 36 horas e não pode ser modificado. Como o tempo máximo de execução de uma função é de 24 horas, o token STS não expirará durante a execução da função, portanto não é necessário preocupar-se com sua atualização. Esse método elimina o risco de manter manualmente um par AccessKey ou um token STS, pois não é preciso fornecer nenhum deles. Para conceder permissões ao Function Compute para acessar o OSS, consulte Usar uma função de função para conceder permissões ao Function Compute para acessar outros serviços da Alibaba Cloud.
-
Adicione a dependência de contexto do 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> -
Inicialize o provedor de credenciais com as credenciais do contexto do 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()); } }
Usar um CredentialsURI
Apropriado para aplicações que recuperam credenciais de um sistema externo, permitindo um gerenciamento flexível de credenciais. Inicialize o provedor de credenciais com uma URI que retorne tokens STS. O SDK obtém e atualiza automaticamente os tokens a partir da URI especificada.
-
Para que o SDK analise e utilize corretamente o token STS, a URI deve seguir este protocolo de resposta:
Código de status da resposta: 200
-
Estrutura do corpo da resposta:
{ "Code": "Success", "AccessKeySecret": "AccessKeySecret", "AccessKeyId": "AccessKeyId", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
-
Adicione a dependência de credenciais.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configure o CredentialsURI como credencial de acesso.
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(); } }
Usar um par AccessKey com rotação automática
Destinado a aplicações que exigem acesso de longo prazo ao OSS em ambientes com risco de vazamento de AccessKey. Inicialize o provedor de credenciais com uma ClientKey. O KMS rotaciona automaticamente o par AccessKey do usuário RAM gerenciado, transformando credenciais estáticas em dinâmicas e reduzindo o risco de vazamento. O KMS também suporta rotação imediata. Para obter uma ClientKey, consulte Criar um ponto de acesso de aplicação.
-
Adicione a dependência do cliente de credenciais.
<!-- 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> -
Crie o arquivo de configuração
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>"}] -
Utilize o arquivo de configuração para transmitir as informações de credencial.
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(); } }
Usar uma credencial de acesso personalizada
Caso nenhum dos métodos anteriores de configuração de credenciais atenda aos seus requisitos, personalize o provedor de credenciais implementando a interface Credential Providers. Note que, se a implementação subjacente for baseada em um token STS, será necessário fornecer suporte para a atualização das credenciais.
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();
}
}
Usar a cadeia de credenciais padrão
Ao inicializar o cliente de credenciais sem parâmetros, o SDK utiliza a cadeia de credenciais padrão. Para entender a lógica da cadeia de credenciais, consulte Cadeia de credenciais padrão.
-
Adicione a dependência de credenciais.
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java --> <dependency> <groupId>com.aliyun</groupId> <artifactId>credentials-java</artifactId> <version>LATEST</version> </dependency> -
Configure Credentials como credencial de acesso.
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
Conflitos de pacotes
-
Causa
Ao usar o OSS Java SDK V1, um erro semelhante ao abaixo indica um conflito de pacotes no seu projeto.
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)Esse erro ocorre porque o OSS Java SDK V1 utiliza o Apache HttpClient 4.4.1, mas o seu projeto usa uma versão conflitante do Apache HttpClient ou um pacote JAR commons-httpclient. Execute o comando
mvn dependency:treeno diretório do seu projeto para visualizar os pacotes JAR e suas respectivas versões utilizadas. Conforme mostrado na figura a seguir, o projeto utiliza o Apache HttpClient 4.3, o que entra em conflito com a versão padrão:
-
Solução
Resolva os conflitos de pacotes de uma das duas maneiras seguintes:
Unificar a versão: Se o seu projeto utiliza uma versão que conflita com o Apache HttpClient 4.4.1, atualize-o para a versão 4.4.1 e remova as dependências de outras versões do Apache HttpClient do arquivo
pom.xml. Caso o projeto utilize commons-httpclient, também pode haver conflito. Remova a dependência do commons-httpclient.Resolver conflitos de dependência: Se o seu projeto depende de vários pacotes de terceiros e esses pacotes, por sua vez, dependem de diferentes versões do Apache HttpClient, haverá conflitos de dependência no projeto. Utilize a tag de exclusão para resolvê-los. Para mais informações, consulte Guias do Maven.
O OSS Java SDK V1 depende das seguintes versões de pacotes. O método de resolução de conflitos é semelhante ao utilizado para o HttpClient.

Pacotes ausentes
-
Causa
Ao usar o OSS Java SDK V1, um erro semelhante ao exemplo abaixo indica que seu projeto pode estar sem os pacotes necessários para compilar ou executar o OSS Java SDK V1.
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 moreO OSS Java SDK V1 depende dos seguintes pacotes:
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
Dentre esses, o log4j-1.2.15.jar é uma dependência opcional. Adicione este pacote apenas se precisar da funcionalidade de log. Os demais pacotes são obrigatórios.
-
Solução
Adicione ao seu projeto os pacotes dos quais o OSS Java SDK V1 depende. Use um dos métodos a seguir:
Projeto Eclipse: consulte Instalar o SDK.
Projeto Ant: coloque os pacotes dos quais o OSS Java SDK V1 depende no diretório lib do seu projeto.
Compilação direta: use o comando
-classpathou-cppara especificar o caminho dos pacotes dos quais o OSS Java SDK V1 depende, ou coloque esses pacotes no classpath.
Tempo limite de conexão
-
Causa
Ao executar um programa do OSS Java SDK V1, pode ocorrer um erro semelhante ao exemplo abaixo devido a um endpoint incorreto ou problemas de conectividade de rede.
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 -
Solução
Use a ferramenta ossutil para localizar rapidamente a causa do erro e resolver o problema.
Erro SignatureDoesNotMatch
-
Causa 1: Informações do par AccessKey incompatíveis
O AccessKey ID e o AccessKey secret não correspondem. Para obter informações sobre como adquirir um AccessKey ID e um AccessKey secret, consulte Criar um par AccessKey.
-
Causa 2: Uso incorreto de uma URL assinada
O exemplo a seguir mostra um uso incorreto de URL assinada:
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);Se o parâmetro Method não for especificado, o método GET será usado por padrão. No entanto, o exemplo anterior é uma requisição PutObject. Portanto, é necessário especificar o parâmetro Method e defini-lo como PUT.
Ao enviar uma requisição PutObject, os metadados personalizados no cabeçalho da requisição devem ter o prefixo
x-oss-meta-. No exemplo anterior, os metadados personalizados devem ser alterados parax-oss-meta-author.Solução:
Especifique o parâmetro Method e modifique o prefixo do cabeçalho:
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); -
Causa 3: Problema de compatibilidade de versão do HttpClient
Uma versão do OSS SDK anterior à 3.7.0 está em uso, e o HttpClient 4.5.9 ou posterior foi introduzido no projeto.
O nome do arquivo enviado contém um caractere
+, e o HttpClient 4.5.9 não codifica o caractere+na URL. Isso faz com que as assinaturas calculadas pelo cliente e pelo servidor sejam inconsistentes.

Solução:
Atualize o OSS SDK para a versão 3.11.1 ou posterior para garantir compatibilidade com o HttpClient 4.5.9.
Remova dependências redundantes do HttpClient. Ao introduzir o OSS SDK, a dependência do HttpClient é adicionada automaticamente. Se uma biblioteca de terceiros também introduzir o HttpClient, consulte a solução para Conflitos de pacotes.
-
Causa 4: Problema de compatibilidade de conjunto de caracteres do HttpClient
O HttpClient 4.5.10 não suporta caracteres fora do padrão ISO-8859-1 no cabeçalho. Em projetos que usam uma versão do HttpClient posterior à 4.5.10, ocorre um problema se o cabeçalho da requisição contiver caracteres fora do padrão ISO-8859-1, como caracteres chineses em metadados personalizados que começam com
x-oss-meta-.
Solução:
Consulte a solução para Conflitos de pacotes para remover a versão conflitante do HttpClient.
Transmita apenas caracteres compatíveis com o padrão ISO-8859-1 no cabeçalho da requisição.
Exceção "Failed to parse the response result"

-
Causa
Algum software especial no lado do cliente intercepta a requisição HTTP, ou uma rota de rede pública sequestra a requisição HTTP.
Você está usando o OSS Java SDK V1 no Java 9 ou posterior e não adicionou as dependências relacionadas ao JAXB ao arquivo pom.xml.
-
Solução
Mude para uma requisição HTTPS.
Adicione as dependências relacionadas ao JAXB. Para o procedimento, consulte Instalar o SDK.
org.apache.http.NoHttpResponseException: The target server failed to respond
-
Causa
Ao executar um programa do OSS Java SDK V1, um erro semelhante ao seguinte é relatado:

O uso de uma conexão expirada causa o erro acima. Esse erro ocorre apenas em versões do Java SDK anteriores à 2.1.2.
-
Solução
Atualize o OSS Java SDK V1 para a versão 2.1.2 ou posterior.
Existem muitas instâncias de org.apache.http.impl.conn.PoolingHttpClientConnectionManager na JVM
-
Causa
O ossClient não foi fechado corretamente.
-
Solução
Feche o ossClient após a conclusão da execução ou use o padrão singleton.
A chamada do OSS Java SDK V1 não responde
-
Causa
Uma chamada do OSS Java SDK V1 não apresenta resposta. Ao executar o comando
jstack -l pidpara visualizar a pilha, é possível localizar o problema na seguinte posição:"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)A causa é um vazamento de conexões no pool de conexões, possivelmente porque o ossObject não foi fechado corretamente após o uso.
-
Solução
Verifique seu programa para garantir que não haja vazamentos de conexão. Use o método a seguir para fechar a conexão corretamente:
// Read the file. OSSObject ossObject = ossClient.getObject(bucketName, objectName); // OSS operation // Close ossObject. ossObject.close();Para etapas detalhadas de solução de problemas, consulte Solucionar problemas de falta de resposta no OSS Java SDK V1.
Conexão fechada
-
Causa
Se você encontrar um erro semelhante ao seguinte ao usar 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)A causa é que o intervalo entre duas leituras de dados excede 1 minuto. O OSS fecha conexões que ficam ociosas por mais de 1 minuto.
-
Solução
Se você ler apenas parte dos dados de cada vez e o tempo de processamento variar, use o download por intervalo para evitar o fechamento da conexão. A conexão é fechada automaticamente após a conclusão do download por intervalo. Download por intervalo (OSS Java SDK V1).
Vazamento de memória
-
Causa
Um programa que chama o OSS Java SDK V1 apresenta vazamento de memória após rodar por um período (de algumas horas a alguns dias, dependendo do volume de negócios). Recomendamos usar o Eclipse Memory Analyzer (MAT) para analisar o uso de memória. Para mais informações, consulte Analisar arquivos de heap dump com MAT.
Se o resultado da análise for semelhante à figura abaixo (PoolingHttpClientConnectionManager ocupa 96% da memória), a causa provável é que
new OSSClientpode ter sido executado várias vezes no programa, masossClient.shutdownnão foi chamado, resultando em vazamento de memória.
-
Solução
Após concluir a operação
new OSSClient, chame o métodoshutdownpara fechá-lo. Certifique-se de quenew OSSClienteossClient.shutdownsejam usados em pares.
InterruptedException é relatado ao chamar ossClient.shutdown
-
Causa
Versões do OSS Java SDK V1 anteriores à 2.3.0 relatam a seguinte exceção ao chamar
ossClient.shutdown:java.lang.InterruptedException: sleep interrupted at java.lang.Thread.sleep(Native Method) at com.aliyun.oss.common.comm.IdleConnectionReaper.run(IdleConnectionReaper:76)A causa é que o thread de backend do ossClient, IdleConnectionReaper, fecha periodicamente conexões ociosas. Se ossClient.shutdown for chamado enquanto o IdleConnectionReaper estiver em estado Sleep, a exceção acima será relatada.
-
Solução
Use o código a seguir para ignorar a exceção:
try { ossClient.shutdown(); } catch(Exception e) { }
Exceção "SDK.ServerUnreachable : Speicified endpoint or uri is not valid"

-
Causa
O cliente envia muitas requisições simultâneas para o STS.
A conexão de rede com o servidor atingiu o tempo limite.
O STS SDK e o SDK core em uso não são as versões mais recentes.
-
Solução
Reduza a concorrência do OSS. Se o cliente estiver enviando muitas requisições simultâneas para o STS, a instância ECS do cliente ou o computador local pode não conseguir lidar com a carga.
A conexão de rede do usuário com o servidor atingiu o tempo limite. Capture pacotes para verificar essa situação.
Atualize o STS SDK e o SDK core para as versões mais recentes.
NoSuchKey

-
Causa
O arquivo de origem não existe.
-
Solução
SocketException

-
Causa
O socket pode ter falhado durante a fase de inicialização, fazendo com que a requisição falhe antes de chegar ao OSS.
-
Solução
Recomendamos verificar os seguintes aspectos:
Se houve instabilidade de rede quando o problema ocorreu.
Se o número de conexões de socket no host atingiu seu limite.
Confirme se o número de conexões excedeu a configuração maxconnection no SDK quando o problema ocorreu. Se o número de conexões ultrapassar a configuração maxconnection, uma exceção de socket também ocorrerá.
Se não houver problemas nos itens acima, recomendamos implantar tcpdump ou Wireshark para capturar pacotes e, em seguida, analisar os pacotes de dados após a recorrência do problema.
O callback do OSS PostObject não é acionado
O callback do OSS PostObject não é acionado, mas o mesmo callback funciona com PutObject. Geralmente, se o formato JSON estiver incorreto ou o callback falhar, uma mensagem correspondente é retornada. Nesse caso, teste separadamente o comportamento de callback do Put e do Post:

-
Causa
Ao enviar a requisição, o parâmetro
callbackfoi colocado incorretamente dentro do parâmetrofile.
-
Solução
Ajuste a posição dos parâmetros callback e file.

Neste ponto, o resultado do teste mostra que o servidor de negócios capturou a requisição com sucesso.

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
-
Causa
Você continua enviando requisições através do ossClient após chamar o método
ossClient.shutdown(). -
Solução
Verifique sua lógica de chamadas para garantir que, após chamar o método
ossClient.shutdown(), nenhuma outra requisição seja enviada através do ossClient.
Ocorre um erro "Request has expired" para requisições geradas por generatePresignedUrl do Java SDK
-
Causa
Um estouro de inteiro causa um problema de timestamp relacionado ao problema do ano 2038.
Uma requisição de upload é iniciada após o tempo de expiração definido para a URL.
-
Solução
Se for um estouro de inteiro, recomendamos que a duração de expiração no Java SDK não ultrapasse o ano 2038.
Se uma requisição de upload for iniciada após o tempo de expiração definido para a URL, defina um tempo de expiração razoável para garantir que ele seja posterior ao momento em que você inicia a requisição.
Erro "Invalid Response" ou "Implementation of JAXB-API has not been found on module path or classpath"
-
Causa
Você está usando Java 9 ou posterior e não adicionou a dependência JAXB.
-
Solução
Para obter informações sobre como adicionar a dependência JAXB, consulte Instalar o SDK.
O OSSClient no OSS Java SDK V1 é thread-safe?
O OSSClient é thread-safe, permitindo que múltiplos threads acessem a mesma instância. Dependendo das necessidades do seu negócio, reutilize uma única instância do OSSClient ou crie várias instâncias.
Uma instância do OSSClient mantém um pool de conexões internamente. Quando uma instância do OSSClient não for mais necessária, chame o método shutdown para fechá-la e evite o esgotamento de recursos causado pela criação excessiva de instâncias do OSSClient.
É relatado um erro "AccessDenied Hierarchical namespace is disabled"
-
Causa
O hierarchical namespace não estava ativado antes de você chamar a operação de API CreateDirectory, Rename ou DeleteDirectory.
-
Solução
Ative o hierarchical namespace ao criar um bucket. Para o procedimento específico, consulte Criar um bucket.
A rede do cliente está normal, mas um erro "Connection reset" é relatado durante o acesso HTTP. Como proceder?
Operadoras em algumas regiões podem sequestrar o nome de domínio do OSS. Configure HTTPS através do endpoint. Configurar o cliente.
Java 17 Cannot invoke "java.lang.reflect.Method.invoke(Object, Object[])" because "com.sun.xml.bind.v2.runtime.reflect.opt.Injector.defineClass" is null
-
Causa
O JAXB foi marcado como obsoleto no Java 9 e removido no Java 11.
-
Solução
Adicione as seguintes dependências:
<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>
Como configurar a impressão de logs internos para o Java SDK?
O Java SDK usa o framework Apache Commons Logging (JCL) para impressão de logs. O JCL pode utilizar vários frameworks de implementação de log. Para mais informações, consulte JCL-Configuration. Os mais comuns são JCL over log4j ou JCL over SLF4j. Os métodos de implementação são os seguintes:
JCL over log4j: É necessário introduzir a dependência log4j (o log4j 2.x possui vários frameworks de implementação à escolha, sendo o padrão log4j-api+log4j-core) e configurá-lo conforme o método de configuração do log4j. Para o processo específico, consulte APACHE LOG4J-API Separation.
JCL over slf4j: É necessário introduzir as dependências jcl-over-slf4j e slf4j (o slf4j também possui vários frameworks de implementação à escolha, como slf4j-api+logback-classic) e configurá-lo conforme o método de configuração do slf4j. Para o processo específico, consulte SJF4J-Bridging legacy APIs.
O Apache Log4j define diferentes níveis de logs, incluindo OFF, FATAL, ERROR, WARN, INFO, DEBUG, TRACE e ALL.
Ative ou desative os logs do SDK configurando as propriedades do log4j:
