Integração rápida
Para integrar o OSS Java SDK V1:
Preparar o ambiente
Instale o Java 7 ou superior. Execute o comando java -version para visualizar sua versão do Java. Caso o Java não esteja instalado ou sua versão seja anterior ao Java 7, baixe o Java.
Instalar 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 o 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.
Configurar 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.-
Utilize 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.
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 verificar se 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 verificar se as variáveis de ambiente foram configuradas.
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
Inicializar 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.
Usar 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();
Usar 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 gratuita de dados internos, 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 o seu caso de uso. Aumente os tempos limite para transferências de arquivos grandes ou redes instáveis. Utilize tempos limite 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();
Novas tentativas máximas de erro
Por padrão, o cliente OSS tenta novamente solicitações com falha três vezes. Em ambientes de alta concorrência ou com rede instável, utilize 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 nova tentativa
Não utilize setRetryStrategy para definir uma política personalizada de nova tentativa. Políticas personalizadas podem causar comportamentos inesperados. O cliente OSS emprega políticas de nova tentativa comprovadas para diferentes tipos de solicitação:
Solicitações POST: Não são repetidas por padrão para evitar inconsistência de dados decorrente de envios duplicados.
-
Solicitações não POST: São repetidas até três vezes se as condições a seguir 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 lado do 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 oferecem suporte à 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();
Usar um endereço IP
Utilize um endereço IP como endpoint para acesso à 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 ativadas por padrão para garantir a integridade da transferência. Mantenha o CRC habilitado 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 é seguro para threads. Utilize o padrão singleton para reutilizar uma única instância do OSSClient, evitando a sobrecarga causada pela 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. 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 indicam 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 de uma 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
-
Utilize o par de AccessKey de um usuário RAM para configurar as variáveis de ambiente.
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 abaixo conforme o tipo de shell padrão.
Zsh
-
Execute os comandos a seguir para adicionar 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 confirmar que as variáveis de ambiente estão configuradas.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
-
Execute os comandos abaixo para adicionar 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 verificar se as variáveis de ambiente foram configuradas corretamente.
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 confirmar que 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 verificar se as variáveis de ambiente foram configuradas corretamente.
[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 backend, para garantir que as novas variáveis sejam carregadas com sucesso.
-
Utilize as variáveis de ambiente para transmitir as informações da credencial.
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 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 via STS. É necessário atualizar manualmente o token STS para acessos subsequentes.
Para obter rapidamente um token STS por meio de uma OpenAPI, consulte AssumeRole - Obter credenciais de identidade temporárias para uma função RAM.
Caso prefira obter o token STS utilizando um SDK, veja Usar um token STS para acessar o OSS.
É obrigatório especificar um tempo de expiração ao gerar o token STS. Após esse período, o token torna-se inválido e não pode mais ser utilizado.
Para consultar a lista de endpoints do service STS, acesse Endpoints de serviço.
Variáveis de ambiente
-
Defina as variáveis de ambiente usando credenciais de identidade temporárias.
Mac OS/Linux/Unix
ImportanteObserve que as credenciais de identidade temporárias (AccessKey ID, AccessKey secret e security token) obtidas do service STS são usadas aqui, e não o par AccessKey de um usuário RAM.
Note que o AccessKey ID fornecido pelo service 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
ImportanteLembre-se de que as credenciais de identidade temporárias (AccessKey ID, AccessKey secret e security token) obtidas do service STS são utilizadas neste cenário, em vez do par AccessKey (AccessKey ID e AccessKey secret) de um usuário RAM.
O AccessKey ID retornado pelo service STS sempre inicia com "STS", por exemplo: "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 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 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 exigem 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 renova automaticamente os tokens STS chamando a API AssumeRole. Além disso, utilize 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, o risco ao sistema é elevado. Evite usar o par AccessKey da conta principal; prefira o par AccessKey de um usuário RAM com apenas 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 aparecem somente no momento da criação. Salve-os imediatamente. Se perdê-los, será preciso gerar um novo par AccessKey para substituir o anterior.
Para obter um RAMRoleARN, siga as instruções em 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 executadas 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 renovados 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, veja Funções RAM de instância.
-
Inclua 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> -
Defina 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 desse nó podem obter o token STS da função anexada via service de metadados global, assim como ocorre em aplicações implantadas no ECS. Contudo, se houver aplicações não confiáveis no cluster de contêineres (por exemplo, códigos enviados por clientes sem visibilidade para você), talvez seja indesejável permitir que elas acessem o token STS da função RAM da instância do nó de trabalho pelo service de metadados global. Para proteger seus recursos cloud e, ao mesmo tempo, permitir que essas aplicações obtenham tokens STS de forma segura com permissões mínimas no nível da aplicação, utilize o recurso RAM Roles for Service Accounts (RRSA). Essa abordagem baseia-se em tokens STS. O cluster de contêineres da Alibaba Cloud cria e monta o arquivo de token OIDC da conta de service correspondente para cada pod e injeta as configurações relevantes nas variáveis de ambiente. O SDK obtém o token STS da função vinculada chamando a operação AssumeRoleWithOIDC da API do service STS, usando as informações 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 detalhes, consulte Configurar permissões RAM para um ServiceAccount via RRSA para 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. Inicialize o provedor de credenciais com as credenciais disponíveis no contexto do Function Compute. A implementação subjacente utiliza um token STS. O Function Compute obtém esse token assumindo a função de service configurada para a função e o repassa à sua aplicação por meio do parâmetro Credentials no contexto. O token tem validade de 36 horas e não pode ser alterado. 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, dispensando qualquer preocupação com renovação. Essa abordagem remove o risco de gerenciar manualmente um par AccessKey ou um token STS, já que nenhum deles precisa ser fornecido. Para conceder permissões de acesso ao OSS via Function Compute, consulte Usar uma função para conceder permissões ao Function Compute para acessar outros services da Alibaba Cloud.
-
Adicione a dependência do 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 buscam credenciais em sistemas externos, permitindo gestão flexível. Inicialize o provedor de credenciais com uma URI que retorne tokens STS. O SDK obtém e renova automaticamente os tokens a partir da URI especificada.
-
Para que o SDK interprete 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" }
-
Inclua 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 requerem 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 exposição. O KMS também permite rotação imediata. Para obter uma ClientKey, consulte Criar um ponto de acesso à 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 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; 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
Se nenhum dos métodos anteriores atender às suas necessidades, personalize o provedor implementando a interface Credential Providers. Caso a implementação subjacente utilize tokens STS, garanta o suporte à 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 adota a cadeia de credenciais padrão. Para entender a lógica dessa cadeia, 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 utilizar o OSS Java SDK V1, erros semelhantes aos abaixo indicam conflito de pacotes no 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 depende do Apache HttpClient 4.4.1, mas seu projeto utiliza uma versão conflitante do Apache HttpClient ou um pacote JAR commons-httpclient. Execute o comando
mvn dependency:treeno diretório do projeto para verificar os pacotes JAR e suas versões. Neste exemplo, o projeto usa Apache HttpClient 4.3, gerando conflito com a versão padrão:[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 -
Solução
Resolva conflitos de pacotes seguindo uma das duas abordagens abaixo:
Unificar a versão: Se o projeto utilizar uma versão incompatível com o Apache HttpClient 4.4.1, atualize para a versão 4.4.1 e remova dependências de outras versões do Apache HttpClient no arquivo
pom.xml. Caso o projeto use commons-httpclient, também pode haver conflito; nesse caso, remova essa dependência.Resolver conflitos de dependência: Quando o projeto depender de vários pacotes de terceiros que, por sua vez, exigem versões diferentes do Apache HttpClient, ocorrerão conflitos de dependência. 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 segue a mesma lógica aplicada ao 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
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 quando 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
Abaixo está um exemplo incorreto de uso de uma 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, o parâmetro Method deve ser especificado e definido 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.
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)Solução: Use um dos métodos a seguir.
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 oferece suporte a caracteres fora do padrão ISO-8859-1 no cabeçalho. Em um projeto que usa 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-.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);Solução: Use um dos métodos a seguir.
Consulte a solução para Conflitos de pacotes para remover a versão conflitante do HttpClient.
Transmita apenas caracteres que estejam em conformidade com o padrão ISO-8859-1 no cabeçalho da requisição.
Exceção "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)
-
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:
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]O uso de uma conexão expirada causa o erro anterior. 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 ele terminar a execução ou use o padrão singleton.
Chamada do OSS Java SDK V1 não responde
-
Causa
Uma chamada do OSS Java SDK V1 não responde. Ao executar o comando
jstack -l pidpara visualizar a pilha, você pode 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ão 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();
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 ficaram 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 ser executado 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 dump de heap com MAT.
Se o resultado da análise for semelhante à figura abaixo (PoolingHttpClientConnectionManager ocupa 96% da memória), a causa é que
new OSSClientpode ter sido executado várias vezes no programa, masossClient.shutdownnão foi chamado, o que resultou em um vazamento de memória.
-
Solução
Após a conclusão da operação
new OSSClient, chame o métodoshutdownpara fechá-lo. Garanta quenew OSSClienteossClient.shutdownsejam usados em pares.
InterruptedException é relatado quando ossClient.shutdown é chamado
-
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 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"
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)
-
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. Você pode capturar pacotes para verificar isso.
Atualize o STS SDK e o SDK core para as versões mais recentes.
NoSuchKey
case:java.lang.Exception: com.aliyun.oss.OSSException:
Not Foundn[ErrorCode]: NoSuchKeyn
-
Causa
O arquivo de origem não existe.
-
Solução
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)
-
Causa
O socket pode ter falhado durante a fase de inicialização, fazendo com que a requisição falhasse antes de chegar ao OSS.
-
Solução
Recomendamos verificar os seguintes aspectos:
Se ocorreu instabilidade de rede quando o problema apareceu.
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 exceder 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 é acionado pelo PutObject. Geralmente, se o formato JSON estiver incorreto ou o callback falhar, uma mensagem correspondente será retornada. Nesse caso, você precisa testar o comportamento de callback do Put e do Post separadamente:
A captura do Wireshark a seguir mostra uma requisição HTTP POST de Callback do OSS e a resposta do servidor:
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"}
-
Causa
Ao enviar a requisição, o parâmetro
callbackfoi colocado incorretamente dentro do parâmetrofile.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 -
Solução
Ajuste a posição dos parâmetros callback e 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/jsonNeste ponto, o resultado do teste mostra que o servidor de negócios capturou a requisição com sucesso.
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
-
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(), você não envie mais requisições 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 da expiração no Java SDK não exceda 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 o tempo de expiração 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, você pode reutilizar uma única instância do OSSClient ou criar 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, você deve chamar o método shutdown para fechá-la e evitar o esgotamento de recursos causado pela criação de muitas instâncias do OSSClient.
É relatado um erro "AccessDenied Hierarchical namespace is disabled"
-
Causa
O namespace hierárquico não estava habilitado antes de você chamar a operação de API CreateDirectory, Rename ou DeleteDirectory.
-
Solução
Habilite o namespace hierárquico 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 lidar com isso?
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 configuro 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 usar 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: Você precisa introduzir a dependência log4j (o log4j 2.x possui vários frameworks de implementação para escolher, sendo o padrão log4j-api+log4j-core) e configurá-lo de acordo com o método de configuração do log4j. Para o processo específico, consulte APACHE LOG4J-API Separation.
JCL over slf4j: Você precisa introduzir as dependências jcl-over-slf4j e slf4j (o slf4j também possui vários frameworks de implementação para escolher, como slf4j-api+logback-classic) e configurá-lo de acordo com 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.
Você pode ativar ou desativar logs do SDK configurando as propriedades do log4j:
#
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
Atualizar para o OSS Java SDK V2
O OSS Java SDK V2 já está disponível. Ele fornece uma API simplificada e mecanismos de nova tentativa aprimorados. Para migrar da V1 para a V2, consulte o Guia de Migração do Java SDK V1 para V2.