

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Programmazione di DynamoDB con AWS SDK for Java 2.x
<a name="ProgrammingWithJava"></a>

Questa guida alla programmazione fornisce un orientamento ai programmatori che desiderano utilizzare Amazon DynamoDB con Java. La guida tratta diversi concetti, tra cui i livelli di astrazione, la gestione della configurazione, la gestione degli errori, il controllo delle policy di ripetizione dei tentativi e la gestione del keep-alive.

**Topics**
+ [Informazioni su AWS SDK for Java 2.x](#AboutProgrammingWithJavaSDK)
+ [Nozioni di base](#GetStartedProgrammingWithJavaSDK)
+ [Documentazione SDK per Java 2.x](#ProgrammingWithJavaUseDoc)
+ [Interfacce supportate](#JavaInterfaces)
+ [Ulteriori esempi di codice](#AdditionalCodeEx)
+ [Programmazione sincrona e asincrona](#SyncAsyncProgramming)
+ [Client HTTP](#HttpClients)
+ [Config](#ConfigHttpClient)
+ [Gestione degli errori](#JavaErrorHandling)
+ [AWS ID della richiesta](#JavaRequestID)
+ [Registrazione dei log](#JavaLogging)
+ [Paginazione](#JavaPagination)
+ [Annotazioni sulle classi di dati](#JavaDataClassAnnotation)

## Informazioni su AWS SDK for Java 2.x
<a name="AboutProgrammingWithJavaSDK"></a>

È possibile accedere a DynamoDB da Java utilizzando il file ufficiale. AWS SDK per Java L’SDK per Java è disponibile in due versioni: 1.x e 2.x. La versione end-of-support 1.x è stata [annunciata](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-java-v1-x-on-december-31-2025/) il 12 gennaio 2024. Entrerà in modalità manutenzione il 31 luglio 2024 e scadrà end-of-support il 31 dicembre 2025. Per le nuove implementazioni, si consiglia vivamente di utilizzare 2.x, che è stata rilasciata per la prima volta nel 2018. In questa guida viene trattata esclusivamente la versione 2.x e vengono illustrate solo le parti dell’SDK relative a DynamoDB.

Per informazioni sulla manutenzione e il supporto di AWS SDKs, consulta la [politica di manutenzione di AWS SDK and Tools e](https://docs.aws.amazon.com/sdkref/latest/guide/maint-policy.html) la [matrice di supporto della versione Tools nella AWS SDKs and Tools](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) Reference *AWS SDKs Guide*.

 AWS SDK for Java 2.x Si tratta di una riscrittura importante del codice base 1.x. L'SDK for Java 2.x supporta le moderne funzionalità Java, come la funzionalità I/O non bloccante introdotta in Java 8. L’SDK per Java 2.x aggiunge anche il supporto per implementazioni di client HTTP collegabili per fornire maggiore flessibilità di connessione di rete e più opzioni di configurazione.

Un cambiamento evidente tra l’SDK per Java 1.x e l’SDK per Java 2.x è l’uso di un nuovo nome pacchetto. L’SDK per Java 1.x utilizza il nome pacchetto `com.amazonaws`, mentre l’SDK per Java 2.x utilizza `software.amazon.awssdk`. Allo stesso modo, gli artefatti Maven per l’SDK per Java 1.x utilizzano il `groupId` `com.amazonaws`, mentre gli artefatti per l’SDK per Java 2.x utilizzano il `groupId` `software.amazon.awssdk`.

**Importante**  
La versione AWS SDK per Java 1.x ha un pacchetto DynamoDB denominato. `com.amazonaws.dynamodbv2` La dicitura “v2” nel nome pacchetto non indica che questo è riservato a Java 2 (J2SE). Piuttosto, “v2” indica che il pacchetto supporta la [seconda versione](CurrentAPI.md) dell’API di basso livello di DynamoDB anziché la [versione originale](Appendix.APIv20111205.md) dell’API di basso livello.

### Support per le versioni Java
<a name="SupportedJavaVersions"></a>

 AWS SDK for Java 2.x [Fornisce il supporto completo per le versioni Java con supporto a lungo termine (LTS).](https://github.com/aws/aws-sdk-java-v2?tab=readme-ov-file#maintenance-and-support-for-java-versions)

## Iniziare con AWS SDK for Java 2.x
<a name="GetStartedProgrammingWithJavaSDK"></a>

Il seguente tutorial mostra come utilizzare [Apache Maven](https://maven.apache.org/) per definire le dipendenze per SDK per Java 2.x. Questo tutorial mostra anche come scrivere il codice che si collega a DynamoDB per elencare le tabelle DynamoDB disponibili. Il tutorial contenuto in questa guida si basa sul tutorial [Get started with the AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html) nella *AWS SDK for Java 2.x Developer Guide*. Questo tutorial è stato modificato per effettuare chiamate a DynamoDB anziché ad Amazon S3.

**Topics**
+ [Fase 1: prepararsi per il tutorial](#GetStartedJavaSetup)
+ [Fase 2: creare il progetto](#GetStartedJavaProjectSetup)
+ [Fase 3: scrivere il codice](#GetStartedJavaCode)
+ [Fase 4: creare ed eseguire l’applicazione](#GetStartedRunJava)

### Fase 1: prepararsi per il tutorial
<a name="GetStartedJavaSetup"></a>

Prima di iniziare questo tutorial, servirà quanto segue:
+ Autorizzazione ad accedere a DynamoDB.
+ Un ambiente di sviluppo Java configurato con accesso Single Sign-On all' Servizi AWS utilizzo di. Portale di accesso AWS

Per prepararti per questo tutorial, segui le istruzioni riportate in [Setup overview](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-overview) nella *AWS SDK for Java 2.x Developer Guide*. Dopo aver [configurato l’ambiente di sviluppo con l’accesso Single Sign-On](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-credentials) per l’SDK per Java e aver svolto una sessione [attiva sul portale di accesso AWS](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso), continua con la [Fase 2](#GetStartedJavaProjectSetup) di questo tutorial.

### Fase 2: creare il progetto
<a name="GetStartedJavaProjectSetup"></a>

Per creare il progetto per questo tutorial, si esegue un comando Maven che richiede input su come configurare il progetto. Dopo aver inserito e confermato tutti gli input, Maven completa la creazione del progetto creando un file `pom.xml` e file Java stub.

1. Apri un terminale o una finestra del prompt dei comandi e accedi a una directory a tua scelta, ad esempio il `Desktop` o la cartella `Home`.

1. Immetti il comando seguente sul terminale, quindi premi Invio.

   ```
   mvn archetype:generate \
      -DarchetypeGroupId=software.amazon.awssdk \
      -DarchetypeArtifactId=archetype-app-quickstart \
      -DarchetypeVersion=2.22.0
   ```

1. Per ogni prompt, inserisci il valore elencato nella seconda colonna.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/it_it/amazondynamodb/latest/developerguide/ProgrammingWithJava.html)

1. Dopo aver inserito l’ultimo valore, Maven elenca le scelte effettuate. Per confermare, inserisci **Y** (per Yes, Sì). In alternativa, inserisci **N** (per No), quindi inserisci nuovamente le tue scelte.

Maven crea una cartella di progetto denominata `getstarted` in base al valore `artifactId` inserito. All’interno della cartella `getstarted`, cerca un file con nome `README.md` che è possibile esaminare, un file `pom.xml` e una directory `src`.

Maven crea la seguente struttura di cartelle.

```
getstarted
 ├── README.md
 ├── pom.xml
 └── src
     ├── main
     │   ├── java
     │   │   └── org
     │   │       └── example
     │   │           ├── App.java
     │   │           ├── DependencyFactory.java
     │   │           └── Handler.java
     │   └── resources
     │       └── simplelogger.properties
     └── test
         └── java
             └── org
                 └── example
                     └── HandlerTest.java
 
 10 directories, 7 files
```

Di seguito viene mostrato il contenuto del file di progetto `pom.xml`.

#### `pom.xml`
<a name="ProjectSetupCollapse2"></a>

La sezione `dependencyManagement` contiene una dipendenza all’ AWS SDK for Java 2.x e la sezione `dependencies` ha una dipendenza per DynamoDB. La specificazione di queste dipendenze impone a Maven di includere i file `.jar` pertinenti nel percorso della classe Java. Per impostazione predefinita, l' AWS SDK non include tutte le classi per tutti. Servizi AWS Per DynamoDB, se si utilizza l’interfaccia di basso livello, dovrebbe essere presente una dipendenza sull’artefatto `dynamodb`. Oppure, se si utilizza l’interfaccia di alto livello, dovrebbe essere presente sull’artefatto `dynamodb-enhanced`. Se non vengono incluse le dipendenze pertinenti, non è possibile compilare il codice. Il progetto utilizza Java 1.8 a causa del valore `1.8` delle proprietà `maven.compiler.source` e `maven.compiler.target`.

```
<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>org.example</groupId>
     <artifactId>getstarted</artifactId>
     <version>1.0-SNAPSHOT</version>
     <packaging>jar</packaging>
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <maven.compiler.source>1.8</maven.compiler.source>
         <maven.compiler.target>1.8</maven.compiler.target>
         <maven.shade.plugin.version>3.2.1</maven.shade.plugin.version>
         <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
         <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
         <aws.java.sdk.version>2.22.0</aws.java.sdk.version> <-------- SDK version picked up from archetype version.
         <slf4j.version>1.7.28</slf4j.version>
         <junit5.version>5.8.1</junit5.version>
     </properties>
 
     <dependencyManagement>
         <dependencies>
             <dependency>
                 <groupId>software.amazon.awssdk</groupId>
                 <artifactId>bom</artifactId>
                 <version>${aws.java.sdk.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
         </dependencies>
     </dependencyManagement>
 
     <dependencies>
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>dynamodb</artifactId>  <-------- DynamoDB dependency
             <exclusions>
                 <exclusion>
                     <groupId>software.amazon.awssdk</groupId>
                     <artifactId>netty-nio-client</artifactId>
                 </exclusion>
                 <exclusion>
                     <groupId>software.amazon.awssdk</groupId>
                     <artifactId>apache-client</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>sso</artifactId> <-------- Required for identity center authentication.
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>ssooidc</artifactId> <-------- Required for identity center authentication.
         </dependency>
 
         <dependency>
             <groupId>software.amazon.awssdk</groupId>
             <artifactId>apache-client</artifactId> <-------- HTTP client specified.
             <exclusions>
                 <exclusion>
                     <groupId>commons-logging</groupId>
                     <artifactId>commons-logging</artifactId>
                 </exclusion>
             </exclusions>
         </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-api</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>slf4j-simple</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <!-- Needed to adapt Apache Commons Logging used by Apache HTTP Client to Slf4j to avoid
         ClassNotFoundException: org.apache.commons.logging.impl.LogFactoryImpl during runtime -->
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>jcl-over-slf4j</artifactId>
             <version>${slf4j.version}</version>
         </dependency>
 
         <!-- Test Dependencies -->
         <dependency>
             <groupId>org.junit.jupiter</groupId>
             <artifactId>junit-jupiter</artifactId>
             <version>${junit5.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
 
     <build>
         <plugins>
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-compiler-plugin</artifactId>
                 <version>${maven.compiler.plugin.version}</version>
             </plugin>
         </plugins>
     </build>
 
 </project>
```

### Fase 3: scrivere il codice
<a name="GetStartedJavaCode"></a>

Il codice seguente mostra la classe `App` creata da Maven. Il metodo `main` è il punto di ingresso nell’applicazione, che crea un’istanza della classe `Handler` e quindi ne richiama il metodo `sendRequest`.

#### Classe `App`
<a name="projectsetup-collapse2"></a>

```
package org.example;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 public class App {
     private static final Logger logger = LoggerFactory.getLogger(App.class);
 
     public static void main(String... args) {
         logger.info("Application starts");
 
         Handler handler = new Handler();
         handler.sendRequest();
 
         logger.info("Application ends");
     }
 }
```

La classe `DependencyFactory` creata da Maven contiene il metodo factory `dynamoDbClient` che crea e restituisce un’istanza [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html). L’istanza `DynamoDbClient` utilizza un’istanza del client HTTP basato su Apache. Questo avviene perché si specifica `apache-client` quando Maven chiede quale client HTTP usare.

Il codice seguente mostra la classe `DependencyFactory`.

#### DependencyFactory classe
<a name="code-collapse2"></a>

```
package org.example;
 
 import software.amazon.awssdk.http.apache.ApacheHttpClient;
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 
 /**
  * The module containing all dependencies required by the {@link Handler}.
  */
 public class DependencyFactory {
 
     private DependencyFactory() {}
 
     /**
      * @return an instance of DynamoDbClient
      */
     public static DynamoDbClient dynamoDbClient() {
         return DynamoDbClient.builder()
                        .httpClientBuilder(ApacheHttpClient.builder())
                        .build();
     }
 }
```

La classe `Handler` contiene la logica principale del programma. Quando viene creata un’istanza di `Handler` nella classe `App`, `DependencyFactory` fornisce il servizio client `DynamoDbClient`. Il codice utilizza l’istanza `DynamoDbClient` per chiamare DynamoDB.

Maven genera la seguente classe `Handler` con un commento `TODO`. La fase successiva del tutorial sostituisce il commento *`TODO`* con il codice.

#### Classe `Handler`, generata da Maven
<a name="code-collapsible3"></a>

```
package org.example;
 
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 
 
 public class Handler {
     private final DynamoDbClient dynamoDbClient;
 
     public Handler() {
         dynamoDbClient = DependencyFactory.dynamoDbClient();
     }
 
     public void sendRequest() {
         // TODO: invoking the API calls using dynamoDbClient.
     }
 }
```

Per compilare la logica, sostituisci l’intero contenuto della classe `Handler` con il codice seguente. Il metodo `sendRequest` viene compilato e vengono aggiunte le importazioni necessarie.

#### Classe `Handler`, implementata
<a name="code-collapse4"></a>

Il codice seguente utilizza l’istanza [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html) per recuperare un elenco di tabelle esistenti. Se esistono tabelle per un determinato account e Regione AWS, il codice utilizza l’istanza `Logger` per registrare log dei nomi di queste tabelle.

```
package org.example;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
 import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
 
 
 public class Handler {
     private final DynamoDbClient dynamoDbClient;
 
     public Handler() {
         dynamoDbClient = DependencyFactory.dynamoDbClient();
     }
 
     public void sendRequest() {
         Logger logger = LoggerFactory.getLogger(Handler.class);
 
         logger.info("calling the DynamoDB API to get a list of existing tables");
         ListTablesResponse response = dynamoDbClient.listTables();
 
         if (!response.hasTableNames()) {
             logger.info("No existing tables found for the configured account & region");
         } else {
             response.tableNames().forEach(tableName -> logger.info("Table: " + tableName));
         }
     }
 }
```

### Fase 4: creare ed eseguire l’applicazione
<a name="GetStartedRunJava"></a>

Dopo aver creato il progetto e nel momento in cui contiene la classe `Handler` completa, crea ed esegui l’applicazione.

1. Assicurati di avere una AWS IAM Identity Center sessione attiva. Per confermare, esegui il comando AWS Command Line Interface (AWS CLI) `aws sts get-caller-identity` e controlla la risposta. Se non è presente una sessione attiva, consulta [Sign in using the AWS CLI](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup.html#setup-login-sso) per istruzioni.

1. Apri un terminale o una finestra del prompt dei comandi e vai alla directory del progetto `getstarted`.

1. Pre compilare il progetto esegui il comando seguente:

   ```
   mvn clean package
   ```

1. Per eseguire l’applicazione, esegui il comando seguente:

   ```
   mvn exec:java -Dexec.mainClass="org.example.App"
   ```

Dopo aver visualizzato il file, elimina l’oggetto e quindi elimina il bucket.

#### Completato
<a name="GetStartedSuccessJava"></a>

Se il progetto Maven è stato creato ed eseguito senza errori, congratulazioni\$1 Hai creato con successo la tua prima applicazione Java utilizzando SDK per Java 2.x.

#### Pulizia
<a name="GetStartedCleanupJava"></a>

Per eliminare le risorse create durante questo tutorial, elimina la cartella del progetto `getstarted`.

## Revisione della AWS SDK for Java 2.x documentazione
<a name="ProgrammingWithJavaUseDoc"></a>

La [AWS SDK for Java 2.x Developer Guide](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/home.html) copre tutti gli aspetti dell’SDK in tutti i Servizi AWS. Si consiglia di iniziare dagli argomenti seguenti:
+ [Migrate from version 1.x to 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/migration.html): include una spiegazione dettagliata delle differenze tra 1.x e 2.x. Questo argomento contiene anche istruzioni su come utilizzare entrambe le versioni principali side-by-side.
+ [DynamoDB guide for Java 2.x SDK](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/examples-dynamodb.html): mostra come eseguire le operazioni di base di DynamoDB: creazione di una tabella, manipolazione di elementi e recupero di elementi. Questi esempi utilizzano l’interfaccia di basso livello. Java ha diverse interfacce, come spiegato nella sezione seguente: [Interfacce supportate](#JavaInterfaces).

**Suggerimento**  
Dopo aver esaminato questi argomenti, aggiungi la [documentazione di riferimento dell’API AWS SDK for Java 2.x](https://sdk.amazonaws.com/java/api/latest/) ai segnalibri. Copre tutto Servizi AWS e ti consigliamo di utilizzarlo come riferimento API principale.

## Interfacce supportate
<a name="JavaInterfaces"></a>

 AWS SDK for Java 2.x Supporta le seguenti interfacce, a seconda del livello di astrazione desiderato.

**Topics**
+ [Interfaccia di basso livello](#LowLevelInterface)
+ [Interfaccia di alto livello](#HighLevelInterface)
+ [Interfaccia documentale](#DocumentInterface)
+ [Confronto delle interfacce con un esempio `Query`](#CompareJavaInterfacesQueryEx)

### Interfaccia di basso livello
<a name="LowLevelInterface"></a>

L'interfaccia di basso livello fornisce una one-to-one mappatura all'API di servizio sottostante. Ogni API DynamoDB è disponibile tramite questa interfaccia. Ciò significa che l’interfaccia di basso livello può fornire funzionalità complete, ma è spesso più verbosa e complessa da usare. Ad esempio, è necessario utilizzare le funzioni `.s()` per contenere le stringhe e le funzioni `.n()` per contenere i numeri. Il seguente esempio di [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)inserimento di un elemento utilizzando l'interfaccia di basso livello.

```
import org.slf4j.*;
import software.amazon.awssdk.http.crt.AwsCrtHttpClient;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.util.Map;

public class PutItem {

    // Create a DynamoDB client with the default settings connected to the DynamoDB
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.create();
    private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);

    private void putItem() {
        PutItemResponse response = DYNAMODB_CLIENT.putItem(PutItemRequest.builder()
                .item(Map.of(
                        "pk", AttributeValue.builder().s("123").build(),
                        "sk", AttributeValue.builder().s("cart#123").build(),
                        "item_data", AttributeValue.builder().s("YourItemData").build(),
                        "inventory", AttributeValue.builder().n("500").build()
                        // ... more attributes ...
                ))
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .tableName("YourTableName")
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

### Interfaccia di alto livello
<a name="HighLevelInterface"></a>

L'interfaccia di alto livello di AWS SDK for Java 2.x si chiama DynamoDB Enhanced Client. Questa interfaccia offre un’esperienza di creazione del codice più idiomatica.

Il client avanzato offre una modalità di mappatura tra le classi di dati lato client e le tabelle DynamoDB progettate per archiviare tali dati. È possibile definire le relazioni tra le tabelle e le relative classi di modello corrispondenti nel codice. È quindi possibile fare affidamento sull’SDK per gestire la manipolazione dei tipi di dati. Per ulteriori informazioni sul client avanzato, consulta [DynamoDB enhanced client API](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/dynamodb-enhanced-client.html) nella *AWS SDK for Java 2.x Developer Guide.*

L'esempio seguente [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)utilizza l'interfaccia di alto livello. In questo esempio, `DynamoDbBean` con nome `YourItem` crea un file `TableSchema` che ne consente l’uso diretto come input per la chiamata `putItem()`.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientPutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(YourItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(PutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourItem.class)
                .item(new YourItem("123", "cart#123", "YourItemData", 500))
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }

    @DynamoDbBean
    public static class YourItem {

        public YourItem() {}

        public YourItem(String pk, String sk, String itemData, int inventory) {
            this.pk = pk;
            this.sk = sk;
            this.itemData = itemData;
            this.inventory = inventory;
        }

        private String pk;
        private String sk;
        private String itemData;

        private int inventory;

        @DynamoDbPartitionKey
        public void setPk(String pk) {
            this.pk = pk;
        }

        public String getPk() {
            return pk;
        }

        @DynamoDbSortKey
        public void setSk(String sk) {
            this.sk = sk;
        }

        public String getSk() {
            return sk;
        }

        public void setItemData(String itemData) {
            this.itemData = itemData;
        }

        public String getItemData() {
            return itemData;
        }

        public void setInventory(int inventory) {
            this.inventory = inventory;
        }

        public int getInventory() {
            return inventory;
        }
    }
}
```

L' AWS SDK per Java 1.x ha una propria interfaccia di alto livello, a cui spesso si fa riferimento con la sua classe principale. `DynamoDBMapper` AWS SDK for Java 2.x È pubblicato in un pacchetto separato (e artefatto Maven) denominato. `software.amazon.awssdk.enhanced.dynamodb` L’SDK per Java 2.x viene spesso identificato tramite la sua classe principale `DynamoDbEnhancedClient`.

#### Interfaccia di alto livello con classi di dati immutabili
<a name="HighLevelInterfaceImmutableDataClasses"></a>

La funzionalità di mappatura fornita dall’API avanzata del client DynamoDB funziona anche con classi di dati immutabili. Una classe immutabile ha solo getter e richiede una classe builder che l’SDK utilizza per creare istanze della classe. L’immutabilità in Java è uno stile privo di effetti collaterali comunemente usato che gli sviluppatori possono utilizzare per creare classi. Queste classi hanno un comportamento più prevedibile in applicazioni multi-thread complesse. Invece di utilizzare l’annotazione `@DynamoDbBean` come mostrato nell’[High-level interface example](#highleveleg), le classi immutabili utilizzano l’annotazione `@DynamoDbImmutable`, che accetta la classe builder come input.

L’esempio seguente utilizza la classe builder `DynamoDbEnhancedClientImmutablePutItem` come input per creare uno schema della tabella. L'esempio fornisce quindi lo schema come input per la chiamata API. [PutItem](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html)

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientImmutablePutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourImmutableItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutablePutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourImmutableItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableItem.class)
                .item(YourImmutableItem.builder()
                                        .pk("123")
                                        .sk("cart#123")
                                        .itemData("YourItemData")
                                        .inventory(500)
                                        .build())
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

L’esempio seguente mostra la classe di dati immutabili.

```
@DynamoDbImmutable(builder = YourImmutableItem.YourImmutableItemBuilder.class)
class YourImmutableItem {
    private final String pk;
    private final String sk;
    private final String itemData;
    private final int inventory;
    public YourImmutableItem(YourImmutableItemBuilder builder) {
        this.pk = builder.pk;
        this.sk = builder.sk;
        this.itemData = builder.itemData;
        this.inventory = builder.inventory;
    }

    public static YourImmutableItemBuilder builder() { return new YourImmutableItemBuilder(); }

    @DynamoDbPartitionKey
    public String getPk() {
        return pk;
    }

    @DynamoDbSortKey
    public String getSk() {
        return sk;
    }

    public String getItemData() {
        return itemData;
    }

    public int getInventory() {
        return inventory;
    }

    static final class YourImmutableItemBuilder {
        private String pk;
        private String sk;
        private String itemData;
        private int inventory;

        private YourImmutableItemBuilder() {}

        public YourImmutableItemBuilder pk(String pk) { this.pk = pk; return this; }
        public YourImmutableItemBuilder sk(String sk) { this.sk = sk; return this; }
        public YourImmutableItemBuilder itemData(String itemData) { this.itemData = itemData; return this; }
        public YourImmutableItemBuilder inventory(int inventory) { this.inventory = inventory; return this; }

        public YourImmutableItem build() { return new YourImmutableItem(this); }
    }
}
```

#### Interfaccia di alto livello che utilizza classi di dati immutabili e librerie di generazione di codice boilerplate di terze parti
<a name="ImmutableDataClassesThirdPartyBoilerplateGenLib"></a>

Le classi di dati immutabili (mostrate nell’esempio precedente) richiedono codice boilerplate. Ad esempio, la logica di getter e setter sulle classi di dati, oltre alle classi `Builder`. Le librerie di terze parti, come [Project Lombok](https://projectlombok.org/), possono aiutare a generare quel tipo di codice boilerplate. La riduzione della maggior parte del codice standard consente di limitare la quantità di codice necessaria per lavorare con classi di dati immutabili e l'SDK. AWS Ciò determina inoltre una migliore produttività e leggibilità del codice. Per ulteriori informazioni, consulta [Use third-party libraries, such as Lombok](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-use-immut.html#ddb-en-client-use-immut-lombok) nella *AWS SDK for Java 2.x Developer Guide*.

L’esempio seguente mostra come Project Lombok semplifica il codice necessario per utilizzare l’API avanzata del client DynamoDB.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedClientImmutableLombokPutItem {

    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourImmutableLombokItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromImmutableClass(YourImmutableLombokItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientImmutableLombokPutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<YourImmutableLombokItem> response = DYNAMODB_TABLE.putItemWithResponse(PutItemEnhancedRequest.builder(YourImmutableLombokItem.class)
                .item(YourImmutableLombokItem.builder()
                        .pk("123")
                        .sk("cart#123")
                        .itemData("YourItemData")
                        .inventory(500)
                        .build())
                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }
}
```

L’esempio seguente mostra l’oggetto di dati immutabili della classe di dati immutabili.

```
import lombok.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;

@Builder
@DynamoDbImmutable(builder = YourImmutableLombokItem.YourImmutableLombokItemBuilder.class)
@Value
public class YourImmutableLombokItem {

    @Getter(onMethod_=@DynamoDbPartitionKey)
    String pk;
    @Getter(onMethod_=@DynamoDbSortKey)
    String sk;
    String itemData;
    int inventory;
}
```

La `YourImmutableLombokItem` classe utilizza le seguenti annotazioni fornite da Project Lombok e dall'SDK: AWS 
+ [@Builder](https://projectlombok.org/features/Builder) — Produce un generatore complesso APIs per le classi di dati fornito da Project Lombok.
+ [@ DynamoDbImmutable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/DynamoDbImmutable.html) — Identifica la `DynamoDbImmutable` classe come annotazione di entità mappabile DynamoDB fornita dall'SDK. AWS 
+ [@Value](https://projectlombok.org/features/Value): la variante immutabile di `@Data`. Per impostazione predefinita, tutti i campi vengono resi privati e definitivi e i setter non vengono generati. Project Lombok fornisce questa annotazione.

### Interfaccia documentale
<a name="DocumentInterface"></a>

L'interfaccia AWS SDK for Java 2.x Document evita la necessità di specificare i descrittori dei tipi di dati. I tipi di dati sono impliciti nella semantica dei dati stessi. Questa interfaccia Document è simile alla AWS SDK per Java 1.x, interfaccia Document, ma con un'interfaccia riprogettata.

Il seguente [Document interface example](#DocInterfaceEg) illustra la chiamata `PutItem` espressa utilizzando l’interfaccia documentale. L'esempio utilizza anche. EnhancedDocument Per eseguire comandi su una tabella DynamoDB utilizzando l’API del documento avanzata, è necessario innanzitutto associare la tabella allo schema della tabella documentale per creare un oggetto risorsa `DynamoDBTable`. Il generatore di schemi della tabella documentale richiede la chiave dell’indice primario e i provider dei convertitori di attributi.

È possibile utilizzare `AttributeConverterProvider.defaultProvider()` per convertire gli attributi documentali di tipi predefiniti. È possibile modificare il comportamento predefinito generale con un’implementazione `AttributeConverterProvider` personalizzata. Inoltre, è possibile modificare il convertitore per un singolo attributo. La [AWS SDKs and Tools Reference Guide](https://docs.aws.amazon.com/sdkref/latest/guide/version-support-matrix.html) fornisce maggiori dettagli ed esempi su come utilizzare i convertitori personalizzati. Il loro utilizzo principale è per gli attributi delle classi di dominio che non dispongono di un convertitore predefinito. Utilizzando un convertitore personalizzato, è possibile fornire all’SDK le informazioni necessarie per scrivere o leggere su DynamoDB.

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.ReturnConsumedCapacity;

public class DynamoDbEnhancedDocumentClientPutItem {
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
            ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
                            .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
                            .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                            .build());

    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientPutItem.class);

    private void putItem() {
        PutItemEnhancedResponse<EnhancedDocument> response = DYNAMODB_TABLE.putItemWithResponse(
                        PutItemEnhancedRequest.builder(EnhancedDocument.class)
                                .item(
                                    EnhancedDocument.builder()
                                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                                            .putString("pk", "123")
                                            .putString("sk", "cart#123")
                                            .putString("item_data", "YourItemData")
                                            .putNumber("inventory", 500)
                                            .build())
                                .returnConsumedCapacity(ReturnConsumedCapacity.TOTAL)
                                .build());
        LOGGER.info("PutItem call consumed [" + response.consumedCapacity().capacityUnits() + "] Write Capacity Unites (WCU)");
    }

}
```

Per convertire documenti JSON da e verso tipi di dati nativi di Amazon DynamoDB, è possibile utilizzare i seguenti metodi di utilizzo:
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#fromJson(java.lang.String))— Crea una nuova EnhancedDocument istanza da una stringa JSON.
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html#toJson()): crea una rappresentazione in formato stringa JSON del documento che è possibile utilizzare nell’applicazione come qualsiasi altro oggetto JSON.

### Confronto delle interfacce con un esempio `Query`
<a name="CompareJavaInterfacesQueryEx"></a>

Questa sezione mostra la stessa chiamata [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) espressa utilizzando le varie interfacce. Per ottimizzare i risultati di queste query, tieni presente quanto segue:
+ DynamoDB ha come destinazione un valore della chiave di partizione specifico, quindi è necessario specificare la chiave di partizione in modo completo.
+ Per fare in modo che la query abbia come destinazione solo gli articoli del carrello, la chiave di ordinamento contiene un’espressione di condizione della chiave che utilizza `begins_with`.
+ Si utilizza `limit()` per limitare la richiesta a un massimo di 100 elementi restituiti.
+ Si imposta il valore `scanIndexForward` su false. I risultati vengono restituiti in ordine di byte UTF-8, il che di solito significa che l’articolo nel carrello con il numero più basso viene restituito per primo. Impostando il valore `scanIndexForward` su false, si inverte l’ordine e l’articolo nel carrello con il numero più alto viene restituito per primo.
+ Si applica un filtro per rimuovere qualsiasi risultato che non corrisponde ai criteri. I dati filtrati consumano la capacità di lettura indipendentemente dal fatto che l’elemento corrisponda al filtro.

**Example `Query` con l’interfaccia di basso livello**  
L’esempio seguente esegue la query di una tabella denominata `YourTableName` utilizzando una `keyConditionExpression`. Ciò limita la query a un valore specifico della chiave di partizione e a un valore della chiave di ordinamento che iniziano con un valore di prefisso specifico. Queste condizioni della chiave limitano la quantità di dati letti da DynamoDB. Infine, la query applica un filtro sui dati recuperati da DynamoDB utilizzando una `filterExpression`.  

```
import org.slf4j.*;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;

import java.util.Map;

public class Query {

    // Create a DynamoDB client with the default settings connected to the DynamoDB 
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbClient DYNAMODB_CLIENT = DynamoDbClient.builder().build();
    private static final Logger LOGGER = LoggerFactory.getLogger(Query.class);

    private static void query() {
        QueryResponse response = DYNAMODB_CLIENT.query(QueryRequest.builder()
                .expressionAttributeNames(Map.of("#name", "name"))
                .expressionAttributeValues(Map.of(
                    ":pk_val", AttributeValue.fromS("id#1"),
                    ":sk_val", AttributeValue.fromS("cart#"),
                    ":name_val", AttributeValue.fromS("SomeName")))
                .filterExpression("#name = :name_val")
                .keyConditionExpression("pk = :pk_val AND begins_with(sk, :sk_val)")
                .limit(100)
                .scanIndexForward(false)
                .tableName("YourTableName")
                .build());

        LOGGER.info("nr of items: " + response.count());
        LOGGER.info("First item pk: " + response.items().get(0).get("pk"));
        LOGGER.info("First item sk: " + response.items().get(0).get("sk"));
    }
}
```

**Example `Query` con l’interfaccia documentale**  
L’esempio seguente esegue la query di una tabella denominata `YourTableName` utilizzando un’interfaccia documentale.  

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.document.EnhancedDocument;
import software.amazon.awssdk.enhanced.dynamodb.model.*;

import java.util.Map;

public class DynamoDbEnhancedDocumentClientQuery {

    // Create a DynamoDB client with the default settings connected to the DynamoDB 
    // endpoint in the default region based on the default credentials provider chain.
    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<EnhancedDocument> DYNAMODB_TABLE =
            ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.documentSchemaBuilder()
                    .addIndexPartitionKey(TableMetadata.primaryIndexName(),"pk", AttributeValueType.S)
                    .addIndexSortKey(TableMetadata.primaryIndexName(), "sk", AttributeValueType.S)
                    .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                    .build());
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedDocumentClientQuery.class);

    private void query() {
        PageIterable<EnhancedDocument> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#name = :name_val")
                        .expressionNames(Map.of("#name", "name"))
                        .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
                        .build())
                .limit(100)
                .queryConditional(QueryConditional.sortBeginsWith(Key.builder()
                        .partitionValue("id#1")
                        .sortValue("cart#")
                        .build()))
                .scanIndexForward(false)
                .build());

        LOGGER.info("nr of items: " + response.items().stream().count());
        LOGGER.info("First item pk: " + response.items().iterator().next().getString("pk"));
        LOGGER.info("First item sk: " + response.items().iterator().next().getString("sk"));

    }
}
```

**Example `Query` con l’interfaccia di alto livello**  
L’esempio seguente esegue una query di una tabella denominata `YourTableName` utilizzando l’API avanzata del client DynamoDB.  

```
import org.slf4j.*;
import software.amazon.awssdk.enhanced.dynamodb.*;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.*;
import software.amazon.awssdk.enhanced.dynamodb.model.*;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;

import java.util.Map;

public class DynamoDbEnhancedClientQuery {

    private static final DynamoDbEnhancedClient ENHANCED_DYNAMODB_CLIENT = DynamoDbEnhancedClient.builder().build();
    private static final DynamoDbTable<YourItem> DYNAMODB_TABLE = ENHANCED_DYNAMODB_CLIENT.table("YourTableName", TableSchema.fromBean(DynamoDbEnhancedClientQuery.YourItem.class));
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamoDbEnhancedClientQuery.class);

    private void query() {
        PageIterable<YourItem> response = DYNAMODB_TABLE.query(QueryEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#name = :name_val")
                        .expressionNames(Map.of("#name", "name"))
                        .expressionValues(Map.of(":name_val", AttributeValue.fromS("SomeName")))
                        .build())
                .limit(100)
                .queryConditional(QueryConditional.sortBeginsWith(Key.builder()
                        .partitionValue("id#1")
                        .sortValue("cart#")
                        .build()))
                .scanIndexForward(false)
                .build());

        LOGGER.info("nr of items: " + response.items().stream().count());
        LOGGER.info("First item pk: " + response.items().iterator().next().getPk());
        LOGGER.info("First item sk: " + response.items().iterator().next().getSk());
    }

    @DynamoDbBean
    public static class YourItem {

        public YourItem() {}

        public YourItem(String pk, String sk, String name) {
            this.pk = pk;
            this.sk = sk;
            this.name = name;
        }

        private String pk;
        private String sk;
        private String name;

        @DynamoDbPartitionKey
        public void setPk(String pk) {
            this.pk = pk;
        }

        public String getPk() {
            return pk;
        }

        @DynamoDbSortKey
        public void setSk(String sk) {
            this.sk = sk;
        }

        public String getSk() {
            return sk;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}
```
**Interfaccia di alto livello con classi di dati immutabili**  
Quando si esegue un’operazione `Query` con le classi di dati immutabili di alto livello, il codice è lo stesso dell’esempio di interfaccia di alto livello, a eccezione della costruzione della classe di entità `YourItem` o `YourImmutableItem`. Per ulteriori informazioni, consulta l'[PutItem](#HighLevelImmutableDataClassEg)esempio.
**Interfaccia di alto livello che utilizza classi di dati immutabili e librerie di generazione di codice boilerplate di terze parti**  
Quando si esegue un’operazione `Query` con le classi di dati immutabili di alto livello, il codice è lo stesso dell’esempio di interfaccia di alto livello, a eccezione della costruzione della classe di entità `YourItem` o `YourImmutableLombokItem`. Per ulteriori informazioni, consulta l'[PutItem](#HighLevelImmutableDataClassEg)esempio.

## Ulteriori esempi di codice
<a name="AdditionalCodeEx"></a>

Per ulteriori esempi di utilizzo di DynamoDB con l’SDK per Java 2.x, fai riferimento ai seguenti repository di esempi di codice:
+ [Esempi di codice a singola azione AWS ufficiali](https://docs.aws.amazon.com/code-library/latest/ug/java_2_dynamodb_code_examples.html)
+ [Esempi di codice a singola azione gestiti dalla community](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)
+ [Esempi di codice ufficiali AWS orientati allo scenario](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/examples/SDK/java)

## Programmazione sincrona e asincrona
<a name="SyncAsyncProgramming"></a>

 AWS SDK for Java 2.x Fornisce client *sincroni* e *asincroni* per, Servizi AWS come DynamoDB.

Le classi `DynamoDbClient` e `DynamoDbEnhancedClient` forniscono metodi sincroni che bloccano l’esecuzione del thread finché il client non riceve una risposta dal servizio. Questo client è il modo più semplice per interagire con DynamoDB se non sono necessarie operazioni asincrone.

Le classi `DynamoDbAsyncClient` e `DynamoDbEnhancedAsyncClient` forniscono metodi asincroni che terminano immediatamente, riassegnando il controllo al thread chiamante senza attendere una risposta. Il client senza blocchi ha un vantaggio che sfrutta per un’elevata simultaneità su pochi thread, il che consente una gestione efficiente delle richieste di I/O con risorse di calcolo minime. Ciò migliora il throughput e la reattività.

 AWS SDK for Java 2.x Utilizza il supporto nativo per I/O non bloccanti. La versione 1.x doveva simulare I/O non bloccanti. AWS SDK per Java 

I metodi asincroni terminano prima che sia disponibile una risposta, perciò occorre un modo per ottenere la risposta quando è pronta. I metodi asincroni in AWS SDK per Java restituiscono un [https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)oggetto che contiene i risultati delle operazioni asincrone future. Quando si chiamano query `get()` o `join()` su questi oggetti `CompletableFuture`, il codice si blocca finché il risultato non è disponibile. Se queste query vengono chiamate contemporaneamente alla richiesta, il comportamento è simile a una semplice chiamata sincrona.

Per ulteriori informazioni sulla programmazione asincrona, consulta [Use asynchronous programming](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/asynchronous.html) nella *AWS SDK for Java 2.x Developer Guide*.

## Client HTTP
<a name="HttpClients"></a>

Per supportare ogni client, esiste un client HTTP che gestisce la comunicazione con i Servizi AWS. È possibile collegare client HTTP alternativi, scegliendone uno con le caratteristiche più adatte alla propria applicazione. Alcuni sono più leggeri, altri hanno più opzioni di configurazione.

Alcuni client HTTP supportano solo l’uso sincrono, mentre altri supportano solo l’uso asincrono. Per un diagramma di flusso che può aiutare a selezionare il client HTTP ottimale per uno specifico carico di lavoro, consulta [HTTP client recommendations](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration.html#http-clients-recommend) nella *AWS SDK for Java 2.x Developer Guide*.

L’elenco seguente presenta alcuni dei possibili client HTTP:

**Topics**
+ [Client HTTP basato su Apache](#ApacheHttpClient)
+ [Client HTTP basato su `URLConnection`](#URLConnHttpClient)
+ [Client HTTP basato su Netty](#NettyHttpClient)
+ [AWS Client HTTP basato su CRT](#AWSCRTHttpClient)

### Client HTTP basato su Apache
<a name="ApacheHttpClient"></a>

La classe [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/apache/ApacheHttpClient.html) supporta client di servizio sincroni. È il client HTTP predefinito per l’uso sincrono. Per informazioni sulla configurazione della classe `ApacheHttpClient`, consulta [Configure the Apache-based HTTP client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-apache.html) nella *AWS SDK for Java 2.x Developer Guide*.

### Client HTTP basato su `URLConnection`
<a name="URLConnHttpClient"></a>

La classe [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html) è un’altra opzione per i client sincroni. Si carica più velocemente rispetto al client HTTP basato su Apache, ma ha meno funzionalità. *Per informazioni sulla configurazione della `UrlConnectionHttpClient` classe, consulta [Configurare il client HTTP URLConnection basato nella Guida per gli sviluppatori](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-url.html).AWS SDK for Java 2.x *

### Client HTTP basato su Netty
<a name="NettyHttpClient"></a>

La classe `NettyNioAsyncHttpClient` supporta client asincroni. È la scelta predefinita per l’uso asincrono. Per informazioni sulla classe `NettyNioAsyncHttpClient`, consulta [Configure the Netty-based HTTP client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-netty.html) nella *AWS SDK for Java 2.x Developer Guide*.

### AWS Client HTTP basato su CRT
<a name="AWSCRTHttpClient"></a>

Le nuove `AwsCrtHttpClient` e `AwsCrtAsyncHttpClient` le classi delle librerie AWS Common Runtime (CRT) sono altre opzioni che supportano client sincroni e asincroni. Rispetto ad altri client HTTP, CRT offre: AWS 
+ Tempo di avvio del’SDK più rapido
+ Ingombro di memoria minore
+ Tempo di latenza ridotto
+ Gestione dell’integrità delle connessioni
+ Bilanciamento del carico DNS

*Per informazioni sulla configurazione delle `AwsCrtAsyncHttpClient` classi `AwsCrtHttpClient` and, consultate [Configurare i client HTTP AWS basati su CRT](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html) nella Guida per gli sviluppatori.AWS SDK for Java 2.x *

Il client HTTP AWS basato su CRT non è l'impostazione predefinita perché ciò comprometterebbe la compatibilità con le versioni precedenti delle applicazioni esistenti. Tuttavia, per DynamoDB consigliamo di utilizzare il client HTTP basato su CRT sia per usi AWS sincronizzati che asincroni.

*Per un'introduzione al client HTTP AWS basato su CRT, consulta [Annuncio della disponibilità del client HTTP AWS CRT nel blog](https://aws.amazon.com/blogs/developer/announcing-availability-of-the-aws-crt-http-client-in-the-aws-sdk-for-java-2-x/) sugli strumenti per sviluppatori. AWS SDK for Java 2.xAWS *

## Configurazione di un client HTTP
<a name="ConfigHttpClient"></a>

Per la configurazione di un client, è possibile fornire diverse opzioni di configurazione, tra cui:
+ Impostazione dei timeout per diversi aspetti delle chiamate API.
+ Abilitazione di TCP Keep-Alive.
+ Controllo della policy di ripetizione dei tentativi in caso di errori.
+ Specifica degli attributi di esecuzione che le istanze degli [strumenti di intercettazione dell’esecuzione](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/interceptors.html) possono modificare. Gli strumenti di intercettazione dell’esecuzione possono scrivere codice che intercetta l’esecuzione delle richieste e delle risposte dell’API. Ciò consente di eseguire attività come la pubblicazione di metriche e la modifica delle richieste in corso.
+ Aggiunta o manipolazione delle intestazioni HTTP.
+ Abilitazione del monitoraggio delle [metriche delle prestazioni lato client](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/metrics.html). L'utilizzo di questa funzionalità ti aiuta a raccogliere metriche sui client di servizio nella tua applicazione e ad analizzare l'output in Amazon CloudWatch.
+ Specificazione di un servizio di esecuzione alternativo da utilizzare per la pianificazione delle attività, ad esempio la ripetizione dei tentativi e attività di timeout asincroni.

È possibile controllare la configurazione fornendo un oggetto [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html) alla classe `Builder` del client di servizio. Questo verrà riportato in alcuni esempi di codice nelle sezioni seguenti.

`ClientOverrideConfiguration` fornisce scelte di configurazione standard. I diversi client HTTP collegabili hanno anche possibilità di configurazione specifiche per l’implementazione.

**Topics**
+ [Configurazione del timeout](#TimeoutConfig)
+ [RetryMode](#RetryMode)
+ [DefaultsMode](#DefaultsMode)
+ [Configurazione Keep-Alive](#KeepAliveConfig)

### Configurazione del timeout
<a name="TimeoutConfig"></a>

È possibile regolare la configurazione del client per controllare vari timeout relativi alle chiamate del servizio. DynamoDB offre latenze inferiori rispetto ad altri Servizi AWS. Pertanto, si potrebbe voler modificare queste proprietà per ridurre i valori di timeout in modo da poter anticipare l’errore (fail fast) in caso di problemi di rete.

È possibile personalizzare il comportamento relativo alla latenza utilizzando `ClientOverrideConfiguration` sul client DynamoDB o modificando le opzioni di configurazione dettagliate sull’implementazione del client HTTP sottostante.

È possibile configurare le seguenti proprietà di impatto utilizzando `ClientOverrideConfiguration`:
+ `apiCallAttemptTimeout`: il tempo di attesa per il completamento di un singolo tentativo di completare una richiesta HTTP prima della rinuncia e dell’interruzione.
+ `apiCallTimeout`: il periodo di tempo a disposizione del client per eseguire completamente una chiamata API. Ciò include l’esecuzione del gestore delle richieste che consiste in tutte le richieste HTTP, incluse le ripetizioni di tentativi.

 AWS SDK for Java 2.x Fornisce [valori predefiniti](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) per alcune opzioni di timeout, come il timeout della connessione e i timeout del socket. L’SDK non fornisce valori predefiniti per i timeout delle chiamate API o i timeout dei singoli tentativi di chiamata API. Se questi timeout non sono impostati in `ClientOverrideConfiguration`, l’SDK utilizza invece il valore di timeout del socket per il timeout complessivo delle chiamate API. La sessione ha un valore di timeout predefinito di 30 secondi.

### RetryMode
<a name="RetryMode"></a>

Un’altra configurazione correlata alla configurazione del timeout da prendere in considerazione è l’oggetto di configurazione `RetryMode`. Questo oggetto di configurazione contiene una raccolta di comportamenti relativi alla ripetizione dei tentativi.

L’SDK per Java 2.x supporta le seguenti modalità di ripetizione dei tentativi:
+ `legacy`: la modalità di ripetizione dei tentativi predefinita se non la si modifica esplicitamente. Questa modalità di ripetizione dei tentativi è specifica dell’SDK per Java. È caratterizzata da un massimo di tre ripetizioni di tentativi, o più per servizi come DynamoDB, che prevede fino a otto ripetizioni.
+ `standard`— Chiamato «standard» perché è più coerente con gli altri. AWS SDKs Questa modalità attende un periodo di tempo casuale compreso tra 0 ms e 1.000 ms per la prima ripetizione di tentativo. Se è necessaria una nuova ripetizione di tentativo, questa modalità seleziona un altro periodo di tempo casuale da 0 ms a 1.000 ms e lo moltiplica per due. Se è necessaria una nuova ripetizione di tentativo, esegue la stessa scelta casuale moltiplicata per quattro e così via. Ogni attesa è limitata a 20 secondi. Questa modalità esegue ripetizioni di tentativi su un numero maggiore di condizioni di errore rilevate rispetto alla modalità `legacy`. Per DynamoDB, esegue fino a un massimo di tre tentativi, a meno che non si esegua la sostituzione con [numRetries](#numRetries).
+ `adaptive`: si basa sulla modalità `standard` e limita dinamicamente la frequenza delle richieste AWS per massimizzare la percentuale di successo. Ciò può avvenire a scapito della latenza delle richieste. Non si consiglia la modalità adattiva per la ripetizione dei tentativi quando la latenza prevedibile è importante.

È possibile trovare una definizione estesa di queste modalità di ripetizione nell'argomento sul [comportamento Riprova](https://docs.aws.amazon.com/sdkref/latest/guide/feature-retry-behavior.html) nella Guida di *riferimento agli strumenti AWS SDKs e agli strumenti*.

#### Policy di ripetizione dei tentativi
<a name="RetryPolicies"></a>

Tutte le configurazioni `RetryMode` hanno una [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html), che è costruita sulla base di una o più configurazioni [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html). [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/TokenBucketRetryCondition.html) è particolarmente importante per il comportamento di ripetizione dei tentativi dell’implementazione del client SDK di DynamoDB. Questa condizione limita il numero di ripetizioni di tentativi che l’SDK effettua utilizzando un algoritmo token bucket. A seconda della modalità di ripetizione dei tentativi selezionata, le eccezioni di limitazione (della larghezza di banda della rete) possono o meno sottrarre token dal `TokenBucket`.

Quando un client rileva un errore per cui è possibile ripetere il tentativo, ad esempio un’eccezione di limitazione (della larghezza di banda della rete) o un errore temporaneo del server, l’SDK ritenta automaticamente la richiesta. È possibile controllare quante volte e con che velocità avviene la ripetizione dei tentativi.

Quando si configura un client, è possibile fornire un client `RetryPolicy` che supporti i seguenti parametri:
+ `numRetries`: il numero massimo di ripetizioni dei tentativi da applicare prima che una richiesta venga considerata non riuscita. Il valore predefinito è 8 indipendentemente dalla modalità di ripetizione dei tentativi utilizzata.
**avvertimento**  
Assicurati di modificare questo valore predefinito dopo debita considerazione.
+ `backoffStrategy`: la [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/BackoffStrategy.html) da applicare alla ripetizione dei tentativi ([https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/FullJitterBackoffStrategy.html) è la strategia predefinita). Questa strategia esegue un ritardo esponenziale tra ripetizioni di tentativi aggiuntive in base al numero di ripetizioni di tentativi correnti, un ritardo di base e un tempo massimo di backoff. Quindi aggiunge il jitter per avere della casualità. Il ritardo di base utilizzato nel ritardo esponenziale è di 25 ms indipendentemente dalla modalità di ripetizione dei tentativi.
+ `retryCondition`: [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryCondition.html) determina se ripetere i tentativi o meno su una richiesta. Per impostazione predefinita, ripete i tentativi con un set specifico di codici di stato HTTP ed eccezioni per cui ritiene che possano essere effettuate ripetizioni di tentativi. Per la maggior parte delle situazioni, la configurazione predefinita dovrebbe essere sufficiente.

Il codice seguente fornisce una policy di ripetizione dei tentativi alternativa. Specifica un totale di cinque ripetizioni di tentativo (sei richieste totali). La prima ripetizione di tentativo deve avvenire dopo un ritardo di circa 100 ms e ogni ripetizione di tentativo aggiuntiva raddoppia tale tempo in modo esponenziale, fino a un ritardo massimo di un secondo.

```
DynamoDbClient client = DynamoDbClient.builder()
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .retryPolicy(RetryPolicy.builder()
            .backoffStrategy(FullJitterBackoffStrategy.builder()
                .baseDelay(Duration.ofMillis(100))
                .maxBackoffTime(Duration.ofSeconds(1))
                .build())
            .numRetries(5)
            .build())
        .build())
    .build();
```

### DefaultsMode
<a name="DefaultsMode"></a>

Le proprietà di timeout che `ClientOverrideConfiguration` e `RetryMode` non gestiscono sono in genere configurate implicitamente specificando una `DefaultsMode`.

La AWS SDK for Java 2.x (versione 2.17.102 o successiva) ha introdotto il supporto per. `DefaultsMode` Questa funzionalità fornisce un set di valori predefiniti per le impostazioni configurabili più comuni, come le impostazioni di comunicazione HTTP, il comportamento della ripetizione dei tentativi, le impostazioni Regionali degli endpoint del servizio e potenzialmente qualsiasi configurazione relativa all’SDK. Quando si utilizza questa funzionalità, è possibile ottenere nuove impostazioni di configurazione predefinite personalizzate per scenari di utilizzo comuni.

Le modalità predefinite sono standardizzate in tutti i. AWS SDKs L’SDK per Java 2.x supporta le seguenti modalità predefinite:
+ `legacy`: fornisce impostazioni predefinite che variano in base all’SDK AWS e che esistevano prima della creazione di `DefaultsMode`.
+ `standard`: fornisce impostazioni predefinite non ottimizzate per la maggior parte degli scenari.
+ `in-region`— Si basa sulla modalità standard e include impostazioni personalizzate per le applicazioni che effettuano chiamate Servizi AWS dall'interno della stessa. Regione AWS
+ `cross-region`: si basa sulla modalità standard e include impostazioni con timeout elevati per le applicazioni che chiamano Servizi AWS in una Regione diversa.
+ `mobile`: si basa sulla modalità standard e include impostazioni con timeout elevati personalizzate per applicazioni mobili con latenze più elevate.
+ `auto`: si basa sulla modalità standard e include funzionalità sperimentali. L’SDK tenta di individuare l’ambiente di runtime per determinare automaticamente le impostazioni appropriate. Il rilevamento automatico è basato sull’euristica e non garantisce una precisione del 100%. Se non è possibile determinare l’ambiente di runtime, viene utilizzata la modalità standard. Il rilevamento automatico potrebbe eseguire query sui [metadati e i dati utente dell’istanza](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html), il che potrebbe introdurre latenza. Se la latenza di avvio è fondamentale per l’applicazione, si consiglia invece di scegliere una `DefaultsMode` esplicita.

È possibile configurare la modalità predefinita nei seguenti modi:
+ Direttamente su un client, tramite `AwsClientBuilder.Builder#defaultsMode(DefaultsMode)`.
+ Su un profilo di configurazione, tramite la proprietà del file di profilo `defaults_mode`.
+ A livello globale, tramite la proprietà di sistema `aws.defaultsMode`.
+ A livello globale, tramite la variabile di ambiente `AWS_DEFAULTS_MODE`.

**Nota**  
Per qualsiasi modalità diversa da `legacy`, i valori predefiniti forniti potrebbero cambiare man mano che le best practice si evolvono. Pertanto, in caso di utilizzo di una modalità diversa da `legacy`, si consiglia di eseguire dei test all’aggiornamento dell’SDK.

Le [impostazioni predefinite di Smart](https://docs.aws.amazon.com/sdkref/latest/guide/feature-smart-config-defaults.html) nella *AWS SDKs and Tools Reference Guide* forniscono un elenco delle proprietà di configurazione e dei relativi valori predefiniti nelle diverse modalità predefinite.

Scegliete il valore della modalità predefinita in base alle caratteristiche dell'applicazione e al tipo con Servizio AWS cui l'applicazione interagisce.

Questi valori sono configurati tenendo conto di un'ampia gamma di Servizi AWS opzioni. Per un’implementazione tipica di DynamoDB in cui sia le tabelle che l’applicazione DynamoDB sono implementate in un’unica Regione, la modalità predefinita `in-region` è la più rilevante tra le modalità predefinite `standard`.

**Example Configurazione del client SDK di DynamoDB ottimizzata per chiamate a bassa latenza**  
L’esempio seguente regola i timeout su valori inferiori per una chiamata DynamoDB con bassa latenza prevista.  

```
DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.builder()
    .defaultsMode(DefaultsMode.IN_REGION)
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder())
    .overrideConfiguration(ClientOverrideConfiguration.builder()
        .apiCallTimeout(Duration.ofSeconds(3))
        .apiCallAttemptTimeout(Duration.ofMillis(500))
        .build())
    .build();
```
L’implementazione individuale del client HTTP può fornire un controllo ancora più granulare sul timeout e sul comportamento di utilizzo della connessione. Ad esempio, per il client AWS basato su CRT, è possibile abilitare`ConnectionHealthConfiguration`, che consente al client di monitorare attivamente lo stato delle connessioni utilizzate. *Per ulteriori informazioni, consulta [Configurazione avanzata dei client HTTP AWS basati su CRT](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/http-configuration-crt.html#configuring-the-crt-based-http-client) nella Guida per gli sviluppatori.AWS SDK for Java 2.x *

### Configurazione Keep-Alive
<a name="KeepAliveConfig"></a>

L’abilitazione del keep-alive può ridurre le latenze riutilizzando le connessioni. Esistono due diversi tipi di keep-alive: HTTP Keep-Alive e TCP Keep-Alive.
+ HTTP Keep-Alive tenta di mantenere la connessione HTTPS tra il client e il server in modo che le richieste successive possano riutilizzare tale connessione. In questo modo si evita la pesante autenticazione HTTPS nelle richieste successive. HTTP Keep-Alive è abilitato per impostazione predefinita su tutti i client.
+ TCP Keep-Alive richiede che il sistema operativo sottostante invii piccoli pacchetti tramite la connessione del socket per fornire la garanzia aggiuntiva che il socket sia mantenuto attivo e per rilevare immediatamente eventuali interruzioni. Ciò garantisce che una richiesta successiva non perda tempo a cercare di utilizzare un socket interrotto. Per impostazione predefinita, TCP Keep-Alive è disabilitato su tutti i client. Gli esempi di codice seguenti mostrano come abilitarlo su ogni client HTTP. Se abilitato per tutti i client HTTP non basati su CRT, l’effettivo meccanismo di Keep-Alive dipende dal sistema operativo. Pertanto, è necessario configurare valori TCP Keep-Alive aggiuntivi, come il timeout e il numero di pacchetti, tramite il sistema operativo. È possibile farlo usando `sysctl` su Linux o macOS o i valori di registro su Windows.

**Example per abilitare TCP Keep-Alive su un client HTTP basato su Apache**  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(ApacheHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**Client HTTP basato su `URLConnection`**  
Qualsiasi client sincrono che utilizza il client HTTP basato su `URLConnection` [https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html](https://docs.oracle.com/javase/8/docs/api/java/net/HttpURLConnection.html) non dispone di un [meccanismo](https://docs.oracle.com/javase/8/docs/api/java/net/doc-files/net-properties.html) per abilitare il keep-alive.

**Example per abilitare TCP Keep-Alive su un client HTTP basato su Netty**  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(NettyNioAsyncHttpClient.builder().tcpKeepAlive(true))
    .build();
```

**Example per abilitare TCP Keep-Alive su un client HTTP basato su CRT AWS**  
Con il client HTTP AWS basato su CRT, puoi abilitare TCP keep-alive e controllarne la durata.  

```
DynamoDbClient client = DynamoDbClient.builder()
    .httpClientBuilder(AwsCrtHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```
Quando si utilizza il client DynamoDB asincrono, è possibile abilitare TCP Keep-Alive come illustrato nel codice seguente.  

```
DynamoDbAsyncClient client = DynamoDbAsyncClient.builder()
    .httpClientBuilder(AwsCrtAsyncHttpClient.builder()
    .tcpKeepAliveConfiguration(TcpKeepAliveConfiguration.builder()
        .keepAliveInterval(Duration.ofSeconds(50))
        .keepAliveTimeout(Duration.ofSeconds(5))
        .build()))
    .build();
```

## Gestione degli errori
<a name="JavaErrorHandling"></a>

Per quanto riguarda la gestione delle eccezioni, AWS SDK for Java 2.x utilizza eccezioni di runtime (non selezionate).

L’eccezione di base, che copre tutte le eccezioni dell’SDK, è [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html), che si estende da `RuntimeException` non controllata di Java. Se si intercetta questa eccezione, sarà possibile intercettare tutte le eccezioni generate dall’SDK.

`SdkServiceException` ha una sottoclasse denominata [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html). Questa sottoclasse indica qualsiasi problema di comunicazione con Servizio AWS. Ha una sottoclasse denominata [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html), che indica un problema nella comunicazione con DynamoDB. Se la si intercetta, sarà possibile intercettare tutte le eccezioni relative a DynamoDB, ma nessun’altra eccezione dell’SDK.

Sono disponibili [tipi di eccezioni](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html) più specifici in `DynamoDbException`. Alcuni di questi tipi di eccezioni si applicano a operazioni sul piano di controllo (control-plane) come [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TableAlreadyExistsException.html). Altri si applicano alle operazioni sul piano dati. Di seguito è riportato un esempio di eccezione comune relativa al piano dati:
+ [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ConditionalCheckFailedException.html): si è specificata una condizione nella richiesta che ha restituito il valore false. Ad esempio, è possibile che si sia provato un aggiornamento condizionale su un elemento, ma il valore effettivo dell’attributo non corrispondesse al valore previsto nella condizione. Per una richiesta che non va a buon fine in questo modo non vengono effettuate ripetizioni di tentativi.

In altre situazioni non viene definita un’eccezione specifica. Ad esempio, quando le richieste vengono sottoposte a limitazione (della larghezza di banda della rete), potrebbe essere limitata la `ProvisionedThroughputExceededException` specifica, mentre in altri casi potrebbe essere limitata la `DynamoDbException` più generica. In entrambi i casi, è possibile determinare se la limitazione (della larghezza di banda della rete) ha causato l’eccezione controllando se `isThrottlingException()` restituisce `true`.

A seconda delle esigenze dell’applicazione, è possibile intercettare tutte le istanze `AwsServiceException` o `DynamoDbException`. Tuttavia, spesso è necessario un comportamento diverso in situazioni diverse. La logica utilizzata per gestire un errore nel controllo delle condizioni è diversa da quella per gestire la limitazione (della larghezza di banda della rete). Definisci quali percorsi eccezionali desideri gestire e assicurati di testare i percorsi alternativi. Questo aiuta ad assicurarsi di poter gestire tutti gli scenari pertinenti.

Per un elenco di errori comuni che si possono riscontrare, consulta [Gestione degli errori con DynamoDB](Programming.Errors.md). Consulta anche [Common Errors](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/CommonErrors.html) in *Amazon DynamoDB API Reference*. Il riferimento fornisce anche gli errori esatti possibili per ogni operazione API, ad esempio per l’operazione [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html). Per informazioni sulla gestione delle eccezioni, consulta [Exception handling for the AWS SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/handling-exceptions.html) nella *AWS SDK for Java 2.x Developer Guide*.

## AWS ID della richiesta
<a name="JavaRequestID"></a>

Ogni richiesta include un ID di richiesta: può essere utile recuperarlo se si sta lavorando con il Supporto AWS per diagnosticare un problema. Ogni eccezione derivata da `SdkServiceException` ha un metodo [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html#requestId()) disponibile per recuperare l’ID della richiesta.

## Registrazione dei log
<a name="JavaLogging"></a>

L’utilizzo della registrazione di log fornita dall’SDK può essere utile sia per intercettare messaggi importanti dalle librerie client sia per scopi di debug più approfonditi. I logger sono gerarchici e l’SDK utilizza `software.amazon.awssdk` come logger root. È possibile configurare il livello con uno dei seguenti: `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `ALL` o `OFF`. Il livello configurato si applica a quel logger e verso il basso nella gerarchia dei logger.

Per la sua registrazione, AWS SDK for Java 2.x utilizza Simple Logging Façade for Java (J). SLF4 Questa funge da livello di astrazione rispetto agli altri logger e può essere usata per collegare il logger preferito. [Per istruzioni su come collegare i logger, consultate il manuale utente J. SLF4](https://www.slf4j.org/manual.html)

Ogni logger ha un comportamento particolare. Per impostazione predefinita, il logger Log4j 2.x crea un `ConsoleAppender`, che aggiunge gli eventi del log a `System.out` e i valori predefiniti al livello del log `ERROR`.

Il SimpleLogger logger incluso in SLF4 J emette per impostazione predefinita su `System.err` e imposta di default il livello di log. `INFO`

Si consiglia di impostare il livello su `WARN` per `software.amazon.awssdk` affinché qualsiasi implementazione di produzione intercetti eventuali messaggi importanti dalle librerie client dell’SDK limitando al contempo la quantità di output.

[Se SLF4 J non riesce a trovare un logger supportato nel percorso della classe (nessun binding SLF4 J), per impostazione predefinita è un'implementazione senza operazioni.](https://www.slf4j.org/codes.html#noProviders) Questa implementazione comporta la registrazione di messaggi che `System.err` spiegano che non sono riuscito a trovare un' SLF4implementazione del logger nel classpath. Per evitare questa situazione, è necessario aggiungere un’implementazione del logger. Per fare ciò, è possibile aggiungere una dipendenza in Apache Maven `pom.xml` verso gli artefatti, come `org.slf4j.slf4j-simple` o `org.apache.logging.log4j.log4j-slf4j2-imp`.

Per informazioni su come configurare la registrazione di log nell’SDK, compresa l’aggiunta di dipendenze di registrazione di log alla configurazione dell’applicazione, consulta [Logging with the SDK for Java 2.x](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/logging-slf4j.html) in the *AWS SDK per Java Developer Guide*.

La seguente configurazione nel file `Log4j2.xml` mostra come regolare il comportamento di registrazione di log se si utilizza il logger Apache Log4j 2. Questa configurazione imposta il livello del logger root su `WARN`. Tutti i logger della gerarchia ereditano questo livello di log, incluso il logger `software.amazon.awssdk`.

Per impostazione predefinita, l’output viene inviato a `System.out`. Nell’esempio seguente si sostituisce comunque l’appender di output predefinito Log4j per applicare un Log4j personalizzato `PatternLayout`.

**Esempio di un file di configurazione `Log4j2.xml`**  
La seguente configurazione registra log di messaggi sulla console ai livelli `ERROR` e `WARN` per tutte le gerarchie di logger.

```
<Configuration status="WARN">
  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
    </Console>
  </Appenders>

  <Loggers>
    <Root level="WARN">
      <AppenderRef ref="ConsoleAppender"/>
    </Root>
  </Loggers>
</Configuration>
```

### AWS richiedere la registrazione degli ID
<a name="JavaReqIDLogging"></a>

Quando qualcosa va storto, puoi trovare la richiesta IDs tra le eccezioni. Tuttavia, se desideri la richiesta IDs per le richieste che non generano eccezioni, puoi utilizzare la registrazione.

Il `software.amazon.awssdk.request` logger emette la richiesta IDs a livello. `DEBUG` L’esempio seguente estende il precedente [configuration example](#Log4j2ConfigEg) per mantenere il livello del logger root al livello `ERROR`, del `software.amazon.awssdk` al livello `WARN` e del `software.amazon.awssdk.request` al livello `DEBUG`. L'impostazione di questi livelli aiuta a catturare la richiesta IDs e altri dettagli relativi alla richiesta, come l'endpoint e il codice di stato.

```
<Configuration status="WARN">
  <Appenders>
    <Console name="ConsoleAppender" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{YYYY-MM-dd HH:mm:ss} [%t] %-5p %c:%L - %m%n" />
    </Console>
  </Appenders>

  <Loggers>
    <Root level="ERROR">
      <AppenderRef ref="ConsoleAppender"/>
    </Root>
    <Logger name="software.amazon.awssdk" level="WARN" />
    <Logger name="software.amazon.awssdk.request" level="DEBUG" />
  </Loggers>
</Configuration>
```

Di seguito è riportato un esempio di output del log:

```
2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Sending Request: DefaultSdkHttpFullRequest(httpMethod=POST, protocol=https, host=dynamodb.us-east-1.amazonaws.com, encodedPath=/, headers=[amz-sdk-invocation-id, Content-Length, Content-Type, User-Agent, X-Amz-Target], queryParameters=[])
 2022-09-23 16:02:08 [main] DEBUG software.amazon.awssdk.request:85 - Received successful response: 200, Request ID: QS9DUMME2NHEDH8TGT9N5V53OJVV4KQNSO5AEMVJF66Q9ASUAAJG, Extended Request ID: not available
```

## Paginazione
<a name="JavaPagination"></a>

Alcune richieste, come [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html) e [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html), limitano la dimensione dei dati restituiti in una singola richiesta e richiedono l’esecuzione di richieste ripetute per richiamare le pagine successive.

È possibile controllare il numero massimo di elementi da leggere per ogni pagina con il parametro `Limit`. Ad esempio, è possibile utilizzare il parametro `Limit` per recuperare solo gli ultimi 10 elementi. Questo limite specifica il numero di elementi da leggere dalla tabella prima di applicare qualsiasi filtro. Se si desiderano esattamente 10 elementi dopo il filtraggio, non c’è modo di specificarlo. È possibile controllare solo il conteggio prefiltrato e controllare lato client quando sono stati effettivamente recuperati 10 elementi. Indipendentemente dal limite, le risposte hanno sempre una dimensione massima di 1 MB.

Nella risposta dell’API potrebbe essere inclusa una `LastEvaluatedKey`. Ciò indica che la risposta è terminata perché ha raggiunto un limite di conteggio o di dimensione. Questa chiave è l’ultima chiave valutata per quella risposta. Interagendo direttamente con l’API, è possibile recuperare questa `LastEvaluatedKey` e passarla a una chiamata successiva come `ExclusiveStartKey` in modo da leggere il blocco successivo da quel punto di partenza. Se non viene restituita alcuna `LastEvaluatedKey`, significa che non ci sono più elementi che corrispondono alla chiamata API `Query` o `Scan`.

L’esempio seguente utilizza l’interfaccia di basso livello per limitare gli elementi a 100 in base al parametro `keyConditionExpression`.

```
QueryRequest.Builder queryRequestBuilder = QueryRequest.builder()
        .expressionAttributeValues(Map.of(
                ":pk_val", AttributeValue.fromS("123"),
                ":sk_val", AttributeValue.fromN("1000")))
        .keyConditionExpression("pk = :pk_val AND sk > :sk_val")
        .limit(100)
        .tableName(TABLE_NAME);

while (true) {
    QueryResponse queryResponse = DYNAMODB_CLIENT.query(queryRequestBuilder.build());

    queryResponse.items().forEach(item -> {
        LOGGER.info("item PK: [" + item.get("pk") + "] and SK: [" + item.get("sk") + "]");
    });

    if (!queryResponse.hasLastEvaluatedKey()) {
        break;
    }
    queryRequestBuilder.exclusiveStartKey(queryResponse.lastEvaluatedKey());
}
```

 AWS SDK for Java 2.x Possono semplificare questa interazione con DynamoDB fornendo metodi di impaginazione automatica che effettuano più chiamate di servizio per ottenere automaticamente le pagine successive di risultati. Questo semplifica il codice, ma toglie un certo controllo sull’utilizzo delle risorse che si avrebbe con la lettura manuale delle pagine.

Utilizzando i metodi `Iterable` disponibili nel client DynamoDB, come [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#queryPaginator(software.amazon.awssdk.services.dynamodb.model.QueryRequest)) e [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html#scanPaginator(software.amazon.awssdk.services.dynamodb.model.ScanRequest)), l’SDK si occupa dell’impaginazione. Il tipo restituito da questi metodi è un iterabile personalizzato che è possibile utilizzare per iterare tutte le pagine. L’SDK si occupa di gestire internamente le chiamate del servizio. Utilizzando l’API per i flussi Java, è possibile gestire il risultato di `QueryPaginator` come mostrato nell’esempio seguente.

```
QueryPublisher queryPublisher =
    DYNAMODB_CLIENT.queryPaginator(QueryRequest.builder()
        .expressionAttributeValues(Map.of(
            ":pk_val", AttributeValue.fromS("123"),
            ":sk_val", AttributeValue.fromN("1000")))
        .keyConditionExpression("pk = :pk_val AND sk > :sk_val")
        .limit(100)
        .tableName("YourTableName")
        .build());

queryPublisher.items().subscribe(item ->
    System.out.println(item.get("itemData"))).join();
```

## Annotazioni sulle classi di dati
<a name="JavaDataClassAnnotation"></a>

L’SDK per Java fornisce diverse annotazioni che è possibile inserire negli attributi della classe di dati. Queste annotazioni influenzano il modo in cui l’SDK interagisce con gli attributi. Aggiungendo un’annotazione, è possibile fare in modo che un attributo si comporti come un contatore atomico implicito, mantenga un valore di timestamp generato automaticamente o tenga traccia del numero di versione di un elemento. Per ulteriori informazioni, consulta [Data class annotations](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html).