

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Mit dem AWS SDK for Java 2.x
<a name="using"></a>

Dieses Kapitel zeigt Ihnen, wie Sie den AWS SDK for Java 2.x effektiv nutzen können. Erfahren Sie, wie Sie Service-Clients erstellen, Anfragen stellen, Antworten bearbeiten und Fehler verwalten. Das Kapitel behandelt synchrone und asynchrone Programmierung, paginierte Ergebnisse, Wartezeiten für die Ressourcenüberwachung und Leistungsoptimierung. 

Außerdem finden Sie bewährte Methoden für die Wiederverwendung von Clients, Anleitungen zur Fehlerbehebung, Lambda-Startoptimierung, HTTP/2-Unterstützung und DNS-Konfiguration.

**Contents**
+ [AWS-Service Anfragen stellen mit dem AWS SDK for Java 2.x](work-witih-clients.md)
  + [Verwenden von Service-Clients zum Stellen von Anfragen](work-witih-clients.md#using-service-client)
    + [Erstellen Sie einen Service-Client](work-witih-clients.md#work-with-clients-create)
    + [Standard-Client-Konfiguration](work-witih-clients.md#using-default-client)
    + [Service-Clients konfigurieren](work-witih-clients.md#using-configure-service-clients)
    + [Schließen Sie den Service-Client](work-witih-clients.md#using-closing-client)
  + [Anfragen stellen](work-witih-clients.md#using-making-requests)
    + [Verwenden Sie Anfragen, um die Client-Konfiguration zu überschreiben](work-witih-clients.md#using-override-client-config-request)
  + [Umgang mit Antworten](work-witih-clients.md#using-handling-responses)
+ [Asynchrone Programmierung mit dem AWS SDK for Java 2.x](asynchronous.md)
  + [Verwenden Sie einen asynchronen Client APIs](asynchronous.md#basics-async-non-streaming)
  + [Behandeln Sie das Streaming mit asynchronen Methoden](asynchronous.md#basics-async-streaming)
  + [Konfigurieren Sie erweiterte asynchrone Optionen](asynchronous.md#advanced-operations)
+ [Bewährte Methoden für die Verwendung des AWS SDK for Java 2.x](best-practices.md)
  + [Vermeiden Sie hängende Anfragen, indem Sie API-Timeouts konfigurieren](best-practices.md#bestpractice5)
  + [Verbessern Sie die Leistung, indem Sie Service-Clients wiederverwenden](best-practices.md#bestpractice1)
  + [Vermeiden Sie Ressourcenlecks, indem Sie ungenutzte Service-Clients schließen](best-practices.md#bestpractice-close-client)
  + [Vermeiden Sie die Erschöpfung des Verbindungspools, indem Sie Eingabestreams schließen](best-practices.md#bestpractice2)
  + [Optimieren Sie die HTTP-Leistung für die Arbeitslast Ihrer Anwendung](best-practices.md#bestpractice3)
  + [Verbessern Sie die SSL-Leistung mit OpenSSL für asynchrone Clients](best-practices.md#bestpractice4)
  + [Überwachen Sie die Anwendungsleistung mit SDK-Metriken](best-practices.md#bestpractice6)
+ [Behandlung von Fehlern in der AWS SDK for Java 2.x](handling-exceptions.md)
  + [Warum ungeprüfte Ausnahmen?](handling-exceptions.md#why-unchecked-exceptions)
  + [AwsServiceException (und Unterklassen)](handling-exceptions.md#sdkserviceexception-and-subclasses)
  + [SdkClientException](handling-exceptions.md#sdkclientexception)
  + [Ausnahmen und Wiederholungsverhalten](handling-exceptions.md#retried-exceptions)
+ [Verwenden von paginierten Ergebnissen in der 2.x AWS SDK für Java](pagination.md)
  + [Synchrone Paginierung](pagination.md#synchronous-pagination)
    + [Iterieren Sie über Seiten hinweg](pagination.md#iterate-pages)
    + [Iteriere über Objekte](pagination.md#iterate-objects)
      + [Verwenden Sie einen Stream](pagination.md#use-a-stream)
      + [Verwenden Sie eine For-Each-Schleife](pagination.md#for-loop)
    + [Manuelle Paginierung](pagination.md#manual-pagination)
  + [Asynchrone Paginierung](pagination.md#asynchronous-pagination)
    + [Iterieren Sie über Seiten mit Tabellennamen](pagination.md#iterate-pages-async)
      + [Benutze ein `Subscriber`](pagination.md#use-a-subscriber)
      + [Benutze ein `Consumer`](pagination.md#id1pagination)
    + [Iteriere über Tabellennamen](pagination.md#iterate-objects-async)
      + [Verwenden Sie ein `Subscriber`](pagination.md#id2)
      + [Benutze ein `Consumer`](pagination.md#for-loop-async)
    + [Verwenden Sie die Bibliothek eines Drittanbieters](pagination.md#use-third-party-library)
+ [Mit Kellnern in der AWS SDK for Java 2.x](waiters.md)
  + [Voraussetzungen](waiters.md#prerequisiteswaiters)
  + [Kellner benutzen](waiters.md#id1waiters)
    + [Synchrone Programmierung](waiters.md#synchronous-programming)
    + [Asynchrone Programmierung](waiters.md#asynchronous-programming)
  + [Kellner konfigurieren](waiters.md#configuring-waiters)
    + [Konfigurieren Sie einen Kellner](waiters.md#configure-a-waiter)
    + [Überschreiben Sie die Konfiguration für eine bestimmte Anfrage](waiters.md#override-configuration-for-a-specific-request)
  + [Codebeispiele](waiters.md#code-examples)
+ [Problembehebung FAQs](troubleshooting.md)
  + [Wie behebe ich den Fehler "`java.net.SocketException`: Verbindung zurückgesetzt“ oder „Server konnte die Antwort nicht abschließen“?](troubleshooting.md#faq-socketexception)
  + [Wie behebe ich das „Verbindungs-Timeout“?](troubleshooting.md#faq-connection-timeout)
  + [Wie behebe ich "`java.net.SocketTimeoutException`: Timeout beim Lesen“?](troubleshooting.md#faq-socket-timeout)
  + [Wie behebe ich den Fehler „HTTP-Anfrage kann nicht ausgeführt werden: Timeout beim Warten auf Verbindung vom Pool“?](troubleshooting.md#faq-pool-timeout)
  + [Wie behebe ich ein`NoClassDefFoundError`, `NoSuchMethodError` oder`NoSuchFieldError`?](troubleshooting.md#faq-classpath-errors)
  + [Wie behebe ich den Fehler "`SignatureDoesNotMatch`" oder den Fehler „Die von uns berechnete Anforderungssignatur stimmt nicht mit der von Ihnen angegebenen Signatur überein“?](troubleshooting.md#faq-signature-does-not-match-error)
  + [Wie behebe ich den Fehler "`java.lang.IllegalStateException`: Der Verbindungspool wurde heruntergefahren“?](troubleshooting.md#faq-connection-pool-shutdown-exception)
  + [Wie behebe ich „Anmeldeinformationen können von keinem der Anbieter in der Kette geladen werden“? AwsCredentialsProviderChain](troubleshooting.md#faq-credentials-provider-chain)
    + [Häufige Ursachen und Lösungen](troubleshooting.md#faq-cred-provider-chain-common-causes-and-solutions)
      + [Überprüfen Sie die Konfiguration Ihrer Anmeldeinformationen](troubleshooting.md#faq-cred-provider-chain-check-config)
        + [Für Amazon EC2 EC2-Instances](troubleshooting.md#faq-cred-check-ec2)
        + [Für Container-Umgebungen](troubleshooting.md#faq-cred-check-container-env)
        + [Für die lokale Entwicklung](troubleshooting.md#faq-cred-check-local-dev)
        + [Für den Web-Identitätsverbund](troubleshooting.md#faq-cred-check-web-id-federation)
      + [Probleme mit der Netzwerk- oder Proxyverbindung](troubleshooting.md#faq-credentials-provider-chain-network-issues)
+ [Verkürzen Sie die SDK-Startzeit für AWS Lambda](lambda-optimize-starttime.md)
  + [Verwenden Sie einen AWS CRT-basierten HTTP-Client](lambda-optimize-starttime.md#lambda-quick-url)
  + [Entfernen Sie ungenutzte HTTP-Client-Abhängigkeiten](lambda-optimize-starttime.md#lambda-quick-remove-deps)
  + [Konfigurieren Sie Service-Clients für Shortcut-Suchvorgänge](lambda-optimize-starttime.md#lambda-quick-clients)
  + [Initialisieren Sie den SDK-Client außerhalb des Lambda-Funktionshandlers](lambda-optimize-starttime.md#lambda-quick-initialize)
  + [Minimiert die Dependency-](lambda-optimize-starttime.md#lambda-quick-di)
  + [Verwenden Sie ein Targeting vom Typ Maven Archetype AWS Lambda](lambda-optimize-starttime.md#lambda-quick-maven)
  + [Ziehen Sie Lambda SnapStart für Java in Betracht](lambda-optimize-starttime.md#lambda-quick-snapstart)
  + [Änderungen an Version 2.x, die sich auf die Startzeit auswirken](lambda-optimize-starttime.md#example-client-configuration)
  + [Weitere Ressourcen](lambda-optimize-starttime.md#lambda-quick-resources)
+ [Implementieren `ContentStreamProvider` Sie in der AWS SDK for Java 2.x](content-stream-provider.md)
  + [Verwendung von `mark()` und `reset()`](content-stream-provider.md#csp-impl-mark-reset)
  + [Verwenden Sie die Pufferung, falls `mark()` und nicht verfügbar `reset()` sind](content-stream-provider.md#csp-impl-unsupported-streams)
  + [Erstelle neue Streams](content-stream-provider.md#csp-impl-new-stream)
+ [Legen Sie die JVM-TTL für DNS-Namenssuchen fest](jvm-ttl-dns.md)
  + [Wie legt man die JVM-TTL fest](jvm-ttl-dns.md#how-to-set-the-jvm-ttl)
    + [Option 1: Stellen Sie sie programmgesteuert in Ihrer Anwendung ein](jvm-ttl-dns.md#set-ttl-programmatically)
    + [Option 2: Legen Sie es in der Datei java.security fest](jvm-ttl-dns.md#set-ttl-java-security-file)
    + [Option 3: Verwenden Sie das Fallback für JDK-Systemeigenschaften (Befehlszeile)](jvm-ttl-dns.md#set-ttl-system-property)
+ [Arbeiten Sie mit HTTP/2 in der AWS SDK für Java](http2.md)

# AWS-Service Anfragen stellen mit dem AWS SDK for Java 2.x
<a name="work-witih-clients"></a>

## Verwenden von Service-Clients zum Stellen von Anfragen
<a name="using-service-client"></a>

Nachdem Sie die Schritte unter [SDK einrichten](setup.md) abgeschlossen und verstanden haben, wie [Service-Clients konfiguriert](configuring-service-clients.md) werden, können Sie Anfragen an AWS Services wie Amazon S3, Amazon DynamoDB AWS Identity and Access Management, Amazon EC2 und mehr stellen.

### Erstellen Sie einen Service-Client
<a name="work-with-clients-create"></a>

Um eine Anfrage an zu stellen AWS-Service, müssen Sie zunächst einen Dienstclient für diesen Dienst instanziieren, indem Sie die statische Factory-Methode verwenden,. `builder()` Die `builder()` Methode gibt ein `builder` Objekt zurück, mit dem Sie den Dienstclient anpassen können. Die praktischen Setter-Methoden geben das `builder`-Objekt zurück. So können Sie die Methodenaufrufe in Reihe schalten, was nicht nur einfacher ist, sondern auch für besser lesbaren Code sorgt. Nachdem Sie die gewünschten Eigenschaften konfiguriert haben, rufen Sie die `build()` Methode auf, um den Client zu erstellen.

Als Beispiel instanziiert der folgende Codeausschnitt ein `Ec2Client` Objekt als Service-Client für Amazon EC2.

```
Region region = Region.US_WEST_2;
Ec2Client ec2Client = Ec2Client.builder()
        .region(region)
        .build();
```

**Anmerkung**  
Service-Clients im SDK sind threadsicher. Um eine optimale Leistung zu erzielen, behandeln Sie sie wie langlebige Objekte. Jeder Client verfügt über seine eigene Verbindungspool-Ressource, die freigegeben wird, wenn der Client von der Speicherbereinigung entfernt wird.  
Ein Service-Client-Objekt ist unveränderlich. Sie müssen also für jeden Service, an den Sie Anfragen stellen, einen neuen Client erstellen, oder wenn Sie eine andere Konfiguration für Anfragen an denselben Service verwenden möchten.  
Die Angabe von `Region` im Service Client Builder ist nicht für alle AWS Dienste erforderlich. Es hat sich jedoch bewährt, die Region für die API-Aufrufe festzulegen, die Sie in Ihren Anwendungen tätigen. Weitere Informationen finden Sie unter [AWS Regionsauswahl](region-selection.md).

### Standard-Client-Konfiguration
<a name="using-default-client"></a>

Die Client-Generatoren haben eine weitere Factory-Methode mit dem Namen `create()`. Diese Methode erstellt einen Service-Client mit der Standard-Konfiguration. Es verwendet die [Standardanbieterkette](credentials-chain.md) zum Laden von Anmeldeinformationen und die [AWS-Region Standardanbieterkette](region-selection.md#automatically-determine-the-aws-region-from-the-environment). Wenn die Anmeldeinformationen oder die Region nicht anhand der Umgebung ermittelt werden können, in der die Anwendung ausgeführt wird, schlägt der Aufruf von `create` fehl. Weitere Informationen darüber, wie das SDK die zu [verwendenden Anmeldeinformationen](credentials.md) und die [Region](region-selection.md) bestimmt, finden Sie unter Anmeldeinformationen verwenden und Region auswählen.

Der folgende Codeausschnitt instanziiert beispielsweise ein `DynamoDbClient` Objekt als Service-Client für Amazon DynamoDB:

```
DynamoDbClient dynamoDbClient = DynamoDbClient.create();
```

### Service-Clients konfigurieren
<a name="using-configure-service-clients"></a>

Einzelheiten zur Konfiguration von Service-Clients finden Sie unter [Client-Konfiguration extern](configuring-service-clients-ext.md) und[Client-Konfiguration im Code](configuring-service-clients-code.md).

### Schließen Sie den Service-Client
<a name="using-closing-client"></a>

Es hat sich bewährt, während der Lebensdauer einer Anwendung einen Service-Client für mehrere API-Dienstaufrufe zu verwenden. Wenn Sie jedoch einen Service-Client für eine einmalige Verwendung benötigen oder den Service-Client nicht mehr benötigen, schließen Sie ihn.

Rufen Sie die `close()` Methode auf, wenn der Service-Client nicht mehr benötigt wird, um Ressourcen freizugeben.

```
ec2Client.close();
```

Wenn Sie einen Service-Client für den einmaligen Gebrauch benötigen, können Sie den Service-Client als Ressource in einer `try` -with-resources-Anweisung instanziieren. Service-Clients implementieren die `[Autoclosable](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/AutoCloseable.html)` Schnittstelle, sodass das JDK die `close()` Methode am Ende der Anweisung automatisch aufruft.

Das folgende Beispiel zeigt, wie ein Service-Client für einen einmaligen Anruf verwendet wird. Die Datei`StsClient`, die anruft, AWS -Security-Token-Service wird geschlossen, nachdem sie die Konto-ID zurückgegeben hat.

```
import software.amazon.awssdk.services.sts.StsClient;

String getAccountID() {
    try (StsClient stsClient = StsClient.create()) {
       return stsClient.getCallerIdentity().account();
    }
}
```

## Anfragen stellen
<a name="using-making-requests"></a>

Verwenden Sie den Service-Client, um Anfragen an die entsprechenden Personen zu stellen AWS-Service.

Dieser Codeausschnitt zeigt beispielsweise, wie Sie ein `RunInstancesRequest` Objekt erstellen, um eine neue Amazon EC2 EC2-Instance zu erstellen:

```
// Create the request by using the fluid setter methods of the request builder.
RunInstancesRequest runInstancesRequest = RunInstancesRequest.builder()
        .imageId(amiId)
        .instanceType(InstanceType.T1_MICRO)
        .maxCount(1)
        .minCount(1)
        .build();

// Use the configured request with the service client.
RunInstancesResponse response = ec2Client.runInstances(runInstancesRequest);
```

Anstatt eine Anfrage zu erstellen und die Instance weiterzuleiten, bietet das SDK eine flüssige API, mit der Sie eine Anfrage erstellen können. Mit der Fluent-API können Sie Java-Lambda-Ausdrücke verwenden, um die Anfrage „online“ zu erstellen.

Das folgende Beispiel schreibt das vorherige Beispiel neu, indem es die Version der `runInstances` [Methode verwendet, die einen Builder verwendet, um](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#runInstances(java.util.function.Consumer)) die Anfrage zu erstellen.

```
// Create the request by using a lambda expression.
RunInstancesResponse response = ec2.runInstances(r -> r
                .imageId(amiId)
                .instanceType(InstanceType.T1_MICRO)
                .maxCount(1)
                .minCount(1));
```

### Verwenden Sie Anfragen, um die Client-Konfiguration zu überschreiben
<a name="using-override-client-config-request"></a>

Obwohl ein Service-Client unveränderlich ist, können Sie viele seiner Einstellungen auf Anforderungsebene überschreiben. Wenn Sie eine Anfrage erstellen, können Sie eine [AwsRequestOverrideConfiguration](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/AwsRequestOverrideConfiguration.html)Instanz bereitstellen, um die überschriebenen Einstellungen bereitzustellen. Einige der Methoden, mit denen Sie Client-Einstellungen überschreiben können, sind:
+ `apiCallAttemptTimeout`
+ `apiCallTimeout`
+ `credentialProvider`
+ `compressionConfiguration`
+ `putHeader`

Gehen Sie als Beispiel für das Überschreiben einer Client-Einstellung mit einer Anfrage davon aus, dass Sie über den folgenden S3-Client verfügen, der Standardeinstellungen verwendet.

```
S3Client s3Client = S3Client.create();
```

Sie möchten eine große Datei herunterladen und sicherstellen, dass die Anfrage nicht zu einem Timeout kommt, bevor der Download abgeschlossen ist. Um dies zu erreichen, erhöhen Sie die Timeout-Werte für nur eine einzelne `GetObject` Anfrage, wie im folgenden Code gezeigt.

------
#### [ Standard API ]

```
AwsRequestOverrideConfiguration overrideConfiguration = AwsRequestOverrideConfiguration.builder()
    .apiCallTimeout(Duration.ofSeconds(100L))
    .apiCallAttemptTimeout(Duration.ofSeconds(25L))
    .build();

GetObjectRequest request = GetObjectRequest.builder()
    .bucket("amzn-s3-demo-bucket")
    .key("demo-key")
    .overrideConfiguration(overrideConfiguration)
    .build();

s3Client.getObject(request, myPath);
```

------
#### [ Fluent API ]

```
s3Client.getObject(b -> b
        .bucket("amzn-s3-demo-bucket")
        .key("demo-key")
        .overrideConfiguration(c -> c
            .apiCallTimeout(Duration.ofSeconds(100L))
            .apiCallAttemptTimeout(Duration.ofSeconds(25L))),
    myPath);
```

------

## Umgang mit Antworten
<a name="using-handling-responses"></a>

Das SDK gibt für die meisten Dienstoperationen ein Antwortobjekt zurück. Ihr Code kann die Informationen im Antwortobjekt Ihren Anforderungen entsprechend verarbeiten.

Der folgende Codeausschnitt druckt beispielsweise die erste Instanz-ID aus, die zusammen mit dem [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesResponse.html)Objekt aus der vorherigen Anfrage zurückgegeben wurde.

```
RunInstancesResponse runInstancesResponse = ec2Client.runInstances(runInstancesRequest);
System.out.println(runInstancesResponse.instances().get(0).instanceId());
```

Nicht alle Operationen geben jedoch ein Antwortobjekt mit dienstspezifischen Daten zurück. In diesen Situationen können Sie den HTTP-Antwortstatus abfragen, um zu erfahren, ob der Vorgang erfolgreich war.

Der Code im folgenden Codeausschnitt überprüft beispielsweise die HTTP-Antwort, um festzustellen, ob der [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sesv2/SesV2Client.html#deleteContactList(software.amazon.awssdk.services.sesv2.model.DeleteContactListRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sesv2/SesV2Client.html#deleteContactList(software.amazon.awssdk.services.sesv2.model.DeleteContactListRequest))Betrieb von Amazon Simple Email Service erfolgreich war. 

```
SesV2Client sesv2Client = SesV2Client.create();

DeleteContactListRequest request = DeleteContactListRequest.builder()
    .contactListName("ExampleContactListName")
    .build();

DeleteContactListResponse response = sesv2Client.deleteContactList(request);
if (response.sdkHttpResponse().isSuccessful()) {
    System.out.println("Contact list deleted successfully");
} else {
    System.out.println("Failed to delete contact list. Status code: " + response.sdkHttpResponse().statusCode());
}
```

# Asynchrone Programmierung mit dem AWS SDK for Java 2.x
<a name="asynchronous"></a>

Es AWS SDK for Java 2.x bietet asynchrone Clients mit nicht blockierender I/O Unterstützung, die eine hohe Parallelität über einige Threads hinweg implementieren. Eine vollständige Blockierung ist jedoch nicht garantiert I/O . In einigen Fällen kann ein asynchroner Client blockierende Aufrufe ausführen, z. B. beim Abrufen von Anmeldeinformationen, beim Signieren von Anfragen mit [AWS Signature Version 4 (Sigv4)](https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-authenticating-requests.html) oder bei der Endpunkterkennung. 

Synchrone Methoden blockieren die Ausführung Ihres Threads, bis der Client eine Antwort vom Service erhält. Asynchrone Methoden kehren sofort zurück. So haben Sie die Gewissheit, dass die Kontrolle an den aufrufenden Thread zurückgegeben wird, ohne auf eine Antwort zu warten.

Da eine asynchrone Methode zurückmeldet, bevor eine Antwort verfügbar ist, benötigen Sie einen Weg, an die Antwort zu gelangen, sobald diese bereitsteht. Die Methoden für asynchrone Clients in 2.x der AWS SDK für Java *CompletableFuture Rückgabeobjekte*, mit denen Sie auf die Antwort zugreifen können, wenn sie bereit ist.

## Verwenden Sie einen asynchronen Client APIs
<a name="basics-async-non-streaming"></a>

*Die Signaturen asynchroner Clientmethoden sind dieselben wie ihre synchronen Gegenstücke, aber die asynchronen Methoden geben ein [CompletableFuture](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/concurrent/CompletableFuture.html)Objekt zurück, das die Ergebnisse der asynchronen Operation in der future enthält.* Wenn während der Ausführung der asynchronen Methode des SDK ein Fehler ausgelöst wird, wird der Fehler als ausgegeben. `CompletionException` 

Ein Ansatz, den Sie verwenden können, um das Ergebnis zu erhalten, besteht darin, eine `whenComplete()` Methode mit dem vom SDK `CompletableFuture` zurückgegebenen Methodenaufruf zu verketten. Die `whenComplete()` Methode empfängt das Ergebnis oder ein Throwable-Objekt des Typs, `CompletionException` je nachdem, wie der asynchrone Aufruf abgeschlossen wurde. Sie geben eine Aktion an, um die Ergebnisse `whenComplete()` zu verarbeiten oder zu überprüfen, bevor sie an den aufrufenden Code zurückgegeben werden.

Wenn Sie etwas anderes als das von der SDK-Methode zurückgegebene Objekt zurückgeben möchten, verwenden Sie stattdessen die `handle()` Methode. Die `handle()` Methode verwendet dieselben Parameter wie`whenComplete()`, aber Sie können das Ergebnis verarbeiten und ein Objekt zurückgeben.

Um zu warten, bis die asynchrone Kette abgeschlossen ist, und um die Ergebnisse der Fertigstellung abzurufen, können Sie die `join()` Methode aufrufen. Wenn das `Throwable` Objekt nicht in der Kette behandelt wurde, löst die `join()` Methode eine unkontrollierte Fehlermeldung aus, `CompletionException` die die ursprüngliche Ausnahme umschließt. Sie greifen auf die ursprüngliche Ausnahme mit zu. `CompletionException#getCause()` Sie können die `CompletableFuture#get()` Methode auch aufrufen, um die Abschlussergebnisse abzurufen. Die `get()` Methode kann jedoch geprüfte Ausnahmen auslösen.

Das folgende Beispiel zeigt zwei Varianten, wie Sie mit der `listTables()` Methode des asynchronen DynamoDB-Clients arbeiten können. Die Aktion, an die übergeben wurde, protokolliert `whenComplete()` lediglich eine erfolgreiche Antwort, wohingegen die `handle()` Version die Liste der Tabellennamen extrahiert und die Liste zurückgibt. In beiden Fällen wird, wenn in der asynchronen Kette ein Fehler generiert wird, der Fehler erneut ausgelöst, sodass der Client-Code die Möglichkeit hat, ihn zu behandeln.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;

import java.util.List;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

------
#### [ whenComplete() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            ListTablesResponse listTablesResponse = listTablesWhenComplete(dynamoDbAsyncClient).join();  // The join() method may throw a CompletionException.
            if (listTablesResponse.hasTableNames()){
                System.out.println("Table exist in this region: " + region.id());
            }
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<ListTablesResponse> listTablesWhenComplete(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .whenComplete((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {  // Consume the response.
                    System.out.println("The SDK's listTables method completed successfully.");
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
```

------
#### [ handle() variation ]

```
public class DynamoDbAsyncListTables {

    public static void main(String[] args) {
        Region region = Region.US_EAST_1;
        DynamoDbAsyncClient dynamoDbAsyncClient = DynamoDbAsyncClient.builder().region(region).build();
        try {
            List<String> tableNames = listTablesHandle(dynamoDbAsyncClient).join(); // The join() method may throw a CompletionException.
            tableNames.forEach(System.out::println);
        } catch (RuntimeException e) {
            // Handle as needed. Here we simply print out the class names.
            System.out.println(e.getClass()); // Prints 'class java.util.concurrent.CompletionException'.
            System.out.println(e.getCause().getClass()); // Prints 'class software.amazon.awssdk.services.dynamodb.model.DynamoDbException'.
        }
    }

    public static CompletableFuture<List<String>> listTablesHandle(DynamoDbAsyncClient client) {
        return client.listTables(ListTablesRequest.builder().build())
            .handle((listTablesResponse, throwable) -> {
                if (listTablesResponse != null) {
                    return listTablesResponse.tableNames(); // Return the list of table names.
                } else {
                    RuntimeException cause = (RuntimeException) throwable.getCause(); // If an error was thrown during the SDK's listTables method it is wrapped in a CompletionException.
                                                                                      // The SDK throws only RuntimeExceptions, so this is a safe cast.
                    System.out.println(cause.getMessage());  // Log error here, but rethrow so the calling code can handle as needed.
                    throw cause;
                }
            });
    }
}
```

------

## Behandeln Sie das Streaming mit asynchronen Methoden
<a name="basics-async-streaming"></a>

Bei asynchronen Methoden mit Streaming-Inhalten müssen Sie eine angeben, [AsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html)um den Inhalt inkrementell bereitzustellen, oder eine, um die Antwort [AsyncResponseTransformer](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncResponseTransformer.html)zu empfangen und zu verarbeiten.

Im folgenden Beispiel wird eine Datei asynchron hochgeladen, indem die Amazon S3 asynchrone Form des Vorgangs verwendet wird. `PutObject`

 **Importe** 

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncOps {

     public static void main(String[] args) {

         final String USAGE = "\n" +
                 "Usage:\n" +
                 "    S3AsyncOps <bucketName> <key> <path>\n\n" +
                 "Where:\n" +
                 "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                 "    key - the name of the object (for example, book.pdf). \n" +
                 "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
             System.exit(1);
        }

        String bucketName = args[0];
        String key = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        PutObjectRequest objectRequest = PutObjectRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        // Put the object into the bucket
        CompletableFuture<PutObjectResponse> future = client.putObject(objectRequest,
                AsyncRequestBody.fromFile(Paths.get(path))
        );
        future.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object uploaded. Details: " + resp);
                } else {
                    // Handle error
                    err.printStackTrace();
                }
            } finally {
                // Only close the client when you are completely done with it
                client.close();
            }
        });

        future.join();
    }
}
```

Im folgenden Beispiel wird mithilfe der asynchronen Form des Vorgangs eine Datei Amazon S3 von abgerufen. `GetObject`

 **Importe** 

```
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import java.nio.file.Paths;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

```
/**
 * To run this AWS code example, ensure that you have setup your development environment, including your AWS credentials.
 *
 * For information, see this documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */

public class S3AsyncStreamOps {

    public static void main(String[] args) {

        final String USAGE = "\n" +
                "Usage:\n" +
                "    S3AsyncStreamOps <bucketName> <objectKey> <path>\n\n" +
                "Where:\n" +
                "    bucketName - the name of the Amazon S3 bucket (for example, bucket1). \n\n" +
                "    objectKey - the name of the object (for example, book.pdf). \n" +
                "    path - the local path to the file (for example, C:/AWS/book.pdf). \n" ;

        if (args.length != 3) {
            System.out.println(USAGE);
            System.exit(1);
         }

        String bucketName = args[0];
        String objectKey = args[1];
        String path = args[2];

        Region region = Region.US_WEST_2;
        S3AsyncClient client = S3AsyncClient.builder()
                .region(region)
                .build();

        GetObjectRequest objectRequest = GetObjectRequest.builder()
                .bucket(bucketName)
                .key(objectKey)
                .build();

        CompletableFuture<GetObjectResponse> futureGet = client.getObject(objectRequest,
                AsyncResponseTransformer.toFile(Paths.get(path)));

        futureGet.whenComplete((resp, err) -> {
            try {
                if (resp != null) {
                    System.out.println("Object downloaded. Details: "+resp);
                } else {
                    err.printStackTrace();
                }
            } finally {
               // Only close the client when you are completely done with it
                client.close();
            }
        });
        futureGet.join();
    }
}
```

## Konfigurieren Sie erweiterte asynchrone Optionen
<a name="advanced-operations"></a>

 AWS SDK für Java 2.x verwendet [Netty](https://netty.io), ein asynchrones, ereignisgesteuertes Netzwerkanwendungs-Framework, um Threads zu verarbeiten. I/O AWS SDK für Java 2.x erstellt ein `ExecutorService` Back-Netty, um die von der HTTP-Client-Anfrage an den Netty-Client zurückgegebenen Futures zu vervollständigen. Diese Abstraktion reduziert das Risiko, dass eine Anwendung den asynchronen Prozess unterbricht, wenn Entwickler Threads anhalten oder in den Ruhezustand versetzen. Standardmäßig erstellt jeder asynchrone Client einen Threadpool, der auf der Anzahl der Prozessoren basiert, und verwaltet die Aufgaben in einer Warteschlange innerhalb von. `ExecutorService`

Sie können eine bestimmte JDK-Implementierung angeben, `ExecutorService` wenn Sie Ihren asynchronen Client erstellen. Das folgende Snippet erstellt einen `ExecutorService` mit einer festen Anzahl von Threads.

 **Code** 

```
S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      Executors.newFixedThreadPool(10)
    )
  )
  .build();
```

Um die Leistung zu optimieren, können Sie Ihren eigenen Thread-Pool-Executor verwalten und ihn bei der Konfiguration Ihres Clients einbeziehen.

```
ThreadPoolExecutor executor = new ThreadPoolExecutor(50, 50,
    10, TimeUnit.SECONDS,
    new LinkedBlockingQueue<>(<custom_value>),
    new ThreadFactoryBuilder()
      .threadNamePrefix("sdk-async-response").build());

// Allow idle core threads to time out
executor.allowCoreThreadTimeOut(true);

S3AsyncClient clientThread = S3AsyncClient.builder()
  .asyncConfiguration(
    b -> b.advancedOption(SdkAdvancedAsyncClientOption
      .FUTURE_COMPLETION_EXECUTOR,
      executor
    )
  )
  .build();
```

# Bewährte Methoden für die Verwendung des AWS SDK for Java 2.x
<a name="best-practices"></a>

## Vermeiden Sie hängende Anfragen, indem Sie API-Timeouts konfigurieren
<a name="bestpractice5"></a>

Das SDK bietet [Standardwerte](https://github.com/aws/aws-sdk-java-v2/blob/a0c8a0af1fa572b16b5bd78f310594d642324156/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java#L134) für einige Timeout-Optionen, wie Verbindungs-Timeout und Socket-Timeout, jedoch nicht für Timeouts bei API-Aufrufen oder Timeouts für einzelne API-Aufrufversuche. Es empfiehlt sich, Timeouts sowohl für einzelne Versuche als auch für die gesamte Anfrage festzulegen. Auf diese Weise wird sichergestellt, dass Ihre Anwendung schnell und optimal fehlschlägt, wenn vorübergehende Probleme auftreten, die dazu führen können, dass Anforderungsversuche länger dauern können, oder bei schwerwiegenden Netzwerkproblemen.

Sie können Timeouts für alle Anfragen konfigurieren, die von einem Service-Client gestellt werden, indem Sie und verwenden`[ClientOverrideConfiguration\$1apiCallAttemptTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallAttemptTimeout())`. `[ClientOverrideConfiguration\$1apiCallTimeout](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/ClientOverrideConfiguration.html#apiCallTimeout())`

Das folgende Beispiel zeigt die Konfiguration eines Amazon S3 S3-Clients mit benutzerdefinierten Timeout-Werten.

```
S3Client.builder()
        .overrideConfiguration(
             b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
                   .apiCallAttemptTimeout(Duration.ofMillis(<custom value>)))
        .build();
```

**`apiCallAttemptTimeout`**  
Diese Einstellung legt die Zeitspanne für einen einzelnen HTTP-Versuch fest, nach deren Ablauf der API-Aufruf erneut versucht werden kann.

**`apiCallTimeout`**  
Der Wert für diese Eigenschaft konfiguriert die Zeitspanne für die gesamte Ausführung, einschließlich aller Wiederholungsversuche.

Als Alternative zur Einstellung dieser Timeout-Werte auf dem Service-Client können Sie [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallTimeout())und verwenden, um eine einzelne Anforderung `[RequestOverrideConfiguration\$1apiCallAttemptTimeout()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/RequestOverrideConfiguration.html#apiCallAttemptTimeout())` zu konfigurieren.

Im folgenden Beispiel wird eine einzelne `listBuckets` Anfrage mit benutzerdefinierten Timeout-Werten konfiguriert.

```
s3Client.listBuckets(lbr -> lbr.overrideConfiguration(
        b -> b.apiCallTimeout(Duration.ofSeconds(<custom value>))
               .apiCallAttemptTimeout(Duration.ofMillis(<custom value>))));
```

Wenn Sie diese Eigenschaften zusammen verwenden, legen Sie ein festes Limit für die Gesamtzeit fest, die für alle Versuche bei Wiederholungsversuchen aufgewendet wird. Sie legen außerdem fest, dass eine einzelne HTTP-Anfrage bei einer langsamen Anfrage schnell fehlschlägt.

## Verbessern Sie die Leistung, indem Sie Service-Clients wiederverwenden
<a name="bestpractice1"></a>

Jeder [Service-Client](work-witih-clients.md) unterhält seinen eigenen HTTP-Verbindungspool. Eine Verbindung, die bereits im Pool vorhanden ist, kann durch eine neue Anfrage wiederverwendet werden, um die Zeit für den Aufbau einer neuen Verbindung zu verkürzen. Wir empfehlen, eine einzelne Instanz des Clients gemeinsam zu nutzen, um den Mehraufwand zu vermeiden, der durch zu viele Verbindungspools entsteht, die nicht effektiv genutzt werden. Alle Service-Clients sind Thread-sicher.

Wenn Sie eine Client-Instanz nicht gemeinsam nutzen möchten, rufen Sie die Instanz `close()` auf, um die Ressourcen freizugeben, wenn der Client nicht benötigt wird.

## Vermeiden Sie Ressourcenlecks, indem Sie ungenutzte Service-Clients schließen
<a name="bestpractice-close-client"></a>

Schließen Sie einen [Service-Client](work-witih-clients.md), um Ressourcen wie Threads freizugeben, wenn sie nicht mehr benötigt werden. Wenn Sie eine Client-Instanz nicht gemeinsam nutzen möchten, rufen Sie die Instanz `close()` auf, um die Ressourcen freizugeben, wenn der Client nicht benötigt wird.

## Vermeiden Sie die Erschöpfung des Verbindungspools, indem Sie Eingabestreams schließen
<a name="bestpractice2"></a>

Bei Streaming-Vorgängen`[S3Client\$1getObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(java.util.function.Consumer,java.nio.file.Path))`, z. B. wenn Sie `[ResponseInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/ResponseInputStream.html)` direkt mit arbeiten, empfehlen wir Ihnen, wie folgt vorzugehen:
+ Lesen Sie so schnell wie möglich alle Daten aus dem Eingabestream.
+ Schließen Sie den Eingabestream so schnell wie möglich.

Wir geben diese Empfehlungen ab, weil der Eingabestream ein direkter Datenstrom aus der HTTP-Verbindung ist und die zugrunde liegende HTTP-Verbindung erst wiederverwendet werden kann, wenn alle Daten aus dem Stream gelesen und der Stream geschlossen wurde. Wenn diese Regeln nicht befolgt werden, können dem Client die Ressourcen ausgehen, indem zu viele offene, aber ungenutzte HTTP-Verbindungen zugewiesen werden.

## Optimieren Sie die HTTP-Leistung für die Arbeitslast Ihrer Anwendung
<a name="bestpractice3"></a>

Das SDK bietet eine Reihe von [Standard-HTTP-Konfigurationen](https://github.com/aws/aws-sdk-java-v2/blob/master/http-client-spi/src/main/java/software/amazon/awssdk/http/SdkHttpConfigurationOption.java), die für allgemeine Anwendungsfälle gelten. Wir empfehlen Kunden, die HTTP-Konfigurationen für ihre Anwendungen auf der Grundlage ihrer Anwendungsfälle zu optimieren. 

Als guten Ausgangspunkt bietet das SDK eine Funktion für [intelligente Standardkonfigurationen](http-configuration.md#http-config-smart-defaults). Diese Funktion ist ab Version 2.17.102 verfügbar. Sie wählen je nach Anwendungsfall einen Modus, der sinnvolle Konfigurationswerte bietet. 

## Verbessern Sie die SSL-Leistung mit OpenSSL für asynchrone Clients
<a name="bestpractice4"></a>

Standardmäßig verwenden die SDKs [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html)die Standard-SSL-Implementierung des JDK als. `SslProvider` Unsere Tests haben ergeben, dass OpenSSL besser abschneidet als die Standardimplementierung von JDK. Die Netty-Community [empfiehlt außerdem die Verwendung von OpenSSL](https://netty.io/wiki/requirements-for-4.x.html#tls-with-openssl). 

Um OpenSSL zu verwenden, fügen Sie Ihre Abhängigkeiten `netty-tcnative` hinzu. Einzelheiten zur Konfiguration finden Sie in der [Netty-Projektdokumentation](https://netty.io/wiki/forked-tomcat-native.html).

Nachdem Sie für Ihr Projekt `netty-tcnative` konfiguriert haben, wählt die `NettyNioAsyncHttpClient` Instanz automatisch OpenSSL aus. Alternativ können Sie das `SslProvider` explizit mithilfe des `NettyNioAsyncHttpClient` Builders festlegen, wie im folgenden Snippet gezeigt.

```
NettyNioAsyncHttpClient.builder()
                        .sslProvider(SslProvider.OPENSSL)
                        .build();
```

## Überwachen Sie die Anwendungsleistung mit SDK-Metriken
<a name="bestpractice6"></a>

Das SDK for Java kann [Metriken für die Service-Clients in Ihrer Anwendung sammeln](metrics.md). Sie können diese Messwerte verwenden, um Leistungsprobleme zu identifizieren, allgemeine Nutzungstrends zu überprüfen, zurückgemeldete Service-Client-Ausnahmen zu überprüfen oder um ein bestimmtes Problem genauer zu untersuchen.

Wir empfehlen Ihnen, Metriken zu sammeln und anschließend die CloudWatch Amazon-Logs zu analysieren, um ein tieferes Verständnis der Leistung Ihrer Anwendung zu erhalten.

# Behandlung von Fehlern in der AWS SDK for Java 2.x
<a name="handling-exceptions"></a>

Für die Entwicklung hochwertiger Anwendungen mit dem AWS SDK for Java 2.x SDK ist es wichtig zu verstehen, wie und wann Ausnahmen ausgelöst werden. In den folgenden Abschnitten werden die verschiedenen Fälle von Ausnahmen beschrieben, die vom SDK ausgelöst werden, und wie sie korrekt verarbeitet werden.

## Warum ungeprüfte Ausnahmen?
<a name="why-unchecked-exceptions"></a>

Der AWS SDK für Java verwendet aus den folgenden Gründen Laufzeitausnahmen (oder ungeprüfte Ausnahmen) anstelle von geprüften Ausnahmen:
+ Entwickler erhalten genaue Kontrolle über die Fehler, auf die sie eingehen möchten. Sie werden aber nicht dazu gezwungen, auftretende Ausnahmen zu verarbeiten, für die sie sich nicht interessieren (was den Code übermäßig aufblähen würde).
+ Skalierbarkeitsprobleme durch geprüfte Ausnahmen in großen Anwendungen werden verhindert.

Im Allgemeinen eignen sich geprüfte Ausnahmen gut im kleinen Rahmen. Wenn Anwendungen wachsen und komplexer werden, können sie allerdings zu Problemen führen.

## AwsServiceException (und Unterklassen)
<a name="sdkserviceexception-and-subclasses"></a>

 [AwsServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html)ist die häufigste Ausnahme, die bei der AWS SDK für Java Verwendung von auftritt. `AwsServiceException`ist eine Unterklasse der [SdkServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkServiceException.html)allgemeineren. `AwsServiceException`s steht für eine Fehlerantwort von einem AWS-Service. Wenn Sie beispielsweise versuchen, eine Amazon EC2 Instanz zu beenden, die nicht existiert, Amazon EC2 wird eine Fehlerantwort zurückgegeben, und alle Details dieser Fehlerantwort werden in der `AwsServiceException` ausgegebenen Antwort enthalten. 

Wenn Sie auf eine stoßen`AwsServiceException`, wissen Sie, dass Ihre Anfrage erfolgreich an die gesendet wurde, AWS-Service aber nicht erfolgreich bearbeitet werden konnte. Dies kann an Fehlern in den Parametern der Anforderung oder an Problemen auf Seiten des Services liegen.

 `AwsServiceException` gibt Ihnen Informationen wie z. B.:
+ zurückgegebener HTTP-Statuscode
+  AWS Fehlercode zurückgegeben
+ Detaillierte Fehlermeldung des Dienstes in der [AwsErrorDetails](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsErrorDetails.html)Klasse
+  AWS Anforderungs-ID für die fehlgeschlagene Anfrage

In den meisten Fällen `AwsServiceException` wird eine dienstspezifische Unterklasse von ausgelöst, um Entwicklern eine genaue Kontrolle über die Behandlung von Fehlerfällen durch Catch-Blöcke zu ermöglichen. In der Java-SDK-API-Referenz für [AwsServiceException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsServiceException.html)wird die große Anzahl von Unterklassen angezeigt. `AwsServiceException` Verwenden Sie die Unterklassen-Links, um sich die detaillierten Ausnahmen anzusehen, die von einem Dienst ausgelöst wurden.

Die folgenden Links zur SDK-API-Referenz zeigen beispielsweise die Ausnahmehierarchien für einige häufig vorkommende Ausnahmen. AWS-Services Die Liste der Unterklassen auf den einzelnen Seiten zeigt die spezifischen Ausnahmen, die Ihr Code catch kann.
+ [Amazon S3](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Exception.html)
+ [DynamoDB](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html)
+ [Amazon SQS](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/SqsException.html)

Um mehr über eine Ausnahme zu erfahren, überprüfen Sie die `errorCode` auf dem [AwsErrorDetails](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/exception/AwsErrorDetails.html)Objekt befindlichen. Sie können den `errorCode` Wert verwenden, um Informationen in der Service Guide-API nachzuschlagen. Wenn beispielsweise ein abgefangen `S3Exception` wird und der `AwsErrorDetails#errorCode()` Wert lautet`InvalidRequest`, verwenden Sie die [Liste der Fehlercodes](https://docs.aws.amazon.com/AmazonS3/latest/API/ErrorResponses.html#ErrorCodeList) in der Amazon S3 S3-API-Referenz, um weitere Informationen zu erhalten.

## SdkClientException
<a name="sdkclientexception"></a>

 [SdkClientException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/exception/SdkClientException.html)gibt an, dass im Java-Client-Code ein Problem aufgetreten ist, entweder beim Versuch, eine Anfrage an zu senden, AWS oder beim Versuch, eine Antwort von AWS zu analysieren. An `SdkClientException` ist im Allgemeinen schwerwiegender als ein `SdkServiceException` und weist auf ein schwerwiegendes Problem hin, das den Client daran hindert, Serviceanfragen an AWS Dienste zu tätigen. Dies ist beispielsweise der AWS SDK für Java Fall, `SdkClientException` wenn keine Netzwerkverbindung verfügbar ist, wenn Sie versuchen, einen Vorgang auf einem der Clients aufzurufen.

## Ausnahmen und Wiederholungsverhalten
<a name="retried-exceptions"></a>

Das SDK for Java wiederholt Anfragen für mehrere [clientseitige Ausnahmen](https://github.com/aws/aws-sdk-java-v2/blob/13985e0668a9a0b12ad331644e3c4fd1385c2cd7/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetrySetting.java#L79C41-L79C41) und für [HTTP-Statuscodes](https://github.com/aws/aws-sdk-java-v2/blob/13985e0668a9a0b12ad331644e3c4fd1385c2cd7/core/sdk-core/src/main/java/software/amazon/awssdk/core/internal/retry/SdkDefaultRetrySetting.java#L72C31-L72C31), die es aus Antworten erhält. AWS-Service Diese Fehler werden als Teil der Legacy-Version behandelt`RetryMode`, die Service-Clients standardmäßig verwenden. In der Java-API-Referenz für `[RetryMode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryMode.html)` werden die verschiedenen Möglichkeiten beschrieben, wie Sie den Modus konfigurieren können.

Um die Ausnahmen und HTTP-Statuscodes, die automatische Wiederholungen auslösen, anzupassen, konfigurieren Sie Ihren Service-Client mit einem`[RetryPolicy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/RetryPolicy.html)`, der `[RetryOnStatusCodeCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/awscore/retry/conditions/RetryOnErrorCodeCondition.html)` Instanzen hinzufügt`[RetryOnExceptionsCondition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/conditions/RetryOnExceptionsCondition.html)`.

# Verwenden von paginierten Ergebnissen in der 2.x AWS SDK für Java
<a name="pagination"></a>

Viele AWS Operationen geben paginierte Ergebnisse zurück, wenn das Antwortobjekt zu groß ist, um es in einer einzigen Antwort zurückzugeben. In AWS SDK für Java Version 1.0 enthält die Antwort ein Token, mit dem Sie die nächste Ergebnisseite abrufen. Im Gegensatz dazu verfügt die Version AWS SDK für Java 2.x über Autopaginationsmethoden, die mehrere Serviceaufrufe tätigen, um automatisch die nächste Ergebnisseite für Sie abzurufen. Sie müssen nur Code schreiben, der die Ergebnisse verarbeitet. Autopagination ist sowohl für synchrone als auch für asynchrone Clients verfügbar.

**Anmerkung**  
[Bei diesen Codefragmenten wird davon ausgegangen, dass Sie die [Grundlagen der Verwendung des SDK](using.md) verstehen und Ihre Umgebung mit Single Sign-On-Zugriff konfiguriert haben.](get-started-auth.md#setup-credentials)

## Synchrone Paginierung
<a name="synchronous-pagination"></a>

Die folgenden Beispiele zeigen synchrone Paginierungsmethoden zum Auflisten von Objekten in einem Bucket. Amazon S3 

### Iterieren Sie über Seiten hinweg
<a name="iterate-pages"></a>

Das erste Beispiel demonstriert die Verwendung eines `listRes` Paginator-Objekts, einer [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/paginators/ListObjectsV2Iterable.html)Instanz, um mit der Methode durch alle Antwortseiten zu iterieren. `stream` Der Code streamt über die Antwortseiten, konvertiert den Antwortstream in einen `[S3Object](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/S3Object.html)` Inhaltsstream und verarbeitet dann den Inhalt des Objekts. Amazon S3 

Die folgenden Importe gelten für alle Beispiele in diesem Abschnitt zur synchronen Paginierung.

#### Importe
<a name="synchronous-pagination-ex-import"></a>

```
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Random;

import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.paginators.ListObjectsV2Iterable;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Request;
import software.amazon.awssdk.services.s3.model.ListObjectsV2Response;
import software.amazon.awssdk.services.s3.model.S3Object;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
import software.amazon.awssdk.services.s3.model.DeleteBucketRequest;
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadRequest;
import software.amazon.awssdk.services.s3.model.CreateMultipartUploadResponse;
import software.amazon.awssdk.services.s3.model.CompletedMultipartUpload;
import software.amazon.awssdk.services.s3.model.CreateBucketRequest;
import software.amazon.awssdk.services.s3.model.CompletedPart;
import software.amazon.awssdk.services.s3.model.CreateBucketConfiguration;
import software.amazon.awssdk.services.s3.model.UploadPartRequest;
import software.amazon.awssdk.services.s3.model.CompleteMultipartUploadRequest;
import software.amazon.awssdk.services.s3.waiters.S3Waiter;
import software.amazon.awssdk.services.s3.model.HeadBucketRequest;
import software.amazon.awssdk.services.s3.model.HeadBucketResponse;
```

```
        ListObjectsV2Request listReq = ListObjectsV2Request.builder()
            .bucket(bucketName)
            .maxKeys(1)
            .build();

        ListObjectsV2Iterable listRes = s3.listObjectsV2Paginator(listReq);
        // Process response pages
        listRes.stream()
            .flatMap(r -> r.contents().stream())
            .forEach(content -> System.out
                .println(" Key: " + content.key() + " size = " + content.size()));
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L112) finden Sie unter. GitHub

### Iteriere über Objekte
<a name="iterate-objects"></a>

Die folgenden Beispiele zeigen Möglichkeit, um über die in der Antwort zurückgegebenen Objekte anstatt über die Seiten der Antwort zu iterieren. Die `contents` Methode der `ListObjectsV2Iterable` Klasse gibt eine zurück [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/pagination/sync/SdkIterable.html), die mehrere Methoden zur Verarbeitung der zugrunde liegenden Inhaltselemente bereitstellt.

#### Verwenden Sie einen Stream
<a name="use-a-stream"></a>

Das folgende Snippet verwendet die `stream` Methode für den Inhalt der Antwort, um über die Sammlung von paginierten Elementen zu iterieren.

```
        // Helper method to work with paginated collection of items directly.
        listRes.contents().stream()
            .forEach(content -> System.out
                .println(" Key: " + content.key() + " size = " + content.size()));
```

[Das vollständige Beispiel finden Sie unter.](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L127) GitHub

#### Verwenden Sie eine For-Each-Schleife
<a name="for-loop"></a>

Da die `Iterable` Schnittstelle `SdkIterable` erweitert wird, können Sie den Inhalt wie jeden anderen `Iterable` bearbeiten. Das folgende Snippet verwendet eine `for-each` Standardschleife, um durch den Inhalt der Antwort zu iterieren.

```
        for (S3Object content : listRes.contents()) {
            System.out.println(" Key: " + content.key() + " size = " + content.size());
        }
```

Das [vollständige](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L133) Beispiel finden Sie unter. GitHub

### Manuelle Paginierung
<a name="manual-pagination"></a>

Wenn Ihr Anwendungsfall es erfordert, ist die manuelle Paginierung weiterhin verfügbar. Verwenden Sie das nächste Token im Antwortobjekte für die nachfolgenden Anforderungen. Im folgenden Beispiel wird eine `while` Schleife verwendet.

```
        ListObjectsV2Request listObjectsReqManual = ListObjectsV2Request.builder()
            .bucket(bucketName)
            .maxKeys(1)
            .build();

        boolean done = false;
        while (!done) {
            ListObjectsV2Response listObjResponse = s3.listObjectsV2(listObjectsReqManual);
            for (S3Object content : listObjResponse.contents()) {
                System.out.println(content.key());
            }

            if (listObjResponse.nextContinuationToken() == null) {
                done = true;
            }

            listObjectsReqManual = listObjectsReqManual.toBuilder()
                .continuationToken(listObjResponse.nextContinuationToken())
                .build();
        }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/s3/src/main/java/com/example/s3/S3ObjectOperations.java#L90) finden Sie unter GitHub.

## Asynchrone Paginierung
<a name="asynchronous-pagination"></a>

Die folgenden Beispiele zeigen asynchrone Paginierungsmethoden zum Auflisten von Tabellen. DynamoDB 

### Iterieren Sie über Seiten mit Tabellennamen
<a name="iterate-pages-async"></a>

In den folgenden beiden Beispielen wird ein asynchroner DynamoDB-Client verwendet, der die `listTablesPaginator` Methode mit einer Anforderung zum Abrufen von aufruft. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/paginators/ListTablesPublisher.html) `ListTablesPublisher`implementiert zwei Schnittstellen, was viele Optionen zur Verarbeitung von Antworten bietet. Wir werden uns die Methoden der einzelnen Schnittstellen ansehen.

#### Benutze ein `Subscriber`
<a name="use-a-subscriber"></a>

Das folgende Codebeispiel zeigt, wie paginierte Ergebnisse mithilfe der von `ListTablesPublisher` implementierten `org.reactivestreams.Publisher` Schnittstelle verarbeitet werden. Weitere Informationen zum Modell mit reaktiven Streams finden Sie im [Reactive GitHub Streams-Repo](https://github.com/reactive-streams/reactive-streams-jvm/blob/v1.0.2/README.md).

Die folgenden Importe gelten für alle Beispiele in diesem Abschnitt zur asynchronen Paginierung.

##### Importe
<a name="use-a-subscriber-ex-imports"></a>

```
import io.reactivex.rxjava3.core.Flowable;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.publisher.Flux;
import software.amazon.awssdk.core.async.SdkPublisher;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
import software.amazon.awssdk.services.dynamodb.paginators.ListTablesPublisher;

import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
```

Der folgende Code erwirbt eine `ListTablesPublisher` Instanz.

```
        // Creates a default client with credentials and region loaded from the
        // environment.
        final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();

        ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build();
        ListTablesPublisher publisher = asyncClient.listTablesPaginator(listTablesRequest);
```

Der folgende Code verwendet eine anonyme Implementierung von`org.reactivestreams.Subscriber`, um die Ergebnisse für jede Seite zu verarbeiten.

Die `onSubscribe`-Methode ruft die `Subscription.request`-Methode auf, um Anforderungen von Daten vom Publisher zu initiieren. Diese Methode muss aufgerufen werden, um den Abruf von Daten vom Publisher zu starten. 

Die `onNext` Methode des Abonnenten verarbeitet eine Antwortseite, indem sie auf alle Tabellennamen zugreift und jeden einzelnen ausdruckt. Nachdem die Seite verarbeitet wurde, wird eine weitere Seite vom Herausgeber angefordert. Diese Methode wird wiederholt aufgerufen, bis alle Seiten abgerufen wurden.

Die `onError`-Methode wird ausgelöst, wenn ein Fehler auftritt, während Daten abgerufen werden. Schließlich wird die `onComplete`-Methode aufgerufen, nachdem alle Seiten angefordert wurden.

```
        // A Subscription represents a one-to-one life-cycle of a Subscriber subscribing
        // to a Publisher.
        publisher.subscribe(new Subscriber<ListTablesResponse>() {
            // Maintain a reference to the subscription object, which is required to request
            // data from the publisher.
            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                // Request method should be called to demand data. Here we request a single
                // page.
                subscription.request(1);
            }

            @Override
            public void onNext(ListTablesResponse response) {
                response.tableNames().forEach(System.out::println);
                // After you process the current page, call the request method to signal that
                // you are ready for next page.
                subscription.request(1);
            }

            @Override
            public void onError(Throwable t) {
                // Called when an error has occurred while processing the requests.
            }

            @Override
            public void onComplete() {
                // This indicates all the results are delivered and there are no more pages
                // left.
            }
        });
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L83) finden Sie unter GitHub.

#### Benutze ein `Consumer`
<a name="id1pagination"></a>

Die `SdkPublisher` Schnittstelle, die `ListTablesPublisher` implementiert wird, hat eine `subscribe` Methode, die a annimmt `Consumer` und a zurückgibt`CompletableFuture<Void>`. 

Die `subscribe` Methode aus dieser Schnittstelle kann für einfache Anwendungsfälle verwendet werden, wenn ein zu großer Overhead sein `org.reactivestreams.Subscriber` könnte. Da der folgende Code jede Seite verbraucht, ruft er die `tableNames` Methode auf jeder Seite auf. Die `tableNames` Methode gibt eine Anzahl `java.util.List` von DynamoDB-Tabellennamen zurück, die mit der `forEach` Methode verarbeitet wurden.

```
        // Use a Consumer for simple use cases.
        CompletableFuture<Void> future = publisher.subscribe(
                response -> response.tableNames()
                        .forEach(System.out::println));
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L96) finden Sie unter. GitHub

### Iteriere über Tabellennamen
<a name="iterate-objects-async"></a>

Die folgenden Beispiele zeigen Möglichkeit, um über die in der Antwort zurückgegebenen Objekte anstatt über die Seiten der Antwort zu iterieren. Ähnlich wie das zuvor gezeigte synchrone Amazon S3 S3-Beispiel mit seiner `contents` Methode `ListTablesPublisher` verfügt die asynchrone Ergebnisklasse von DynamoDB über die `tableNames` bequeme Methode, um mit der zugrunde liegenden Elementsammlung zu interagieren. Der Rückgabetyp der `tableNames` Methode ist ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html), der verwendet werden kann, um Artikel auf allen Seiten anzufordern.

#### Verwenden Sie ein `Subscriber`
<a name="id2"></a>

Der folgende Code erfasst eine `SdkPublisher` der zugrunde liegenden Sammlungen von Tabellennamen.

```
        // Create a default client with credentials and region loaded from the
        // environment.
        final DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();

        ListTablesRequest listTablesRequest = ListTablesRequest.builder().limit(3).build();
        ListTablesPublisher listTablesPublisher = asyncClient.listTablesPaginator(listTablesRequest);
        SdkPublisher<String> publisher = listTablesPublisher.tableNames();
```

Der folgende Code verwendet eine anonyme Implementierung von`org.reactivestreams.Subscriber`, um die Ergebnisse für jede Seite zu verarbeiten.

Die `onNext` Methode des Abonnenten verarbeitet ein einzelnes Element der Sammlung. In diesem Fall ist es ein Tabellenname. Nachdem der Tabellenname verarbeitet wurde, wird ein anderer Tabellenname vom Herausgeber angefordert. Diese Methode wird wiederholt aufgerufen, bis alle Tabellennamen abgerufen wurden.

```
        // Use a Subscriber.
        publisher.subscribe(new Subscriber<String>() {
            private Subscription subscription;

            @Override
            public void onSubscribe(Subscription s) {
                subscription = s;
                subscription.request(1);
            }

            @Override
            public void onNext(String tableName) {
                System.out.println(tableName);
                subscription.request(1);
            }

            @Override
            public void onError(Throwable t) {
            }

            @Override
            public void onComplete() {
            }
        });
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L147) finden Sie unter GitHub.

#### Benutze ein `Consumer`
<a name="for-loop-async"></a>

Das folgende Beispiel verwendet die `subscribe` Methode `SdkPublisher` that takes a, `Consumer` um jedes Element zu verarbeiten.

```
        // Use a Consumer.
        CompletableFuture<Void> future = publisher.subscribe(System.out::println);
        future.get();
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L161) finden Sie unter GitHub.

### Verwenden Sie die Bibliothek eines Drittanbieters
<a name="use-third-party-library"></a>

Sie können andere Drittanbieter-Bibliotheken verwenden, statt einen benutzerdefinierten Abonnenten zu implementieren. Dieses Beispiel demonstriert die Verwendung von RxJava, aber jede Bibliothek, die die reaktiven Stream-Schnittstellen implementiert, kann verwendet werden. Weitere Informationen zu dieser Bibliothek GitHub finden Sie auf der [RxJava Wiki-Seite](https://github.com/ReactiveX/RxJava/wiki) unter.

Um die Bibliothek zu verwenden, fügen Sie sie als Abhängigkeit hinzu. Bei Verwendung von Maven zeigt das Beispiel den zu verwendenden POM-Ausschnitt.

 **POM-Eintrag** 

```
<dependency>
      <groupId>io.reactivex.rxjava3</groupId>
      <artifactId>rxjava</artifactId>
      <version>3.1.6</version>
</dependency>
```

 **Code** 

```
        DynamoDbAsyncClient asyncClient = DynamoDbAsyncClient.create();
        ListTablesPublisher publisher = asyncClient.listTablesPaginator(ListTablesRequest.builder()
                .build());

        // The Flowable class has many helper methods that work with
        // an implementation of an org.reactivestreams.Publisher.
        List<String> tables = Flowable.fromPublisher(publisher)
                .flatMapIterable(ListTablesResponse::tableNames)
                .toList()
                .blockingGet();
        System.out.println(tables);
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/f807d60010caf3d14fe4cd0801b842fb8e9511ca/javav2/example_code/dynamodbasync/src/main/java/com/example/dynamodbasync/AsyncPagination.java#L198) finden Sie unter GitHub.

# Mit Kellnern in der AWS SDK for Java 2.x
<a name="waiters"></a>

Mit dem Waiter-Hilfsprogramm der Version AWS SDK für Java 2.x können Sie überprüfen, ob sich AWS Ressourcen in einem bestimmten Zustand befinden, bevor Sie Operationen mit diesen Ressourcen ausführen.

Ein *Waiter* ist eine Abstraktion, die verwendet wird, um AWS Ressourcen wie DynamoDB Tabellen oder Amazon S3 Buckets abzufragen, bis ein gewünschter Status erreicht ist (oder bis festgestellt wird, dass die Ressource niemals den gewünschten Status erreichen wird). Anstatt Logik zu schreiben, um Ihre AWS Ressourcen kontinuierlich abzufragen, was umständlich und fehleranfällig sein kann, können Sie Waiter verwenden, um eine Ressource abzufragen und Ihren Code weiterlaufen zu lassen, nachdem die Ressource bereit ist.

## Voraussetzungen
<a name="prerequisiteswaiters"></a>

[Bevor Sie Waiters in einem Projekt mit dem verwenden können AWS SDK für Java, müssen Sie die Schritte unter 2.x einrichten ausführen. AWS SDK für Java](setup.md)

Außerdem müssen Sie Ihre Projektabhängigkeiten (z. B. in Ihrer `pom.xml` `build.gradle` OR-Datei) so konfigurieren, dass Version `2.15.0` oder höher von verwendet wird. AWS SDK für Java

Beispiel:

```
<project>
  <dependencyManagement>
   <dependencies>
      <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>bom</artifactId>
        <version>2.27.21</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
   </dependencies>
  </dependencyManagement>
</project>
```

## Kellner benutzen
<a name="id1waiters"></a>

Um ein Waiters-Objekt zu instanziieren, erstellen Sie zunächst einen Service-Client. Legen Sie die `waiter()` Methode des Service-Clients als Wert des Waiter-Objekts fest. Sobald die Waiter-Instanz existiert, legen Sie ihre Antwortoptionen fest, um den entsprechenden Code auszuführen.

### Synchrone Programmierung
<a name="synchronous-programming"></a>

**Der folgende Codeausschnitt zeigt, wie man darauf wartet, dass eine DynamoDB Tabelle existiert und sich im Status AKTIV befindet.**

```
DynamoDbClient dynamo = DynamoDbClient.create();
DynamoDbWaiter waiter = dynamo.waiter();

WaiterResponse<DescribeTableResponse> waiterResponse =
  waiter.waitUntilTableExists(r -> r.tableName("myTable"));

// print out the matched response with a tableStatus of ACTIVE
waiterResponse.matched().response().ifPresent(System.out::println);
```

### Asynchrone Programmierung
<a name="asynchronous-programming"></a>

Der folgende Codeausschnitt zeigt, wie man darauf wartet, dass eine DynamoDB Tabelle nicht mehr existiert.

```
DynamoDbAsyncClient asyncDynamo = DynamoDbAsyncClient.create();
DynamoDbAsyncWaiter asyncWaiter = asyncDynamo.waiter();

CompletableFuture<WaiterResponse<DescribeTableResponse>> waiterResponse =
          asyncWaiter.waitUntilTableNotExists(r -> r.tableName("myTable"));

waiterResponse.whenComplete((r, t) -> {
  if (t == null) {
   // print out the matched ResourceNotFoundException
   r.matched().exception().ifPresent(System.out::println);
  }
}).join();
```

## Kellner konfigurieren
<a name="configuring-waiters"></a>

Sie können die Konfiguration für einen Kellner anpassen, indem Sie den in `overrideConfiguration()` seinem Builder verwenden. Bei einigen Vorgängen können Sie bei der Anfrage eine benutzerdefinierte Konfiguration anwenden.

### Konfigurieren Sie einen Kellner
<a name="configure-a-waiter"></a>

Der folgende Codeausschnitt zeigt, wie Sie die Konfiguration eines Kellners überschreiben können.

```
// sync
DynamoDbWaiter waiter =
   DynamoDbWaiter.builder()
          .overrideConfiguration(b -> b.maxAttempts(10))
          .client(dynamoDbClient)
          .build();
// async
DynamoDbAsyncWaiter asyncWaiter =
   DynamoDbAsyncWaiter.builder()
          .client(dynamoDbAsyncClient)
          .overrideConfiguration(o -> o.backoffStrategy(
               FixedDelayBackoffStrategy.create(Duration.ofSeconds(2))))
          .scheduledExecutorService(Executors.newScheduledThreadPool(3))
          .build();
```

### Überschreiben Sie die Konfiguration für eine bestimmte Anfrage
<a name="override-configuration-for-a-specific-request"></a>

Der folgende Codeausschnitt zeigt, wie Sie die Konfiguration für einen Kellner pro Anfrage überschreiben können. Beachten Sie, dass nur für einige Operationen anpassbare Konfigurationen verfügbar sind.

```
waiter.waitUntilTableNotExists(b -> b.tableName("myTable"),
               o -> o.maxAttempts(10));

asyncWaiter.waitUntilTableExists(b -> b.tableName("myTable"),
                 o -> o.waitTimeout(Duration.ofMinutes(1)));
```

## Codebeispiele
<a name="code-examples"></a>

Ein vollständiges Beispiel für die Verwendung von waiters with DynamoDB finden Sie unter [CreateTable.java](https://github.com/awsdocs/aws-doc-sdk-examples/blob/869b7ddbc7c8f66c7c45acd5b813429aff37003e/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/CreateTable.java) im AWS Code Examples Repository.

Ein vollständiges Beispiel für die Verwendung von waiters with Amazon S3 finden Sie unter [S3 BucketOps .java](https://github.com/awsdocs/aws-doc-sdk-examples/blob/869b7ddbc7c8f66c7c45acd5b813429aff37003e/javav2/example_code/s3/src/main/java/com/example/s3/S3BucketOps.java) im Code Examples Repository. AWS 

# Problembehebung FAQs
<a name="troubleshooting"></a>

 AWS SDK for Java 2.x Bei der Verwendung von in Ihren Anwendungen können die in diesem Thema aufgeführten Laufzeitfehler auftreten. Verwenden Sie die hier aufgeführten Vorschläge, um die Ursache zu ermitteln und den Fehler zu beheben.

## Wie behebe ich den Fehler "`java.net.SocketException`: Verbindung zurückgesetzt“ oder „Server konnte die Antwort nicht abschließen“?
<a name="faq-socketexception"></a>

Ein Fehler beim Zurücksetzen der Verbindung weist darauf hin, dass Ihr Host AWS-Service, der oder eine zwischengeschaltete Partei (z. B. ein NAT-Gateway, ein Proxy, ein Load Balancer) die Verbindung geschlossen hat, bevor die Anfrage abgeschlossen war. Da es viele Ursachen gibt, müssen Sie für die Suche nach einer Lösung wissen, warum die Verbindung geschlossen wurde. Die folgenden Faktoren führen in der Regel dazu, dass eine Verbindung geschlossen wird.
+ **Die Verbindung ist inaktiv.**Dies ist bei Streaming-Vorgängen üblich, bei denen für einen bestimmten Zeitraum keine Daten auf oder von der Leitung geschrieben werden, sodass eine zwischengeschaltete Partei die Verbindung als unterbrochen erkennt und sie schließt. Um dies zu verhindern, stellen Sie sicher, dass Ihre Anwendung aktiv Daten herunterlädt oder hochlädt.
+ **Sie haben den HTTP- oder SDK-Client geschlossen.** Achten Sie darauf, Ressourcen nicht zu schließen, während sie verwendet werden.
+ **Ein falsch konfigurierter Proxy.** Versuchen Sie, alle von Ihnen konfigurierten Proxys zu umgehen, um festzustellen, ob das Problem dadurch behoben wird. Wenn das Problem dadurch behoben wird, schließt der Proxy Ihre Verbindung aus irgendeinem Grund. Untersuchen Sie Ihren spezifischen Proxy, um herauszufinden, warum er die Verbindung schließt.

Wenn Sie das Problem nicht identifizieren können, versuchen Sie, einen TCP-Dump für eine betroffene Verbindung am Client-Edge Ihres Netzwerks auszuführen (z. B. hinter allen Proxys, die Sie kontrollieren). 

Wenn Sie feststellen, dass der AWS Endpunkt einen `TCP RST` (Reset) sendet, [wenden Sie sich an den betroffenen Dienst](https://aws.amazon.com/contact-us/), um herauszufinden, warum der Reset durchgeführt wird. Seien Sie bereit, die Anfrage IDs und den Zeitstempel anzugeben, wann das Problem aufgetreten ist. Das AWS Support-Team könnte auch von [Übertragungsprotokollen](logging-slf4j.md#sdk-java-logging-verbose) profitieren, aus denen genau hervorgeht, welche Byte Ihre Anwendung wann sendet und empfängt.

## Wie behebe ich das „Verbindungs-Timeout“?
<a name="faq-connection-timeout"></a>

Ein Verbindungs-Timeout-Fehler weist darauf hin, dass Ihr Host AWS-Service, der oder eine zwischengeschaltete Partei (z. B. ein NAT-Gateway, ein Proxy, ein Load Balancer) innerhalb des konfigurierten Verbindungstimeouts keine neue Verbindung mit dem Server herstellen konnte. In den folgenden Abschnitten werden die häufigsten Ursachen für dieses Problem beschrieben.
+ **Das konfigurierte Verbindungstimeout ist zu niedrig.** Standardmäßig beträgt das Verbindungs-Timeout 2 Sekunden in der. AWS SDK for Java 2.x Wenn Sie das Verbindungstimeout zu niedrig einstellen, wird möglicherweise dieser Fehler angezeigt. Das empfohlene Verbindungstimeout beträgt 1 Sekunde, wenn Sie nur Anrufe innerhalb der Region tätigen, und 3 Sekunden, wenn Sie regionsübergreifende Anfragen stellen.
+ **Ein falsch konfigurierter Proxy.** Versuchen Sie, alle von Ihnen konfigurierten Proxys zu umgehen, um festzustellen, ob das Problem dadurch behoben wird. Wenn das Problem dadurch behoben wird, ist der Proxy der Grund für das Verbindungstimeout. Recherchiere deinen spezifischen Proxy, um herauszufinden, warum das passiert

Wenn Sie das Problem nicht identifizieren können, versuchen Sie, einen TCP-Dump für eine betroffene Verbindung am Client-Edge Ihres Netzwerks auszuführen (z. B. hinter allen Proxys, die Sie kontrollieren), um das Netzwerkproblem zu untersuchen.

## Wie behebe ich "`java.net.SocketTimeoutException`: Timeout beim Lesen“?
<a name="faq-socket-timeout"></a>

Ein Timeout-Fehler beim Lesen weist darauf hin, dass die JVM versucht hat, Daten vom zugrunde liegenden Betriebssystem zu lesen, die Daten jedoch nicht innerhalb der über das SDK konfigurierten Zeit zurückgegeben wurden. Dieser Fehler kann auftreten, wenn das Betriebssystem AWS-Service, die oder eine zwischengeschaltete Partei (z. B. ein NAT-Gateway, ein Proxy, ein Load Balancer) Daten nicht innerhalb der von der JVM erwarteten Zeit sendet. Da es viele Ursachen gibt, müssen Sie für die Suche nach einer Lösung wissen, warum die Daten nicht zurückgegeben werden.

Versuchen Sie, einen TCP-Dump für eine betroffene Verbindung am Client-Edge Ihres Netzwerks auszuführen (z. B. hinter allen Proxys, die Sie kontrollieren). 

Wenn Sie feststellen, dass der AWS Endpunkt einen `TCP RST` (Reset) sendet, [wenden Sie sich an den betroffenen Dienst](https://aws.amazon.com/contact-us/). Seien Sie bereit, die Anfrage IDs und den Zeitstempel anzugeben, wann das Problem aufgetreten ist. Das AWS Support-Team könnte auch von [Übertragungsprotokollen](logging-slf4j.md#sdk-java-logging-verbose) profitieren, aus denen genau hervorgeht, welche Byte Ihre Anwendung wann sendet und empfängt.

## Wie behebe ich den Fehler „HTTP-Anfrage kann nicht ausgeführt werden: Timeout beim Warten auf Verbindung vom Pool“?
<a name="faq-pool-timeout"></a>

Dieser Fehler weist darauf hin, dass mit einer Anfrage innerhalb der angegebenen maximalen Zeit keine Verbindung vom Pool hergestellt werden kann. Um das Problem zu beheben, empfehlen wir, die [clientseitigen SDK-Metriken zu aktivieren, um Metriken](metrics.md) auf Amazon zu veröffentlichen. CloudWatch Die HTTP-Metriken können dabei helfen, die Ursache einzugrenzen. In den folgenden Artikeln werden die häufigsten Ursachen für diesen Fehler beschrieben.
+ **Verbindungsleck.** Sie können dies untersuchen, indem Sie die `MaxConcurrency` Metriken `LeasedConcurrency``AvailableConcurrency`,, und überprüfen. Wenn der Wert `LeasedConcurrency` zunimmt, bis er den Wert erreicht, `MaxConcurrency` aber nie abnimmt, liegt möglicherweise ein Verbindungsleck vor. Eine häufige Ursache für ein Datenleck ist, dass ein Streaming-Vorgang — z. B. eine `getObject` S3-Methode — nicht abgeschlossen ist. Wir empfehlen, dass Ihre Anwendung so schnell wie möglich alle Daten aus dem Eingabestream liest und [den Eingabestream anschließend schließt](best-practices.md#bestpractice2). Die folgende Tabelle zeigt, wie SDK-Metriken für Verbindungslecks aussehen könnten.  
![\[Ein Screenshot von CloudWatch Metriken, die auf ein wahrscheinliches Verbindungsleck hinweisen.\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/images/JavaDevGuide-connection-leak-metrics-chart.png)
+ **Mangel an Verbindungspool.**Dies kann passieren, wenn Ihre Anforderungsrate zu hoch ist und die konfigurierte Größe des Verbindungspools den Anforderungsbedarf nicht decken kann. Die Standardgröße des Verbindungspools ist 50, und wenn die Verbindungen im Pool das Maximum erreichen, stellt der HTTP-Client eingehende Anfragen in eine Warteschlange, bis Verbindungen verfügbar sind. Die folgende Tabelle zeigt, wie SDK-Metriken bei einem Ausfall des Verbindungspools aussehen könnten.  
![\[Ein Screenshot von CloudWatch Messwerten, die zeigen, wie ein Ausfall des Verbindungspools aussehen könnte.\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/images/JavaDevGuide-connection-pool-starvation-chart.png)

  Um dieses Problem zu beheben, sollten Sie eine der folgenden Maßnahmen in Betracht ziehen.
  + Erhöhen Sie die Größe des Verbindungspools,
  + Erhöhen Sie das Acquire-Timeout.
  + Verlangsamen Sie die Anforderungsrate.

  Durch die Erhöhung der maximalen Anzahl von Verbindungen kann der Client-Durchsatz erhöht werden (sofern die Netzwerkschnittstelle nicht bereits voll ausgelastet ist). Im Laufe der Zeit kann es jedoch zu Einschränkungen des Betriebssystems kommen, was die Anzahl der vom Prozess verwendeten Dateideskriptoren angeht. Wenn Sie Ihre Netzwerkschnittstelle bereits vollständig nutzen oder die Anzahl der Verbindungen nicht weiter erhöhen können, versuchen Sie, das Acque-Timeout zu erhöhen. Mit der Erhöhung gewinnen Sie zusätzliche Zeit für Anfragen zum Verbindungsaufbau, bevor das Timeout abläuft. Wenn die Verbindungen nicht freigegeben werden, kommt es bei den nachfolgenden Anfragen trotzdem zu einem Timeout. 

  Wenn Sie das Problem mit den ersten beiden Mechanismen nicht beheben können, verringern Sie die Anforderungsrate, indem Sie die folgenden Optionen ausprobieren.
  + Glätten Sie Ihre Anfragen, sodass der Client nicht durch große Datenverkehrsströme überlastet wird.
  + Seien Sie effizienter mit Anrufen an AWS-Services.
  + Erhöhen Sie die Anzahl der Hosts, die Anfragen senden.
+ **I/O-Threads sind zu ausgelastet.** Dies gilt nur, wenn Sie einen asynchronen SDK-Client mit [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html)verwenden. Wenn die `AvailableConcurrency` Metrik nicht niedrig ist — was darauf hinweist, dass Verbindungen im Pool verfügbar sind —, sondern hoch, `ConcurrencyAcquireDuration` liegt das möglicherweise daran, dass I/O Threads die Anfragen nicht verarbeiten können. Stellen Sie sicher, dass Sie sich nicht `Runnable:run` als [zukünftiger Completion-Executor ausgeben](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/client/config/SdkAdvancedAsyncClientOption.html#FUTURE_COMPLETION_EXECUTOR) und zeitaufwändige Aufgaben in der Antwortkette für die future Fertigstellung ausführen, da dies einen I/O Thread blockieren kann. Wenn das nicht der Fall ist, sollten Sie erwägen, die Anzahl der I/O Threads mithilfe der `[eventLoopGroupBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.Builder.html#eventLoopGroupBuilder(software.amazon.awssdk.http.nio.netty.SdkEventLoopGroup.Builder))` Methode zu erhöhen. Als Referenz: Die Standardanzahl von I/O-Threads für eine `NettyNioAsyncHttpClient` Instanz ist doppelt so hoch wie die Anzahl der CPU-Kerne des Hosts.
+ **Hohe TLS-Handshake-Latenz.** Wenn Ihre `AvailableConcurrency` Metrik nahe 0 und niedriger als `LeasedConcurrency` ist, kann dies daran liegen`MaxConcurrency`, dass die TLS-Handshake-Latenz hoch ist. Die folgende Tabelle zeigt, wie SDK-Metriken für eine hohe TLS-Handshake-Latenz aussehen könnten.  
![\[Ein Screenshot von CloudWatch Metriken, die auf eine hohe TLS-Handshake-Latenz hinweisen könnten.\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/images/JavaDevGuide-high-tls-latency-chart.png)

  Versuchen Sie für vom Java SDK angebotene HTTP-Clients, die nicht auf CRT basieren, [TLS-Protokolle zu aktivieren, um TLS-Probleme](security-java-tls.md) zu beheben. [Versuchen Sie für den AWS CRT-basierten HTTP-Client, CRT-Protokolle zu aktivieren AWS .](logging-slf4j.md#sdk-java-logging-verbose) Wenn Sie feststellen, dass der AWS Endpunkt anscheinend lange braucht, um einen TLS-Handshake durchzuführen, sollten Sie sich an den betroffenen Dienst [wenden](https://aws.amazon.com/contact-us/).

## Wie behebe ich ein`NoClassDefFoundError`, `NoSuchMethodError` oder`NoSuchFieldError`?
<a name="faq-classpath-errors"></a>

A `NoClassDefFoundError` gibt an, dass eine Klasse zur Laufzeit nicht geladen werden konnte. Die zwei häufigsten Ursachen für diesen Fehler sind:
+ Die Klasse ist im Klassenpfad nicht vorhanden, weil die JAR fehlt oder die falsche Version der JAR sich im Klassenpfad befindet.
+ Die Klasse konnte nicht geladen werden, weil ihr statischer Initialisierer eine Ausnahme ausgelöst hat.

In ähnlicher Weise resultieren `NoSuchMethodError` s und `NoSuchFieldError` s typischerweise aus einer nicht übereinstimmenden JAR-Version. Wir empfehlen Ihnen, die folgenden Schritte durchzuführen.

1. **Überprüfen Sie Ihre Abhängigkeiten**, um sicherzustellen, dass Sie *dieselbe Version aller SDK-Jars* verwenden. Der häufigste Grund dafür, dass eine Klasse, Methode oder ein Feld nicht gefunden werden kann, ist, wenn Sie auf eine neue Client-Version aktualisieren, aber weiterhin eine alte, gemeinsam genutzte SDK-Abhängigkeitsversion verwenden. Die neue Client-Version versucht möglicherweise, Klassen zu verwenden, die nur in neueren „gemeinsam genutzten“ SDK-Abhängigkeiten existieren. Versuchen Sie, `mvn dependency:tree` oder `gradle dependencies` (für Gradle) auszuführen, um zu überprüfen, ob alle Versionen der SDK-Bibliothek übereinstimmen. Um dieses Problem in future vollständig zu vermeiden, empfehlen wir die Verwendung von [BOM (Bill of Materials)](setup-project-maven.md#sdk-as-dependency) zur Verwaltung von SDK-Modulversionen.

   Das folgende Beispiel zeigt Ihnen ein Beispiel für gemischte SDK-Versionen.

   ```
   [INFO] +- software.amazon.awssdk:dynamodb:jar:2.20.00:compile
   [INFO] |  +- software.amazon.awssdk:aws-core:jar:2.13.19:compile
   [INFO] +- software.amazon.awssdk:netty-nio-client:jar:2.20.00:compile
   ```

   Die Version von `dynamodb` ist 2.20.00 und die Version von `aws-core` ist 2.13.19. Die `aws-core` Artefaktversion sollte ebenfalls 2.20.00 sein.

1. **Überprüfen Sie die Anweisungen zu Beginn Ihrer Logs**, um festzustellen, ob eine Klasse aufgrund eines statischen Initialisierungsfehlers nicht geladen werden kann. Wenn die Klasse zum ersten Mal nicht geladen werden kann, wird möglicherweise eine andere, nützlichere Ausnahme ausgelöst, die angibt, *warum* die Klasse nicht geladen werden kann. Diese potenziell nützliche Ausnahme tritt nur einmal auf, sodass spätere Protokollanweisungen nur melden, dass die Klasse nicht gefunden wurde.

1. **Überprüfen Sie Ihren Bereitstellungsprozess**, um sicherzustellen, dass die erforderlichen JAR-Dateien tatsächlich zusammen mit Ihrer Anwendung bereitgestellt werden. Es ist möglich, dass Sie mit der richtigen Version bauen, aber der Prozess, der den Klassenpfad für Ihre Anwendung erstellt, schließt eine erforderliche Abhängigkeit aus.

## Wie behebe ich den Fehler "`SignatureDoesNotMatch`" oder den Fehler „Die von uns berechnete Anforderungssignatur stimmt nicht mit der von Ihnen angegebenen Signatur überein“?
<a name="faq-signature-does-not-match-error"></a>

Ein `SignatureDoesNotMatch` Fehler weist darauf hin, dass die von generierte Signatur AWS SDK für Java und die von der generierte Signatur AWS-Service nicht übereinstimmen. In den folgenden Punkten werden mögliche Ursachen beschrieben.
+ Ein Proxy oder eine zwischengeschaltete Partei ändert die Anfrage. Beispielsweise könnte ein Proxy oder Load Balancer einen Header, Pfad oder eine Abfragezeichenfolge ändern, die vom SDK signiert wurden.
+ Der Dienst und das SDK unterscheiden sich darin, wie sie die Anfrage codieren, wenn sie jeweils die zu signierende Zeichenfolge generieren.

Um dieses Problem zu beheben, empfehlen wir, die [Debug-Protokollierung für das SDK zu aktivieren](logging-slf4j.md#sdk-debug-level-logging). Versuchen Sie, den Fehler zu reproduzieren und die kanonische Anfrage zu finden, die das SDK generiert hat. Im Protokoll ist die kanonische Anfrage mit gekennzeichnet `AWS4 Canonical Request: ...` und die zu signierende Zeichenfolge ist beschriftet. `AWS4 String to sign: ...` 

Wenn Sie das Debuggen nicht aktivieren können, z. B. weil es nur in der Produktion reproduzierbar ist, fügen Sie Ihrer Anwendung eine Logik hinzu, die Informationen über die Anfrage protokolliert, wenn der Fehler auftritt. Sie können diese Informationen dann verwenden, um zu versuchen, den Fehler außerhalb der Produktion in einem Integrationstest mit aktivierter Debug-Protokollierung zu replizieren.

Nachdem Sie die kanonische Anfrage und die zu signierende Zeichenfolge erfasst haben, vergleichen Sie sie mit der [AWS Signature Version 4-Spezifikation](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html), um festzustellen, ob es Probleme mit der Art und Weise gibt, wie das SDK die zu signierende Zeichenfolge generiert hat. Wenn etwas nicht in Ordnung zu sein scheint, können Sie einen [GitHub Fehlerbericht](https://github.com/aws/aws-sdk-java-v2/issues/new/choose) an die erstellen. AWS SDK für Java

Wenn nichts falsch zu sein scheint, können Sie die Zeichenkette zum Signieren des SDK mit der Zeichenfolge vergleichen, die einige als Teil der Fehlerreaktion AWS-Services zurückgeben (z. B. Amazon S3). Wenn dies nicht verfügbar ist, sollten Sie [sich an den betroffenen Dienst wenden](https://aws.amazon.com/contact-us/), um zu erfahren, welche kanonische Anfrage und welche Zeichenfolge zum Signieren er für den Vergleich generiert hat. Diese Vergleiche können helfen, zwischengeschaltete Parteien zu identifizieren, die möglicherweise die Anfrage oder die Codierungsunterschiede zwischen dem Dienst und dem Client geändert haben.

Weitere Hintergrundinformationen zum Signieren von Anfragen finden Sie im AWS Identity and Access Management Benutzerhandbuch unter [Signieren von AWS API-Anfragen](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-signing.html).

**Example einer kanonischen Anfrage**  

```
PUT
/Example-Bucket/Example-Object
partNumber=19&uploadId=string
amz-sdk-invocation-id:f8c2799d-367c-f024-e8fa-6ad6d0a1afb9
amz-sdk-request:attempt=1; max=4
content-encoding:aws-chunked
content-length:51
content-type:application/octet-stream
host:xxxxx
x-amz-content-sha256:STREAMING-UNSIGNED-PAYLOAD-TRAILER
x-amz-date:20240308T034733Z
x-amz-decoded-content-length:10
x-amz-sdk-checksum-algorithm:CRC32
x-amz-trailer:x-amz-checksum-crc32
```

**Example einer Zeichenfolge, die signiert werden soll**  

```
AWS4-HMAC-SHA256
20240308T034435Z
20240308/us-east-1/s3/aws4_request
5f20a7604b1ef65dd89c333fd66736fdef9578d11a4f5d22d289597c387dc713
```

## Wie behebe ich den Fehler "`java.lang.IllegalStateException`: Der Verbindungspool wurde heruntergefahren“?
<a name="faq-connection-pool-shutdown-exception"></a>

Dieser Fehler weist darauf hin, dass der zugrunde liegende Apache HTTP-Verbindungspool geschlossen wurde. In den folgenden Artikeln werden mögliche Ursachen beschrieben.
+ **Der SDK-Client wurde vorzeitig geschlossen.**Das SDK schließt den Verbindungspool nur, wenn der zugehörige Client geschlossen wird. Achten Sie darauf, Ressourcen nicht zu schließen, während sie verwendet werden.
+ **A `java.lang.Error` wurde geworfen.** Fehler, die z. B. `OutOfMemoryError` dazu führen, dass ein Apache HTTP-Verbindungspool [heruntergefahren wird](https://github.com/apache/httpcomponents-client/blob/6a741b4f8f23e6c5c7cc42c36c2acabfac19c3d6/httpclient/src/main/java/org/apache/http/impl/execchain/MainClientExec.java#L368). Untersuchen Sie Ihre Logs auf Fehler-Stack-Traces. Überprüfen Sie Ihren Code auch auf Stellen, an denen er `Throwable` s oder `Error` s abfängt, aber die Ausgabe verschluckt, wodurch verhindert wird, dass der Fehler auftaucht. Wenn Ihr Code keine Fehler meldet, schreiben Sie den Code neu, sodass die Informationen protokolliert werden. Die protokollierten Informationen helfen dabei, die Ursache des Fehlers zu ermitteln.
+ **Sie haben versucht, den Anbieter für Anmeldeinformationen zu verwenden, der `DefaultCredentialsProvider#create()` nach dem Schließen zurückgegeben wurde**. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html#create()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/DefaultCredentialsProvider.html#create())gibt eine Singleton-Instanz zurück. Wenn sie also geschlossen ist und Ihr Code die `resolveCredentials` Methode aufruft, wird die Ausnahme ausgelöst, nachdem die zwischengespeicherten Anmeldeinformationen (oder Token) abgelaufen sind. 

  Überprüfen Sie Ihren Code auf Stellen, an denen der geschlossen `DefaultCredentialsProvider` ist, wie in den folgenden Beispielen gezeigt.
  + Die Singleton-Instanz wird durch Aufrufen geschlossen `DefaultCredentialsProvider#close().`

    ```
    DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // Singleton instance returned.
    AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
    
    // Make calls to AWS-Services.
    
    defaultCredentialsProvider.close();  // Explicit close.
    
    // Make calls to AWS-Services.
    
    // After the credentials expire, either of the following calls eventually results in a "Connection pool shut down" exception.
    credentials = defaultCredentialsProvider.resolveCredentials();
    // Or
    credentials = DefaultCredentialsProvider.create().resolveCredentials();
    ```
  + `DefaultCredentialsProvider#create()`In einem try-with-resources Block aufrufen.

    ```
    try (DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create()) {
        AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
        
        // Make calls to AWS-Services.
    
    } // After the try-with-resources block exits, the singleton DefaultCredentialsProvider is closed.
    
    // Make calls to AWS-Services.
    
    DefaultCredentialsProvider defaultCredentialsProvider = DefaultCredentialsProvider.create(); // The closed singleton instance is returned.
    // If the credentials (or token) has expired, the following call results in the error.
    AwsCredentials credentials = defaultCredentialsProvider.resolveCredentials();
    ```

  Erstellen Sie eine neue Nicht-Singleton-Instanz, indem Sie aufrufen, `DefaultCredentialsProvider.builder().build()` falls Ihr Code die Singleton-Instanz geschlossen hat und Sie Anmeldeinformationen mithilfe von a auflösen müssen. `DefaultCredentialsProvider`

## Wie behebe ich „Anmeldeinformationen können von keinem der Anbieter in der Kette geladen werden“? AwsCredentialsProviderChain
<a name="faq-credentials-provider-chain"></a>

Dieser Fehler weist darauf hin, dass über keinen der Anmeldeinformationsanbieter in der Kette der Standardanbieter für AWS Anmeldeinformationen gültige Anmeldeinformationen gefunden werden AWS SDK for Java 2.x konnten. Das SDK sucht automatisch in einer bestimmten Reihenfolge nach Anmeldeinformationen. Dieser Fehler tritt auf, wenn alle Anbieter in der Kette keine gültigen Anmeldeinformationen bereitstellen.

Die vollständige Fehlermeldung sieht normalerweise so aus (Zeilenenden und Einrückungen wurden hinzugefügt, um die Lesbarkeit zu verbessern):

```
Unable to load credentials from any of the providers in the chain AwsCredentialsProviderChain(
    credentialsProviders=[
        SystemPropertyCredentialsProvider(),
        EnvironmentVariableCredentialsProvider(), 
        WebIdentityTokenCredentialsProvider(), 
        ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])), 
        ContainerCredentialsProvider(), 
        InstanceProfileCredentialsProvider()
    ]) : [
        SystemPropertyCredentialsProvider(): Unable to load credentials from system settings.
        Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) 
        or system property (aws.accessKeyId)., 

        EnvironmentVariableCredentialsProvider(): Unable to load credentials from system settings. 
        Access key must be specified either via environment variable (AWS_ACCESS_KEY_ID) 
        or system property (aws.accessKeyId)., 

        WebIdentityTokenCredentialsProvider(): To use web identity tokens, the 'sts' service module 
        must be on the class path., 

        ProfileCredentialsProvider(profileName=default, profileFile=ProfileFile(sections=[])): 
        Profile file contained no credentials for profile 'default': ProfileFile(sections=[]), 

        ContainerCredentialsProvider(): Cannot fetch credentials from container - neither 
        AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI environment 
        variables are set., 

        InstanceProfileCredentialsProvider(): Failed to load credentials from IMDS.]
```

### Häufige Ursachen und Lösungen
<a name="faq-cred-provider-chain-common-causes-and-solutions"></a>

#### Überprüfen Sie die Konfiguration Ihrer Anmeldeinformationen
<a name="faq-cred-provider-chain-check-config"></a>

Wenn Sie den Standardanmeldedienstanbieter verwenden (indem Sie die Anmeldeinformationen aufrufen, `ServiceClient.create()` ohne die Anmeldeinformationen explizit zu konfigurieren), sucht das SDK in einer bestimmten Reihenfolge nach Anmeldeinformationen. Sehen Sie sich an, [wie die standardmäßige Anbieterkette für Anmeldeinformationen funktioniert](credentials-chain.md), um zu verstehen, welche Anmeldeinformationsquellen das SDK in welcher Reihenfolge überprüft.

Stellen Sie sicher, dass die Methode zur Konfiguration der Anmeldeinformationen, die Sie verwenden möchten, in Ihrer Umgebung ordnungsgemäß eingerichtet ist:

##### Für Amazon EC2 EC2-Instances
<a name="faq-cred-check-ec2"></a>
+ **Überprüfen Sie die IAM-Rolle:** Stellen Sie sicher, dass Ihrer Instance eine IAM-Rolle zugewiesen ist.
+ **Intermittierende IMDS-Ausfälle:** Wenn Sie zeitweise Ausfälle haben (in der Regel einige hundert Millisekunden), deutet dies in der Regel auf vorübergehende Netzwerkprobleme hin, die den Instance Metadata Service (IMDS) erreichen.

  Lösungen:
  + Aktivieren Sie die [Debug-Protokollierung](logging-slf4j.md#sdk-debug-level-logging), um den Zeitpunkt und die Häufigkeit von Ausfällen zu analysieren
  + Erwägen Sie die Implementierung einer Wiederholungslogik in Ihrer Anwendung für Fehler im Zusammenhang mit Anmeldeinformationen
  + Prüfen Sie, ob Netzwerkverbindungsprobleme zwischen Ihrer Instance und dem IMDS-Endpunkt bestehen

##### Für Container-Umgebungen
<a name="faq-cred-check-container-env"></a>

Vergewissern Sie sich, dass Aufgabenrollen (Amazon ECS) oder Dienstkonten (Amazon EKS) konfiguriert sind und dass die erforderlichen Umgebungsvariablen festgelegt sind.

##### Für die lokale Entwicklung
<a name="faq-cred-check-local-dev"></a>

Vergewissern Sie sich, dass die Umgebungsvariablen, die Anmeldeinformationsdateien oder die IAM Identity Center-Konfiguration vorhanden sind.

##### Für den Web-Identitätsverbund
<a name="faq-cred-check-web-id-federation"></a>
+ **Konfiguration überprüfen:** Stellen Sie sicher, dass die Webidentitäts-Tokendatei vorhanden ist und dass die erforderlichen Umgebungsvariablen konfiguriert sind.
+ **Fehlende Abhängigkeit vom STS-Modul:** Wenn der Fehler angezeigt wird`To use web identity tokens, the 'sts' service module must be on the class path`, müssen Sie das STS-Modul als Abhängigkeit hinzufügen. Dies ist häufig der Fall, wenn Amazon EKS Pod Identity oder eine andere Web-Identitätstoken-Authentifizierung verwendet wird.

  Lösung: Fügen Sie das STS-Modul zu Ihren Projektabhängigkeiten hinzu:
  + 

    ```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>sts</artifactId>
    </dependency>
    ```

    Für einige Dienste benötigen Sie möglicherweise auch die `aws-query-protocol` Abhängigkeit:

    ```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>aws-query-protocol</artifactId>
    </dependency>
    ```

#### Probleme mit der Netzwerk- oder Proxyverbindung
<a name="faq-credentials-provider-chain-network-issues"></a>

Wenn Sie `Connection refused` Fehler in der Anmeldeinformationsanbieterkette feststellen, deutet dies in der Regel auf Netzwerkverbindungsprobleme hin, wenn das SDK versucht, AWS Endpunkte zu erreichen.

**Lösungen:**
+ Überprüfen Sie die Proxykonfiguration, wenn Sie einen Proxyserver verwenden
+ Vergewissern Sie sich, dass Ihr Netzwerk ausgehende HTTPS-Verbindungen zu AWS Endpunkten zulässt
+ Aktivieren Sie die [Debug-Protokollierung, um detaillierte](logging-slf4j.md#sdk-debug-level-logging) Verbindungsversuche zu sehen
+ Testen Sie die Konnektivität mithilfe von Tools wie `curl` der Überprüfung des Netzwerkzugriffs auf AWS Endgeräte

# Verkürzen Sie die SDK-Startzeit für AWS Lambda
<a name="lambda-optimize-starttime"></a>

Eines der Ziele von AWS SDK for Java 2.x ist es, die Startlatenz für AWS Lambda Funktionen zu reduzieren. Das SDK enthält Änderungen zur Verkürzung der Startzeit, auf die am Ende dieses Themas eingegangen wird.

Dieses Thema konzentriert sich zunächst auf Änderungen, die Sie vornehmen können, um die Kaltstartzeiten zu verkürzen. Dazu gehören Änderungen an Ihrer Codestruktur und an der Konfiguration von Service-Clients.

## Verwenden Sie einen AWS CRT-basierten HTTP-Client
<a name="lambda-quick-url"></a>

Für die Arbeit mit AWS Lambda empfehlen wir die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtHttpClient.html)für synchrone Szenarien und die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/crt/AwsCrtAsyncHttpClient.html)für asynchrone Szenarien.

Das [AWS CRT-basierte HTTP-Clients konfigurieren](http-configuration-crt.md) Thema in diesem Handbuch beschreibt die Vorteile der Verwendung der HTTP-Clients, das Hinzufügen der Abhängigkeit und die Konfiguration ihrer Verwendung durch Service-Clients. 

## Entfernen Sie ungenutzte HTTP-Client-Abhängigkeiten
<a name="lambda-quick-remove-deps"></a>

Neben der expliziten Verwendung eines AWS CRT-basierten Clients können Sie auch andere HTTP-Clients entfernen, die das SDK standardmäßig bereitstellt. Die Lambda-Startzeit wird reduziert, wenn weniger Bibliotheken geladen werden müssen. Daher sollten Sie alle ungenutzten Artefakte entfernen, die die JVM laden muss.

Der folgende Ausschnitt aus einer `pom.xml` Maven-Datei zeigt den Ausschluss des Apache-basierten HTTP-Clients und des Netty-basierten HTTP-Clients. (Diese Clients werden nicht benötigt, wenn Sie einen CRT-basierten Client verwenden.) AWS In diesem Beispiel werden die HTTP-Client-Artefakte von der S3-Client-Abhängigkeit ausgeschlossen und das `aws-crt-client` Artefakt hinzugefügt, um den Zugriff auf die CRT-basierten HTTP-Clients zu ermöglichen. AWS 

```
<project>
    <properties>
        <aws.java.sdk.version>2.27.21</aws.java.sdk.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>aws-crt-client</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <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>
    </dependencies>
</project>
```

**Anmerkung**  
Fügen Sie das `<exclusions>` Element zu allen Service-Client-Abhängigkeiten in Ihrer Datei hinzu. `pom.xml`

## Konfigurieren Sie Service-Clients für Shortcut-Suchvorgänge
<a name="lambda-quick-clients"></a>

**Geben Sie eine Region an**  
Wenn Sie einen Service-Client erstellen, rufen Sie die `region` Methode im Service Client Builder auf. Dadurch wird der standardmäßige [Regions-Suchvorgang](region-selection.md#default-region-provider-chain) des SDK, der an mehreren Stellen nach AWS-Region Informationen sucht, verkürzt.  
Um den Lambda-Code unabhängig von der Region zu halten, verwenden Sie den folgenden Code innerhalb der `region` Methode. Dieser Code greift auf die vom Lambda-Container festgelegte `AWS_REGION` Umgebungsvariable zu.  

```
Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable()))
```

**Verwenden der `EnvironmentVariableCredentialProvider`**  
Ähnlich wie beim standardmäßigen Suchverhalten für die Regionsinformationen sucht das SDK an mehreren Stellen nach Anmeldeinformationen. Indem Sie [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/auth/credentials/EnvironmentVariableCredentialsProvider.html)bei der Erstellung eines Service-Clients angeben, sparen Sie Zeit bei der Suche nach Anmeldeinformationen durch das SDK.  
Durch die Verwendung dieses Anbieters für Anmeldeinformationen kann der Code in Lambda Funktionen verwendet werden, funktioniert aber möglicherweise nicht auf Amazon EC2 oder anderen Systemen.  
Wenn Sie [Lambda SnapStart für Java](#lambda-quick-snapstart) irgendwann verwenden möchten, sollten Sie sich bei der Suche nach Anmeldeinformationen auf die standardmäßige Anbieterkette für Anmeldeinformationen verlassen. Wenn Sie den angeben`EnvironmentVariableCredentialsProvider`, funktioniert die anfängliche Suche nach Anmeldeinformationen, aber wenn sie aktiviert SnapStart ist, [legt die Java-Runtime Umgebungsvariablen für Container-Anmeldeinformationen](https://docs.aws.amazon.com/lambda/latest/dg/snapstart-activate.html#snapstart-credentials) fest. Bei der Aktivierung sind die Umgebungsvariablen, die von den `EnvironmentVariableCredentialsProvider` Zugriffsschlüssel-Umgebungsvariablen verwendet werden, für das Java-SDK nicht verfügbar.

Der folgende Codeausschnitt zeigt einen S3-Serviceclient, der für die Verwendung in einer Lambda-Umgebung entsprechend konfiguriert ist.

```
S3Client s3Client = S3Client.builder()
    .region(Region.of(System.getenv(SdkSystemSetting.AWS_REGION.environmentVariable())))
    .credentialsProvider(EnvironmentVariableCredentialsProvider.create())
    .httpClient(AwsCrtHttpClient.builder().build())
    .build();
```

## Initialisieren Sie den SDK-Client außerhalb des Lambda-Funktionshandlers
<a name="lambda-quick-initialize"></a>

Wir empfehlen, einen SDK-Client außerhalb der Lambda-Handler-Methode zu initialisieren. Auf diese Weise kann die Initialisierung des Service-Clients übersprungen werden, wenn der Ausführungskontext wiederverwendet wird. Durch die Wiederverwendung der Client-Instanz und ihrer Verbindungen erfolgen nachfolgende Aufrufe der Handler-Methode schneller.

Im folgenden Beispiel wird die `S3Client` Instanz im Konstruktor mithilfe einer statischen Factory-Methode initialisiert. Wenn der Container, der von der Lambda-Umgebung verwaltet wird, wiederverwendet wird, wird die initialisierte `S3Client` Instanz wiederverwendet.

```
public class App implements RequestHandler<Object, Object> {
    private final S3Client s3Client;

    public App() {
        s3Client = DependencyFactory.s3Client();
    }

    @Override
    public Object handle Request(final Object input, final Context context) {
         ListBucketResponse response = s3Client.listBuckets();
         // Process the response.
    }
}
```

## Minimiert die Dependency-
<a name="lambda-quick-di"></a>

Bei Dependency Injection (DI) -Frameworks kann es länger dauern, bis der Einrichtungsvorgang abgeschlossen ist. Sie benötigen möglicherweise auch zusätzliche Abhängigkeiten, deren Laden einige Zeit in Anspruch nimmt.

Wenn ein DI-Framework benötigt wird, empfehlen wir die Verwendung leichter DI-Frameworks wie [Dagger](https://dagger.dev/dev-guide/).

## Verwenden Sie ein Targeting vom Typ Maven Archetype AWS Lambda
<a name="lambda-quick-maven"></a>

Das AWS Java SDK-Team hat eine [Maven-Archetype-Vorlage](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda) entwickelt, um ein Lambda-Projekt mit minimaler Startzeit zu booten. Sie können aus dem Archetyp ein Maven-Projekt aufbauen und wissen, dass die Abhängigkeiten für die Lambda-Umgebung geeignet konfiguriert sind. 

[In diesem Blogbeitrag finden Sie weitere Informationen über den Archetyp und eine Beispielbereitstellung.](https://aws.amazon.com/blogs/developer/bootstrapping-a-java-lambda-application-with-minimal-aws-java-sdk-startup-time-using-maven/)

## Ziehen Sie Lambda SnapStart für Java in Betracht
<a name="lambda-quick-snapstart"></a>

Wenn Ihre Laufzeitanforderungen kompatibel sind, AWS bietet [Lambda SnapStart für Java](https://docs.aws.amazon.com/lambda/latest/dg/snapstart.html) an. Lambda SnapStart ist eine infrastrukturbasierte Lösung, die die Startleistung von Java-Funktionen verbessert. Wenn Sie eine neue Version einer Funktion veröffentlichen, SnapStart initialisiert Lambda sie und erstellt einen unveränderlichen, verschlüsselten Snapshot des Speicher- und Festplattenstatus. SnapStart speichert den Snapshot dann zur Wiederverwendung im Cache.

## Änderungen an Version 2.x, die sich auf die Startzeit auswirken
<a name="example-client-configuration"></a>

Zusätzlich zu den Änderungen, die Sie an Ihrem Code vornehmen, enthält Version 2.x des SDK for Java drei Hauptänderungen, die die Startzeit reduzieren:
+ Verwendung von [jackson-jr](https://github.com/FasterXML/jackson-jr), einer Serialisierungsbibliothek, die die Initialisierungszeit verbessert
+ Verwendung der [java.time-Bibliotheken für Datums- und Uhrzeitobjekte](https://docs.oracle.com/javase/8/docs/api/index.html?java/time.html), die Teil des JDK sind
+ Verwendung von [Slf4j](https://www.slf4j.org/) für eine Holzfassade

## Weitere Ressourcen
<a name="lambda-quick-resources"></a>

Das AWS Lambda Entwicklerhandbuch enthält einen [Abschnitt über bewährte Methoden](https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html) für die Entwicklung von Lambda-Funktionen, der nicht Java-spezifisch ist.

Ein Beispiel für die Erstellung einer cloudnativen Anwendung in Java, die verwendet AWS Lambda, finden Sie in diesem [Workshop-Inhalt](https://github.com/aws-samples/aws-lambda-java-workshop). Im Workshop werden Leistungsoptimierung und andere bewährte Verfahren erörtert.

Sie können erwägen, statische Images zu verwenden, die im Voraus kompiliert wurden, um die Startlatenz zu reduzieren. Sie können beispielsweise das SDK for Java 2.x und Maven verwenden, um [ein natives GraalVM-Image zu erstellen](setup-project-graalvm.md).

# Implementieren `ContentStreamProvider` Sie in der AWS SDK for Java 2.x
<a name="content-stream-provider"></a>

`ContentStreamProvider`ist eine Abstraktion, die verwendet wird, um mehrere Lesevorgänge AWS SDK for Java 2.x von Eingabedaten zu ermöglichen. In diesem Thema wird erklärt, wie Sie A `ContentStreamProvider` korrekt für Ihre Anwendungen implementieren.

Das SDK for Java 2.x verwendet die `ContentStreamProvider#newStream()` Methode jedes Mal, wenn es einen ganzen Stream lesen muss. Damit dies für den gesamten Stream funktioniert, muss der zurückgegebene Stream immer am Anfang des Inhalts stehen und dieselben Daten enthalten. 

In den folgenden Abschnitten stellen wir drei Ansätze zur korrekten Implementierung dieses Verhaltens vor.

## Verwendung von `mark()` und `reset()`
<a name="csp-impl-mark-reset"></a>

Im folgenden Beispiel verwenden wir `mark(int)` im Konstruktor vor Beginn des Lesens, um sicherzustellen, dass wir den Stream wieder auf den Anfang zurücksetzen können. Bei jedem Aufruf von setzen `newStream()` wir den Stream zurück:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private InputStream contentStream;  
  
    public MyContentStreamProvider(InputStream contentStream) {  
        this.contentStream = contentStream;  
        this.contentStream.mark(MAX_LEN);  
    }  
  
    @Override  
    public InputStream newStream() {  
        contentStream.reset();  
        return contentStream;  
    }  
}
```

## Verwenden Sie die Pufferung, falls `mark()` und nicht verfügbar `reset()` sind
<a name="csp-impl-unsupported-streams"></a>

 Wenn Ihr Stream S&D nicht `reset()` direkt unterstützt`mark()`, können Sie trotzdem die zuvor gezeigte Lösung verwenden, indem Sie den Stream zunächst in ein`BufferedInputStream`:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private BufferedReader contentStream;  
  
    public MyContentStreamProvider(InputStream contentStream) {  
        this.contentStream = new BufferedInputStream(contentStream);  
        this.contentStream.mark(MAX_LEN);
    }  
  
    @Override  
    public InputStream newStream() {  
        contentStream.reset();  
        return contentStream;  
    }  
}
```

## Erstelle neue Streams
<a name="csp-impl-new-stream"></a>

Ein einfacherer Ansatz besteht darin, bei jedem Aufruf einfach einen neuen Stream zu Ihren Daten abzurufen und den vorherigen zu schließen:

```
public class MyContentStreamProvider implements ContentStreamProvider {  
    private InputStream contentStream;  
  
    @Override  
    public InputStream newStream() {  
        if (contentStream != null) {  
            contentStream.close();  
        }  
        contentStream = openStream();  
        return contentStream;  
    }  
}
```

# Legen Sie die JVM-TTL für DNS-Namenssuchen fest
<a name="jvm-ttl-dns"></a>

Die Java Virtual Machine (JVM) speichert DNS-Namensauflösungen zwischen. Wenn die JVM einen Hostnamen in eine IP-Adresse auflöst, speichert sie die IP-Adresse für einen bestimmten Zeitraum, der als (TTL) bezeichnet wird. *time-to-live*

Da AWS Ressourcen DNS-Namenseinträge verwenden, die sich gelegentlich ändern, empfehlen wir, dass Sie Ihre JVM mit einem TTL-Wert von 5 Sekunden konfigurieren. Auf diese Weise wird bei Änderung der IP-Adresse einer Ressource sichergestellt, dass Ihre Anwendung die neue IP-Adresse der Ressource durch erneute Abfrage des DNS abrufen und nutzen kann.

Bei einigen Java-Konfigurationen ist die JVM-Standard-TTL so festgelegt, dass DNS-Einträge *nie* aktualisiert werden, bis die JVM neu gestartet wird. Wenn sich also die IP-Adresse einer AWS Ressource ändert, während Ihre Anwendung noch läuft, kann sie diese Ressource erst verwenden, wenn Sie die JVM *manuell neu starten* und die zwischengespeicherten IP-Informationen aktualisiert werden. In diesem Fall ist es wichtig, die TTL der JVM so einzustellen, dass sie die zwischengespeicherten IP-Daten von Zeit zu Zeit aktualisiert.

## Wie legt man die JVM-TTL fest
<a name="how-to-set-the-jvm-ttl"></a>

Um die TTL der JVM zu ändern, legen Sie den Sicherheitseigenschaftswert [networkaddress.cache.ttl](https://docs.oracle.com/en/java/javase/17/core/java-networking.html#GUID-A680DADB-C4C1-40F1-B568-D9A97C917F5D) fest. Beachten Sie, dass `networkaddress.cache.ttl` es sich um eine *Sicherheitseigenschaft und nicht um eine Systemeigenschaft* handelt, d. h. sie kann nicht mit dem Befehlszeilen-Flag gesetzt werden. `-D`

### Option 1: Stellen Sie sie programmgesteuert in Ihrer Anwendung ein
<a name="set-ttl-programmatically"></a>

Rufen Sie [https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/Security.html](https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/security/Security.html)früh beim Start Ihrer Anwendung an, bevor AWS SDK-Clients erstellt werden und bevor Netzwerkanforderungen gestellt werden:

```
import java.security.Security;

public class MyApplication {
    public static void main(String[] args) {
        Security.setProperty("networkaddress.cache.ttl", "5");

        // ... create SDK clients and run application
    }
}
```

### Option 2: Legen Sie es in der Datei java.security fest
<a name="set-ttl-java-security-file"></a>

Legen Sie die `networkaddress.cache.ttl` Eigenschaft in der `$JAVA_HOME/jre/lib/security/java.security` Datei für Java 8 oder der `$JAVA_HOME/conf/security/java.security` Datei für Java 11 oder höher fest.

Das Folgende ist ein Ausschnitt aus einer `java.security` Datei, die zeigt, dass der TTL-Cache auf 5 Sekunden eingestellt ist.

```
#
# The Java-level namelookup cache policy for successful lookups:
#
# any negative value: caching forever
# any positive value: the number of seconds to cache an address for
# zero: do not cache
#
...
networkaddress.cache.ttl=5
...
```

Alle Anwendungen, die auf der durch die `$JAVA_HOME` Umgebungsvariable repräsentierten JVM ausgeführt werden, verwenden diese Einstellung.

### Option 3: Verwenden Sie das Fallback für JDK-Systemeigenschaften (Befehlszeile)
<a name="set-ttl-system-property"></a>

Wenn Sie die Sicherheitskonfiguration oder den Sicherheitscode nicht ändern können, können Sie die JDK-Systemeigenschaften verwenden. Diese dienen als Fallbacks, wenn keine Sicherheitseigenschaft definiert ist.
+ `sun.net.inetaddr.ttl`— Steuert erfolgreiche Suchvorgänge (positive TTL)
+ `sun.net.inetaddr.negative.ttl`— Steuert fehlgeschlagene Suchvorgänge (negative TTL)

```
java -Dsun.net.inetaddr.ttl=5 -Dsun.net.inetaddr.negative.ttl=1 -jar myapp.jar
```

**Anmerkung**  
Dies sind JDK-interne Eigenschaften, die in der [Oracle Java 8 Networking Properties](https://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html) Reference als private Eigenschaften dokumentiert sind und „in future Versionen möglicherweise nicht unterstützt werden“. Verwenden Sie nach Möglichkeit die Optionen 1—2.

# Arbeiten Sie mit HTTP/2 in der AWS SDK für Java
<a name="http2"></a>

HTTP/2 ist eine Hauptversion des HTTP-Protokolls. Diese neue Version verfügt über mehrere Erweiterungen, um die Leistung zu verbessern:
+ Binäre Datencodierung ermöglicht eine effizientere Datenübertragung.
+ Header-Komprimierung reduziert die vom Client heruntergeladenen Overhead-Bytes, sodass die Inhalte früher zum Client gelangen. Dies ist besonders bei mobilen Clients nützlich, bei denen die Bandbreite bereits eingeschränkt ist.
+ Die bidirektionale asynchrone Kommunikation (Multiplexing) ermöglicht die gleichzeitige Übertragung mehrerer Anfragen und AWS Antwortnachrichten zwischen dem Client über eine einzige Verbindung statt über mehrere Verbindungen, wodurch die Leistung verbessert wird.

Entwickler, die auf die neueste Version aktualisieren, verwenden SDKs automatisch HTTP/2, wenn es von dem Dienst, mit dem sie arbeiten, unterstützt wird. Neue Programmierschnittstellen nutzen nahtlos die Vorteile von HTTP/2 Funktionen und bieten neue Möglichkeiten zur Erstellung von Anwendungen.

Die Version AWS SDK für Java 2.x bietet neue Funktionen APIs für Event-Streaming, die das HTTP/2-Protokoll implementieren. Beispiele für die Verwendung dieser neuen Funktionen finden Sie APIs unter [Arbeiten mit Kinesis](examples-kinesis.md).