

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.

# Anruf AWS-Services vom AWS SDK for Java 2.x
<a name="work-with-services"></a>

Dieser Abschnitt enthält kurze Tutorials und Anleitungen für die Arbeit mit Select AWS-Services. Eine vollständige Reihe von Beispielen finden Sie im [Abschnitt Codebeispiele](java_code_examples.md).

**Topics**
+ [CloudWatch](examples-cloudwatch.md)
+ [AWS Datenbankdienste](examples-databases.md)
+ [DynamoDB](examples-dynamodb.md)
+ [Amazon EC2](examples-ec2.md)
+ [IAM](examples-iam.md)
+ [Kinesis](examples-kinesis.md)
+ [Lambda](examples-lambda.md)
+ [Amazon S3](examples-s3.md)
+ [Amazon SNS](examples-simple-notification-service.md)
+ [Amazon SQS](examples-sqs.md)
+ [Amazon Transcribe](examples-transcribe.md)

# Arbeite mit CloudWatch
<a name="examples-cloudwatch"></a>

Dieser Abschnitt enthält Beispiele für die Programmierung CloudWatch von [Amazon](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/WhatIsCloudWatch.html) mithilfe von AWS SDK für Java 2.x.

 Amazon CloudWatch überwacht Ihre Amazon Web Services (AWS) Ressourcen und die Anwendungen, auf denen Sie laufen, AWS in Echtzeit. Sie können CloudWatch damit Metriken sammeln und verfolgen. Dabei handelt es sich um Variablen, die Sie für Ihre Ressourcen und Anwendungen messen können. CloudWatch Alarme senden Benachrichtigungen oder nehmen auf der Grundlage von von Ihnen festgelegter Regeln automatisch Änderungen an den Ressourcen vor, die Sie überwachen.

Die folgenden Beispiele enthalten nur den Code, der zur Demonstration jeder Technik nötig ist. Der [vollständige Beispielcode ist verfügbar unter GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2). Von dort aus können Sie eine einzelne Quelldatei herunterladen oder das Repository klonen, um alle Beispiele lokal zu erstellen und auszuführen.

**Topics**
+ [Metriken abrufen von CloudWatch](examples-cloudwatch-get-metrics.md)
+ [Veröffentlichen Sie benutzerdefinierte Metrikdaten in CloudWatch](examples-cloudwatch-publish-custom-metrics.md)
+ [Mit CloudWatch Alarmen arbeiten](examples-cloudwatch-create-alarms.md)
+ [Verwenden Sie Amazon CloudWatch Events](examples-cloudwatch-send-events.md)

# Metriken abrufen von CloudWatch
<a name="examples-cloudwatch-get-metrics"></a>

## Auflisten von Metriken
<a name="listing-metrics"></a>

Um CloudWatch Metriken aufzulisten, erstellen Sie eine `listMetrics` Methode [ListMetricsRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/ListMetricsRequest.html)und rufen sie auf CloudWatchClient. Sie können `ListMetricsRequest` zum Filtern der zurückgegebenen Metriken nach Namespace, Metrikname oder Dimensionen verwenden.

**Anmerkung**  
Eine Liste der Metriken und Dimensionen, die von AWS Diensten veröffentlicht werden, finden Sie in der [Referenz zu Amazon CloudWatch Metriken und Dimensionen](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html) im Amazon CloudWatch Benutzerhandbuch.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import software.amazon.awssdk.services.cloudwatch.model.ListMetricsRequest;
import software.amazon.awssdk.services.cloudwatch.model.ListMetricsResponse;
import software.amazon.awssdk.services.cloudwatch.model.Metric;
```

 **Code** 

```
    public static void listMets( CloudWatchClient cw, String namespace) {

        boolean done = false;
        String nextToken = null;

        try {
            while(!done) {

                ListMetricsResponse response;

                if (nextToken == null) {
                   ListMetricsRequest request = ListMetricsRequest.builder()
                        .namespace(namespace)
                        .build();

                 response = cw.listMetrics(request);
                } else {
                  ListMetricsRequest request = ListMetricsRequest.builder()
                        .namespace(namespace)
                        .nextToken(nextToken)
                        .build();

                response = cw.listMetrics(request);
            }

            for (Metric metric : response.metrics()) {
                System.out.printf(
                        "Retrieved metric %s", metric.metricName());
                System.out.println();
            }

            if(response.nextToken() == null) {
                done = true;
            } else {
                nextToken = response.nextToken();
            }
        }

        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Die Metriken werden in a zurückgegeben, [ListMetricsResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/ListMetricsResponse.html)indem die zugehörige `getMetrics` Methode aufgerufen wird.

Eventuell werden die Ergebnisse *seitenweise* zurückgegeben. Um den nächsten Stapel Ergebnisse abzurufen, rufen Sie `nextToken` für das Antwortobjekt auf und verwenden den Tokenwert, um ein neues Anforderungsobjekt zu erstellen. Anschließend rufen Sie die `listMetrics`-Methode erneut für die neue Anforderung auf.

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

## Weitere Informationen
<a name="more-information"></a>
+  [ListMetrics](https://docs.aws.amazon.com//AmazonCloudWatch/latest/APIReference/API_ListMetrics.html)in der Amazon CloudWatch API-Referenz

# Veröffentlichen Sie benutzerdefinierte Metrikdaten in CloudWatch
<a name="examples-cloudwatch-publish-custom-metrics"></a>

Eine Reihe von AWS Diensten veröffentlichen [ihre eigenen Metriken](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html) in Namespaces, die mit "`AWS`" beginnen. Sie können benutzerdefinierte Metrikdaten auch in Ihrem eigenen Namespace veröffentlichen (sofern dieser nicht mit "" beginnt). `AWS`

## Veröffentlichen benutzerdefinierter Metrikdaten
<a name="cwid1"></a>

Um Ihre eigenen Metrikdaten zu veröffentlichen, rufen Sie die Methode CloudWatchClient's `putMetricData` mit einem auf. [PutMetricDataRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/PutMetricDataRequest.html) Die `PutMetricDataRequest` muss den benutzerdefinierten Namespace enthalten, der für die Daten verwendet werden soll, und Informationen über den Datenpunkt selbst in einem [MetricDatum](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/MetricDatum.html)Objekt.

**Anmerkung**  
Sie können keinen Namespace angeben, der mit "" `AWS` beginnt. Namespaces, die mit "`AWS`" beginnen, sind für die Verwendung durch Produkte reserviert. Amazon Web Services 

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.Dimension;
import software.amazon.awssdk.services.cloudwatch.model.MetricDatum;
import software.amazon.awssdk.services.cloudwatch.model.StandardUnit;
import software.amazon.awssdk.services.cloudwatch.model.PutMetricDataRequest;
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
```

 **Code** 

```
    public static void putMetData(CloudWatchClient cw, Double dataPoint ) {

        try {
            Dimension dimension = Dimension.builder()
                    .name("UNIQUE_PAGES")
                    .value("URLS")
                    .build();

            // Set an Instant object
            String time = ZonedDateTime.now( ZoneOffset.UTC ).format( DateTimeFormatter.ISO_INSTANT );
            Instant instant = Instant.parse(time);

            MetricDatum datum = MetricDatum.builder()
                .metricName("PAGES_VISITED")
                .unit(StandardUnit.NONE)
                .value(dataPoint)
                .timestamp(instant)
                .dimensions(dimension).build();

            PutMetricDataRequest request = PutMetricDataRequest.builder()
                .namespace("SITE/TRAFFIC")
                .metricData(datum).build();

            cw.putMetricData(request);

        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        System.out.printf("Successfully put data point %f", dataPoint);
     }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [Verwenden Sie Amazon CloudWatch Metriken](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/working_with_metrics.html) im Amazon CloudWatch Benutzerhandbuch.
+  [AWS Namespaces](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/aws-services-cloudwatch-metrics.html) im Amazon CloudWatch Benutzerhandbuch.
+  [PutMetricData](https://docs.aws.amazon.com//AmazonCloudWatch/latest/APIReference/API_PutMetricData.html)in der API-Referenz Amazon CloudWatch .

# Mit CloudWatch Alarmen arbeiten
<a name="examples-cloudwatch-create-alarms"></a>

## Alarm erstellen
<a name="create-an-alarm"></a>

Um einen Alarm auf der Grundlage einer CloudWatch Metrik zu erstellen, rufen Sie die CloudWatchClient `putMetricAlarm` Methode 'mit einer [PutMetricAlarmRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/PutMetricAlarmRequest.html)Angabe der Alarmbedingungen auf.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.Dimension;
import software.amazon.awssdk.services.cloudwatch.model.PutMetricAlarmRequest;
import software.amazon.awssdk.services.cloudwatch.model.ComparisonOperator;
import software.amazon.awssdk.services.cloudwatch.model.Statistic;
import software.amazon.awssdk.services.cloudwatch.model.StandardUnit;
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
```

 **Code** 

```
    public static void putMetricAlarm(CloudWatchClient cw, String alarmName, String instanceId) {

        try {
            Dimension dimension = Dimension.builder()
                .name("InstanceId")
                .value(instanceId).build();

            PutMetricAlarmRequest request = PutMetricAlarmRequest.builder()
                .alarmName(alarmName)
                .comparisonOperator(
                        ComparisonOperator.GREATER_THAN_THRESHOLD)
                .evaluationPeriods(1)
                .metricName("CPUUtilization")
                .namespace("AWS/EC2")
                .period(60)
                .statistic(Statistic.AVERAGE)
                .threshold(70.0)
                .actionsEnabled(false)
                .alarmDescription(
                        "Alarm when server CPU utilization exceeds 70%")
                .unit(StandardUnit.SECONDS)
                .dimensions(dimension)
                .build();

            cw.putMetricAlarm(request);
            System.out.printf(
                    "Successfully created alarm with name %s", alarmName);

        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Auflisten von Alarmen
<a name="list-alarms"></a>

Um die CloudWatch Alarme aufzulisten, die Sie erstellt haben, rufen Sie die `describeAlarms` Methode CloudWatchClient's mit einer auf [DescribeAlarmsRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/DescribeAlarmsRequest.html), mit der Sie Optionen für das Ergebnis festlegen können.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import software.amazon.awssdk.services.cloudwatch.model.DescribeAlarmsRequest;
import software.amazon.awssdk.services.cloudwatch.model.DescribeAlarmsResponse;
import software.amazon.awssdk.services.cloudwatch.model.MetricAlarm;
```

 **Code** 

```
    public static void desCWAlarms( CloudWatchClient cw) {

        try {

            boolean done = false;
            String newToken = null;

            while(!done) {
                DescribeAlarmsResponse response;

                if (newToken == null) {
                    DescribeAlarmsRequest request = DescribeAlarmsRequest.builder().build();
                    response = cw.describeAlarms(request);
                } else {
                    DescribeAlarmsRequest request = DescribeAlarmsRequest.builder()
                        .nextToken(newToken)
                        .build();
                    response = cw.describeAlarms(request);
                }

                for(MetricAlarm alarm : response.metricAlarms()) {
                    System.out.printf("\n Retrieved alarm %s", alarm.alarmName());
                }

                if(response.nextToken() == null) {
                    done = true;
                } else {
                    newToken = response.nextToken();
                }
            }

        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        System.out.printf("Done");
    }
```

Die Liste der Alarme kann abgerufen werden, indem Sie die `MetricAlarms` Funktion aufrufen [DescribeAlarmsResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/DescribeAlarmsResponse.html), die von zurückgegeben wird`describeAlarms`.

Eventuell werden die Ergebnisse *seitenweise* zurückgegeben. Um den nächsten Stapel Ergebnisse abzurufen, rufen Sie `nextToken` für das Antwortobjekt auf und verwenden den Tokenwert, um ein neues Anforderungsobjekt zu erstellen. Anschließend rufen Sie die `describeAlarms`-Methode erneut für die neue Anforderung auf.

**Anmerkung**  
Sie können auch Alarme für eine bestimmte Metrik abrufen, indem Sie die `describeAlarmsForMetric` Methode CloudWatchClient's verwenden. Sie lässt sich ähnlich wie `describeAlarms` nutzen.

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

## Löschen von Alarmen
<a name="delete-alarms"></a>

Um CloudWatch Alarme zu löschen, rufen Sie die `deleteAlarms` Methode CloudWatchClient s mit einem auf, das einen oder mehrere Namen von Alarmen [DeleteAlarmsRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/model/DeleteAlarmsRequest.html)enthält, die Sie löschen möchten.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.cloudwatch.CloudWatchClient;
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import software.amazon.awssdk.services.cloudwatch.model.DeleteAlarmsRequest;
```

 **Code** 

```
    public static void deleteCWAlarm(CloudWatchClient cw, String alarmName) {

        try {
            DeleteAlarmsRequest request = DeleteAlarmsRequest.builder()
                    .alarmNames(alarmName)
                    .build();

            cw.deleteAlarms(request);
            System.out.printf("Successfully deleted alarm %s", alarmName);

        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [Verwenden von Amazon CloudWatch Alarmen](https://docs.aws.amazon.com//AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html) im Amazon CloudWatch Benutzerhandbuch
+  [PutMetricAlarm](https://docs.aws.amazon.com//AmazonCloudWatch/latest/APIReference/API_PutMetricAlarm.html)in der Amazon CloudWatch API-Referenz
+  [DescribeAlarms](https://docs.aws.amazon.com//AmazonCloudWatch/latest/APIReference/API_DescribeAlarms.html)in der Amazon CloudWatch API-Referenz
+  [DeleteAlarms](https://docs.aws.amazon.com//AmazonCloudWatch/latest/APIReference/API_DeleteAlarms.html)in der Amazon CloudWatch API-Referenz

# Verwenden Sie Amazon CloudWatch Events
<a name="examples-cloudwatch-send-events"></a>

 CloudWatch Events liefert nahezu in Echtzeit einen Stream von Systemereignissen, die Änderungen an AWS Ressourcen an Amazon EC2 Instanzen, Lambda Funktionen, Kinesis Streams, Amazon ECS Aufgaben, Schrittfunktionen Zustandsmaschinen, Amazon SNS Themen, Amazon SQS Warteschlangen oder integrierten Zielen beschreiben. Sie können Ereignisse zuordnen und sie zu einer oder mehreren Zielfunktionen oder Streams umleiten, indem Sie einfache Regeln nutzen.

Amazon EventBridge ist die [Weiterentwicklung](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-cwe-now-eb.html) von CloudWatch Events. Beide Dienste verwenden dieselbe API, sodass Sie weiterhin den vom SDK bereitgestellten [CloudWatch Events-Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatch/CloudWatchClient.html) verwenden oder auf die [EventBridge Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/eventbridge/EventBridgeClient.html) for CloudWatch Events-Funktionalität des SDK für Java migrieren können. CloudWatch Die [Dokumentation zum Events-Benutzerhandbuch](https://docs.aws.amazon.com/eventbridge/latest/userguide/index.html) und die [API-Referenz](https://docs.aws.amazon.com/eventbridge/latest/APIReference/index.html) sind jetzt auf den EventBridge Dokumentationsseiten verfügbar.

## Hinzufügen von Ereignissen
<a name="add-events"></a>

Um benutzerdefinierte CloudWatch Ereignisse hinzuzufügen, rufen Sie die `CloudWatchEventsClient’s` `putEvents` Methode mit einem [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutEventsRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutEventsRequest.html)Objekt auf, das ein oder mehrere [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutEventsRequestEntry.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutEventsRequestEntry.html)Objekte enthält, die Details zu jedem Ereignis bereitstellen. Sie können mehrere Parameter für den Eintrag angeben, wie z. B. die Quelle und den Typ des Ereignisses, mit dem Ereignis verknüpfte Ressourcen usw.

**Anmerkung**  
Sie können maximal 10 Ereignisse pro Aufruf von `putEvents` angeben.

 **Importe** 

```
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient;
import software.amazon.awssdk.services.cloudwatchevents.model.PutEventsRequest;
import software.amazon.awssdk.services.cloudwatchevents.model.PutEventsRequestEntry;
```

 **Code** 

```
    public static void putCWEvents(CloudWatchEventsClient cwe, String resourceArn ) {

        try {

            final String EVENT_DETAILS =
                "{ \"key1\": \"value1\", \"key2\": \"value2\" }";

            PutEventsRequestEntry requestEntry = PutEventsRequestEntry.builder()
                    .detail(EVENT_DETAILS)
                    .detailType("sampleSubmitted")
                    .resources(resourceArn)
                    .source("aws-sdk-java-cloudwatch-example")
                    .build();

            PutEventsRequest request = PutEventsRequest.builder()
                    .entries(requestEntry)
                    .build();

            cwe.putEvents(request);
            System.out.println("Successfully put CloudWatch event");

        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/cloudwatch/src/main/java/com/example/cloudwatch/PutEvents.java) finden Sie unter GitHub.

## Hinzufügen von Regeln
<a name="add-rules"></a>

Um eine Regel zu erstellen oder zu aktualisieren, rufen Sie die `CloudWatchEventsClient’s` `putRule` Methode mit einem [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutRuleRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutRuleRequest.html)mit dem Namen der Regel und optionalen Parametern wie dem [Ereignismuster](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html), der IAM Rolle, die der Regel zugeordnet werden soll, und einem [Planungsausdruck](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html) auf, der beschreibt, wie oft die Regel ausgeführt wird.

 **Importe** 

```
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient;
import software.amazon.awssdk.services.cloudwatchevents.model.PutRuleRequest;
import software.amazon.awssdk.services.cloudwatchevents.model.PutRuleResponse;
import software.amazon.awssdk.services.cloudwatchevents.model.RuleState;
```

 **Code** 

```
    public static void putCWRule(CloudWatchEventsClient cwe, String ruleName, String roleArn) {

        try {
            PutRuleRequest request = PutRuleRequest.builder()
                .name(ruleName)
                .roleArn(roleArn)
                .scheduleExpression("rate(5 minutes)")
                .state(RuleState.ENABLED)
                .build();

            PutRuleResponse response = cwe.putRule(request);
            System.out.printf(
                    "Successfully created CloudWatch events rule %s with arn %s",
                    roleArn, response.ruleArn());
        } catch (
            CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/cloudwatch/src/main/java/com/example/cloudwatch/PutRule.java) finden Sie unter GitHub.

## Hinzufügen von Zielen
<a name="add-targets"></a>

Ziele sind die Ressourcen, die beim Auslösen einer Regel aufgerufen werden. Zu den Beispielzielen gehören Amazon EC2 Instanzen, Lambda Funktionen, Kinesis Streams, Amazon ECS Aufgaben, Schrittfunktionen Zustandsmaschinen und integrierte Ziele.

Um einer Regel ein Ziel hinzuzufügen, rufen Sie die `CloudWatchEventsClient’s` `putTargets` Methode mit einer auf, die die zu aktualisierende Regel und eine Liste von Zielen [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutTargetsRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/cloudwatchevents/model/PutTargetsRequest.html)enthält, die der Regel hinzugefügt werden sollen.

 **Importe** 

```
import software.amazon.awssdk.services.cloudwatch.model.CloudWatchException;
import software.amazon.awssdk.services.cloudwatchevents.CloudWatchEventsClient;
import software.amazon.awssdk.services.cloudwatchevents.model.PutTargetsRequest;
import software.amazon.awssdk.services.cloudwatchevents.model.PutTargetsResponse;
import software.amazon.awssdk.services.cloudwatchevents.model.Target;
```

 **Code** 

```
    public static void putCWTargets(CloudWatchEventsClient cwe, String ruleName, String functionArn, String targetId ) {

        try {
            Target target = Target.builder()
                .arn(functionArn)
                .id(targetId)
                .build();

            PutTargetsRequest request = PutTargetsRequest.builder()
                .targets(target)
                .rule(ruleName)
                .build();

            PutTargetsResponse response = cwe.putTargets(request);
            System.out.printf(
                "Successfully created CloudWatch events target for rule %s",
                ruleName);
        } catch (CloudWatchException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/cloudwatch/src/main/java/com/example/cloudwatch/PutTargets.java) finden Sie unter GitHub.

## Weitere Informationen
<a name="more-information"></a>
+  [Hinzufügen von Ereignissen mit PutEvents](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-putevents.html) im EventBridge Amazon-Benutzerhandbuch
+  [Ausdrücke für Regeln planen](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule-schedule.html#eb-create-scheduled-rule-schedule) im EventBridge Amazon-Benutzerhandbuch
+  [Ereignistypen für CloudWatch Events](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-service-event.html) im EventBridge Amazon-Benutzerhandbuch
+  [Ereignismuster](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-event-patterns.html) im EventBridge Amazon-Benutzerhandbuch
+  [PutEvents](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutEvents.html)in der Amazon EventBridge API-Referenz
+  [PutTargets](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutTargets.html)in der Amazon EventBridge API-Referenz
+  [PutRule](https://docs.aws.amazon.com/eventbridge/latest/APIReference/API_PutRule.html)in der Amazon EventBridge API-Referenz

# AWS Datenbankdienste und AWS SDK for Java 2.x
<a name="examples-databases"></a>

AWS [bietet verschiedene Datenbanktypen: relationale Datenbanken, Key-Value-Datenbanken, In-Memory-Datenbanken, Dokumentendatenbanken und viele andere.](https://aws.amazon.com/products/databases/) Die Unterstützung des SDK for Java 2.x variiert je nach Art des Datenbankdienstes in AWS.

Einige Datenbankdienste, z. B. der [Amazon DynamoDB DynamoDB-Dienst](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/Welcome.html), verfügen über einen Webservice APIs zur Verwaltung der AWS Ressource (Datenbank) sowie über einen Webservice APIs zur Interaktion mit den Daten. Im SDK for Java 2.x haben diese Arten von Diensten spezielle Service-Clients, zum Beispiel [Dynamo DBClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html).

Andere Datenbankdienste verfügen über Webdienste, APIs die mit der Ressource interagieren, z. B. die [Amazon DocumentDB DocumentDB-API](https://docs.aws.amazon.com/documentdb/latest/developerguide/api-reference.html) (für Cluster-, Instance- und Ressourcenmanagement), haben jedoch keine Webservice-API für die Arbeit mit den Daten. Das SDK for Java 2.x hat eine entsprechende [DocDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/docdb/DocDbClient.html)Schnittstelle für die Arbeit mit der Ressource. Sie benötigen jedoch eine andere Java-API, z. B. [MongoDB für Java](https://www.mongodb.com/developer/languages/java/), um mit den Daten arbeiten zu können.

Verwenden Sie die folgenden Beispiele, um zu erfahren, wie Sie das SDK for Java 2.x-Serviceclients mit den verschiedenen Datenbanktypen verwenden.

## Beispiele für Amazon DynamoDB
<a name="examples-db-dynamodb"></a>


| Mit den Daten arbeiten | Mit der Datenbank arbeiten | 
| --- |--- |
| SDK-Dienstclient: [DynamoDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html) | SDK-Dienstclient: [DynamoDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html) | 
| Beispiel: [React/Spring-REST-Anwendung](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/usecases/creating_dynamodb_web_app) mit DynamoDB | [Beispiele:,, CreateTable ListTables DeleteTable](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb) | 
| Beispiele: [Verschiedene DynamoDB-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb) |  | 
|  | 
| --- |
| SDK-Dienstclient: [DynamoDbEnhancedClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html) |  | 
| Beispiel: [React/Spring-REST-Anwendung](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/usecases/creating_dynamodb_web_app) mit DynamoDB |  | 
| Beispiele: [Verschiedene DynamoDB-Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb) (Namen, die mit „Enhanced“ beginnen) |  | 

[Weitere DynamoDB-Beispiele](examples-dynamodb.md) finden Sie im Abschnitt mit geführten Codebeispielen dieses Handbuchs.

## Beispiele für Amazon RDS
<a name="examples-db-rds"></a>


|  Mit den Daten arbeiten  |  Mit der Datenbank arbeiten  | 
| --- | --- | 
| API ohne SDK: JDBC, datenbankspezifische SQL-Variante; Ihr Code verwaltet Datenbankverbindungen oder einen Verbindungspool. | SDK-Dienstclient: [RdsClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/rds/RdsClient.html) | 
| Beispiel: [React/Spring REST-Anwendung](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/usecases/Creating_rds_item_tracker) mit MySQL | [Beispiele: Mehrere Beispiele RdsClient ](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/rds/src/main/java/com/example/rds) | 

## Beispiele für Amazon Redshift
<a name="examples-db-redshift"></a>


|  Mit den Daten arbeiten  |  Mit der Datenbank arbeiten  | 
| --- | --- | 
| SDK-Dienstclient: [RedshiftDataClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/redshiftdata/RedshiftDataClient.html) | SDK-Dienstclient: [RedshiftClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/redshift/RedshiftClient.html) | 
| Beispiele: [Verschiedene RedshiftDataClient Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/blob/c682a07a1e6abce793e3c32ef3b9661fa723d0ff/javav2/example_code/redshift/src/main/java/com/example/scenario/RedshiftScenario.java) | Beispiele: [Mehrere RedshiftClient Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/redshift/src/main/java/com/example/redshift) | 
| Beispiel: [React/Spring REST-Anwendung](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/usecases/CreatingSpringRedshiftRest) mit RedshiftDataClient |  | 

## Beispiele für Amazon Aurora Serverless v2
<a name="examples-db-aurora-sv1"></a>


|  Mit den Daten arbeiten  |  Mit der Datenbank arbeiten  | 
| --- | --- | 
| SDK-Dienstclient: [RdsDataClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/rdsdata/RdsDataClient.html) | SDK-Dienstclient: [RdsClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/rds/RdsClient.html) | 
| Beispiel: [React/Spring-REST-Anwendung](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/usecases/Creating_Spring_RDS_Rest) mit RdsDataClient | [Beispiele: Mehrere Beispiele RdsClient ](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/rds/src/main/java/com/example/rds) | 

## Beispiele für Amazon DocumentDB
<a name="examples-db-docdb"></a>


|  Mit den Daten arbeiten  |  Mit der Datenbank arbeiten  | 
| --- | --- | 
| Nicht-SDK-API: MongoDB-spezifische Java-Bibliothek (zum Beispiel [MongoDB für Java](https://www.mongodb.com/developer/languages/java/)); Ihr Code verwaltet Datenbankverbindungen oder einen Verbindungspool. | SDK-Dienstclient: [DocDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/docdb/DocDbClient.html) | 
| Beispiele: [DocumentDB (Mongo) Developer Guide](https://docs.aws.amazon.com/documentdb/latest/developerguide/connect_programmatically.html#connect_programmatically-tls_enabled) (wählen Sie die Registerkarte „Java“) |  | 

# Arbeite mit DynamoDB
<a name="examples-dynamodb"></a>

[DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) ist ein vollständig verwalteter NoSQL-Datenbankdienst, der schnelle und vorhersehbare Leistung mit nahtloser Skalierbarkeit bietet. In diesem Abschnitt erfahren Sie, wie Sie mit DynamoDB unter Verwendung von 2.x arbeiten. AWS SDK für Java 

## Wählen Sie Ihren DynamoDB-Client
<a name="ddb-clients-overview"></a>

Das SDK bietet zwei Hauptansätze für die Arbeit mit DynamoDB:

Low-Level-Client (`DynamoDbClient`)  
Bietet direkten Zugriff auf DynamoDB-Operationen mit voller Kontrolle über Anfragen und Antworten. Verwenden Sie diesen Client, wenn Sie eine detaillierte Steuerung benötigen oder mit dynamischen Schemas arbeiten möchten.

Verbesserter Client () `DynamoDbEnhancedClient`  
Bietet objektorientierte Programmierung mit automatischer Zuordnung zwischen Java-Objekten und DynamoDB-Elementen. Bietet außerdem dokumentenorientierte Funktionen für die Arbeit mit JSON-ähnlichen Daten, die keinem festen Schema folgen. Verwenden Sie diesen Client, wenn Sie mit klar definierten Datenmodellen oder dokumentartigen Daten arbeiten.

## DynamoDB-Clients konfigurieren
<a name="ddb-configuration-setup"></a>

Bevor Sie mit DynamoDB arbeiten, konfigurieren Sie Ihren Client für optimale Leistung und Zuverlässigkeit.

### Das Wiederholungsverhalten von DynamoDB verstehen
<a name="ddb-retry-behavior"></a>

DynamoDB-Clients verwenden standardmäßig eine maximale Anzahl von Wiederholungsversuchen von 8, was höher ist als bei anderen Clients. AWS-Service Diese höhere Anzahl an Wiederholungen hilft dabei, den verteilten Charakter von DynamoDB und die vorübergehenden Kapazitätsbeschränkungen zu bewältigen. Weitere Informationen zu Wiederholungsstrategien finden Sie unter. [Konfigurieren Sie das Wiederholungsverhalten in der AWS SDK for Java 2.x](retry-strategy.md)

### Optimieren Sie die Leistung mit kontobasierten Endpunkten
<a name="ddb-account-based-endpoints-v2"></a>

DynamoDB bietet [AWS kontobasierte Endpunkte](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Programming.SDKOverview.html#Programming.SDKs.endpoints), die die Leistung verbessern, indem sie Ihre AWS Konto-ID verwenden, um die Anforderungsweiterleitung zu optimieren. 

Um diese Funktion nutzen zu können, benötigen Sie Version 2.28.4 oder höher von. AWS SDK for Java 2.x Sie finden die neueste Version im zentralen [Maven-Repository](https://central.sonatype.com/artifact/software.amazon.awssdk/bom/versions). Unterstützte SDK-Versionen verwenden automatisch die neuen Endpunkte.

Wählen Sie eine der folgenden Optionen, um das kontobasierte Routing zu deaktivieren:
+ Konfigurieren Sie einen DynamoDB-Dienstclient mit der `AccountIdEndpointMode` Einstellung auf. `DISABLED`
+ Legen Sie eine Umgebungsvariable fest.
+ Legen Sie eine JVM-Systemeigenschaft fest.
+ Aktualisieren Sie die Einstellung für die gemeinsam genutzte AWS Konfigurationsdatei.

Das folgende Beispiel zeigt, wie Sie das kontobasierte Routing deaktivieren, indem Sie einen DynamoDB-Dienstclient konfigurieren:

```
DynamoDbClient.builder()
                 .accountIdEndpointMode(AccountIdEndpointMode.DISABLED)
                 .build();
```

Weitere Informationen zu den anderen Konfigurationsoptionen finden Sie unter [Account-based Endpoints](https://docs.aws.amazon.com/sdkref/latest/guide/feature-account-endpoints.html) im Referenzhandbuch und im Tools-Referenzhandbuch. AWS SDKs 

## Was wird in diesem Thema behandelt
<a name="ddb-topics-overview"></a>

In den folgenden Abschnitten erfahren Sie, wie Sie mit DynamoDB arbeiten:
+ [Arbeiten Sie mit Tabellen in DynamoDB](examples-dynamodb-tables.md)- Tabellen erstellen, beschreiben, aktualisieren und löschen
+ [Arbeiten Sie mit Artikeln in DynamoDB](examples-dynamodb-items.md)- Einzelne Elemente hinzufügen, abrufen und aktualisieren
+ [Ordnen Sie Java-Objekte DynamoDB-Elementen zu mit dem AWS SDK for Java 2.x](dynamodb-enhanced-client.md)- Verwenden Sie Objektzuordnungen und dokumentenorientierte Daten mit dem Enhanced Client

Weitere DynamoDB-Codebeispiele finden Sie unter [DynamoDB-Codebeispiele in der AWS Codebeispielbibliothek](java_dynamodb_code_examples.md).

# Arbeiten Sie mit Tabellen in DynamoDB
<a name="examples-dynamodb-tables"></a>

Tabellen sind die Container für alle Elemente in einer DynamoDB Datenbank. Bevor Sie Daten hinzufügen oder daraus entfernen können DynamoDB, müssen Sie eine Tabelle erstellen.

Für jede Tabelle definieren Sie:
+ Ein *Tabellenname*, der für Ihr Konto und Ihre Region eindeutig ist.
+ Einen *Primärschlüssel,* für den jeder Wert eindeutig sein muss. Ihre Tabelle kann keine zwei Elemente mit demselben Primärschlüsselwert enthalten.

  Ein Primärschlüssel kann *einfach* sein, also aus einem Schlüssel mit einer einzigen Partition (HASH) bestehen, oder *zusammengesetzt*, also aus einer Partition und einem Sortierschlüssel (RANGE).

  Jedem Schlüsselwert ist ein *Datentyp* zugeordnet, der nach der [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ScalarAttributeType.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ScalarAttributeType.html)Klasse aufgezählt wird. Der Schlüsselwert kann binär (B), numerisch (n) oder eine Zeichenfolge (S) sein. Weitere Informationen finden Sie unter [Benennungsregeln und Datentypen](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) im Amazon DynamoDB Entwicklerhandbuch.
+  Der *bereitgestellte Durchsatz* gibt Werte an, die die Anzahl der reservierten Lese-Schreib-Kapazitätseinheiten für die Tabelle angeben.
**Anmerkung**  
Amazon DynamoDB Die [Preisgestaltung](https://aws.amazon.com/dynamodb/pricing/) basiert auf den bereitgestellten Durchsatzwerten, die Sie für Ihre Tabellen festlegen. Reservieren Sie daher nur so viel Kapazität, wie Sie für Ihre Tabelle voraussichtlich benötigen.

  Der bereitgestellte Durchsatz für eine Tabelle kann jederzeit geändert werden. So können Sie die Kapazität anpassen, wenn sich Ihre Anforderungen ändern.

## Erstellen einer Tabelle
<a name="dynamodb-create-table"></a>

Verwenden Sie die `DynamoDbClient’s` `createTable` Methode, um eine neue DynamoDB Tabelle zu erstellen. Sie müssen Tabellenattribute und ein Tabellenschema erstellen. Beide Komponenten fließen in den Primärschlüssel der Tabelle ein. Sie müssen auch anfänglich bereitgestellte Durchsatzwerte und einen Tabellennamen angeben.

**Anmerkung**  
Wenn eine Tabelle mit dem von Ihnen gewählten Namen bereits existiert, `[DynamoDbException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/DynamoDbException.html)` wird a ausgelöst.

### Erstellen einer Tabelle mit einem einfachen Primärschlüssel
<a name="dynamodb-create-table-simple"></a>

Dieser Code erstellt eine Tabelle mit einem Attribut, das den einfachen Primärschlüssel der Tabelle darstellt. Das Beispiel verwendet `[KeySchemaElement](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/KeySchemaElement.html)` Objekte `[AttributeDefinition](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/AttributeDefinition.html)` und für. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/CreateTableRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/CreateTableRequest.html)

 **Importe** 

```
import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
import software.amazon.awssdk.services.dynamodb.model.KeyType;
import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter;
```

 **Code** 

```
    public static String createTable(DynamoDbClient ddb, String tableName, String key) {

        DynamoDbWaiter dbWaiter = ddb.waiter();
        CreateTableRequest request = CreateTableRequest.builder()
                .attributeDefinitions(AttributeDefinition.builder()
                        .attributeName(key)
                        .attributeType(ScalarAttributeType.S)
                        .build())
                .keySchema(KeySchemaElement.builder()
                        .attributeName(key)
                        .keyType(KeyType.HASH)
                        .build())
                .provisionedThroughput(ProvisionedThroughput.builder()
                        .readCapacityUnits(new Long(10))
                        .writeCapacityUnits(new Long(10))
                        .build())
                .tableName(tableName)
                .build();

        String newTable ="";
        try {
            CreateTableResponse response = ddb.createTable(request);
            DescribeTableRequest tableRequest = DescribeTableRequest.builder()
                    .tableName(tableName)
                    .build();

            // Wait until the Amazon DynamoDB table is created
            WaiterResponse<DescribeTableResponse> waiterResponse =  dbWaiter.waitUntilTableExists(tableRequest);
            waiterResponse.matched().response().ifPresent(System.out::println);

            newTable = response.tableDescription().tableName();
            return newTable;

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
       return "";
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/CreateTable.java) finden Sie unter. GitHub

### Erstellen einer Tabelle mit einem zusammengesetzten Primärschlüssel
<a name="dynamodb-create-table-composite"></a>

Im folgenden Beispiel wird eine Tabelle mit zwei Attributen erstellt. Beide Attribute werden für den zusammengesetzten Primärschlüssel verwendet.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
import software.amazon.awssdk.services.dynamodb.model.CreateTableRequest;
import software.amazon.awssdk.services.dynamodb.model.CreateTableResponse;
import software.amazon.awssdk.services.dynamodb.model.KeySchemaElement;
import software.amazon.awssdk.services.dynamodb.model.KeyType;
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
import software.amazon.awssdk.services.dynamodb.model.ScalarAttributeType;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
```

 **Code** 

```
    public static String createTableComKey(DynamoDbClient ddb, String tableName) {
        CreateTableRequest request = CreateTableRequest.builder()
                .attributeDefinitions(
                        AttributeDefinition.builder()
                                .attributeName("Language")
                                .attributeType(ScalarAttributeType.S)
                                .build(),
                        AttributeDefinition.builder()
                                .attributeName("Greeting")
                                .attributeType(ScalarAttributeType.S)
                                .build())
                .keySchema(
                        KeySchemaElement.builder()
                                .attributeName("Language")
                                .keyType(KeyType.HASH)
                                .build(),
                        KeySchemaElement.builder()
                                .attributeName("Greeting")
                                .keyType(KeyType.RANGE)
                                .build())
                .provisionedThroughput(
                        ProvisionedThroughput.builder()
                                .readCapacityUnits(new Long(10))
                                .writeCapacityUnits(new Long(10)).build())
                .tableName(tableName)
                .build();

       String tableId = "";

       try {
            CreateTableResponse result = ddb.createTable(request);
            tableId = result.tableDescription().tableId();
            return tableId;
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
       return "";
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/CreateTableCompositeKey.java) finden Sie unter GitHub.

## Auflisten von Tabellen
<a name="dynamodb-list-tables"></a>

Sie können die Tabellen in einer bestimmten Region auflisten, indem Sie die `DynamoDbClient’s` `listTables` Methode aufrufen.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert, [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.ListTablesResponse;
import software.amazon.awssdk.services.dynamodb.model.ListTablesRequest;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import java.util.List;
```

 **Code** 

```
    public static void listAllTables(DynamoDbClient ddb){

        boolean moreTables = true;
        String lastName = null;

        while(moreTables) {
            try {
                ListTablesResponse response = null;
                if (lastName == null) {
                    ListTablesRequest request = ListTablesRequest.builder().build();
                    response = ddb.listTables(request);
                } else {
                    ListTablesRequest request = ListTablesRequest.builder()
                            .exclusiveStartTableName(lastName).build();
                    response = ddb.listTables(request);
                }

                List<String> tableNames = response.tableNames();

                if (tableNames.size() > 0) {
                    for (String curName : tableNames) {
                        System.out.format("* %s\n", curName);
                    }
                } else {
                    System.out.println("No tables found!");
                    System.exit(0);
                }

                lastName = response.lastEvaluatedTableName();
                if (lastName == null) {
                    moreTables = false;
                }
            } catch (DynamoDbException e) {
                System.err.println(e.getMessage());
                System.exit(1);
            }
        }
        System.out.println("\nDone!");
    }
```

Standardmäßig werden bis zu 100 Tabellen pro Aufruf zurückgegeben. Verwenden Sie diese `lastEvaluatedTableName` Option für das zurückgegebene [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ListTablesResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ListTablesResponse.html)Objekt, um die zuletzt ausgewertete Tabelle abzurufen. Mit diesem Wert können Sie die Auflistung nach dem zuletzt zurückgegebenen Wert der vorherigen Auflistung beginnen.

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/ListTables.java) finden Sie unter. GitHub

## Beschreiben (Abrufen von Informationen zu) einer Tabelle
<a name="dynamodb-describe-table"></a>

Verwenden Sie die `DynamoDbClient’s` `describeTable` Methode, um Informationen zu einer Tabelle abzurufen.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert, [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeDefinition;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableRequest;
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughputDescription;
import software.amazon.awssdk.services.dynamodb.model.TableDescription;
import java.util.List;
```

 **Code** 

```
    public static void describeDymamoDBTable(DynamoDbClient ddb,String tableName ) {

        DescribeTableRequest request = DescribeTableRequest.builder()
                .tableName(tableName)
                .build();

        try {
            TableDescription tableInfo =
                    ddb.describeTable(request).table();

            if (tableInfo != null) {
                System.out.format("Table name  : %s\n",
                        tableInfo.tableName());
                System.out.format("Table ARN   : %s\n",
                        tableInfo.tableArn());
                System.out.format("Status      : %s\n",
                        tableInfo.tableStatus());
                System.out.format("Item count  : %d\n",
                        tableInfo.itemCount().longValue());
                System.out.format("Size (bytes): %d\n",
                        tableInfo.tableSizeBytes().longValue());

                ProvisionedThroughputDescription throughputInfo =
                        tableInfo.provisionedThroughput();
                System.out.println("Throughput");
                System.out.format("  Read Capacity : %d\n",
                        throughputInfo.readCapacityUnits().longValue());
                System.out.format("  Write Capacity: %d\n",
                        throughputInfo.writeCapacityUnits().longValue());

                List<AttributeDefinition> attributes =
                        tableInfo.attributeDefinitions();
                System.out.println("Attributes");

                for (AttributeDefinition a : attributes) {
                    System.out.format("  %s (%s)\n",
                            a.attributeName(), a.attributeType());
                }
            }
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        System.out.println("\nDone!");
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/DescribeTable.java) finden Sie unter GitHub.

## Ändern (Aktualisieren) einer Tabelle
<a name="dynamodb-update-table"></a>

Sie können die bereitgestellten Durchsatzwerte Ihrer Tabelle jederzeit ändern, indem Sie die `DynamoDbClient’s` `updateTable` Methode aufrufen.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert, [ResourceNotFoundException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.ProvisionedThroughput;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.UpdateTableRequest;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
```

 **Code** 

```
    public static void updateDynamoDBTable(DynamoDbClient ddb,
                                           String tableName,
                                           Long readCapacity,
                                           Long writeCapacity) {

        System.out.format(
                "Updating %s with new provisioned throughput values\n",
                tableName);
        System.out.format("Read capacity : %d\n", readCapacity);
        System.out.format("Write capacity : %d\n", writeCapacity);

        ProvisionedThroughput tableThroughput = ProvisionedThroughput.builder()
                .readCapacityUnits(readCapacity)
                .writeCapacityUnits(writeCapacity)
                .build();

        UpdateTableRequest request = UpdateTableRequest.builder()
                .provisionedThroughput(tableThroughput)
                .tableName(tableName)
                .build();

        try {
            ddb.updateTable(request);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }

        System.out.println("Done!");
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/UpdateTable.java) finden Sie unter GitHub.

## Löschen einer Tabelle
<a name="dynamodb-delete-table"></a>

Um eine Tabelle zu löschen, rufen Sie `DynamoDbClient’s` `deleteTable` method auf und geben Sie den Namen der Tabelle ein.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert, [ResourceNotFoundException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.DeleteTableRequest;
```

 **Code** 

```
    public static void deleteDynamoDBTable(DynamoDbClient ddb, String tableName) {

        DeleteTableRequest request = DeleteTableRequest.builder()
                .tableName(tableName)
                .build();

        try {
            ddb.deleteTable(request);

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        System.out.println(tableName +" was successfully deleted!");
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/dynamodb/src/main/java/com/example/dynamodb/DeleteTable.java) finden Sie unter GitHub.

## Weitere Informationen
<a name="more-information"></a>
+  [Richtlinien für die Arbeit mit Tabellen finden](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html) Sie im Amazon DynamoDB Entwicklerhandbuch
+  [Arbeiten mit Tabellen finden Sie DynamoDB im](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/WorkingWithTables.html) Amazon DynamoDB Entwicklerhandbuch

# Arbeiten Sie mit Artikeln in DynamoDB
<a name="examples-dynamodb-items"></a>

*In DynamoDB ist ein Element eine Sammlung von *Attributen*, von denen jedes einen *Namen und einen Wert* hat.* Ein Attributwert kann eine Skalarfunktion, eine Gruppe oder ein Dokumenttyp sein. Weitere Informationen finden Sie unter [Benennungsregeln und Datentypen](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html) im Amazon DynamoDB Entwicklerhandbuch.

## Abrufen (get) eines Elements aus einer Tabelle
<a name="dynamodb-get-item"></a>

Rufen Sie die DynamoDbClient `getItem` Methode auf und übergeben Sie ihr ein [GetItemRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/GetItemRequest.html)Objekt mit dem Tabellennamen und dem Primärschlüsselwert des gewünschten Elements. Sie gibt ein [GetItemResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/GetItemResponse.html)Objekt mit allen Attributen für dieses Element zurück. Sie können einen oder mehrere [Projektionsausdrücke](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html) in der `GetItemRequest` angeben, um spezifische Attribute abzurufen.

Sie können die `item()` Methode des zurückgegebenen `GetItemResponse` Objekts verwenden, um eine [Map](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Map.html) von Schlüssel- (String) - und Wertpaaren ([AttributeValue](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/AttributeValue.html)) abzurufen, die dem Element zugeordnet sind.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
```

 **Code** 

```
    public static void getDynamoDBItem(DynamoDbClient ddb,String tableName,String key,String keyVal ) {

        HashMap<String,AttributeValue> keyToGet = new HashMap<String,AttributeValue>();

        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal).build());

        GetItemRequest request = GetItemRequest.builder()
                .key(keyToGet)
                .tableName(tableName)
                .build();

        try {
            Map<String,AttributeValue> returnedItem = ddb.getItem(request).item();

            if (returnedItem != null) {
                Set<String> keys = returnedItem.keySet();
                System.out.println("Amazon DynamoDB table attributes: \n");

                for (String key1 : keys) {
                    System.out.format("%s: %s\n", key1, returnedItem.get(key1).toString());
                }
            } else {
                System.out.format("No item found with the key %s!\n", key);
            }
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

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

## Abrufen eines Elements aus einer Tabelle mithilfe des asynchronen Clients (get)
<a name="id1ddb"></a>

Rufen Sie die `getItem` Methode von auf DynamoDbAsyncClient und übergeben Sie ihr ein [GetItemRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/GetItemRequest.html)Objekt mit dem Tabellennamen und dem Primärschlüsselwert des gewünschten Elements.

Sie können eine [Collection](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Collection.html)-Instance mit allen Attributen für dieses Element zurückgeben (siehe das folgende Beispiel).

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
```

 **Code** 

```
    public static void getItem(DynamoDbAsyncClient client, String tableName, String key,  String keyVal) {

        HashMap<String, AttributeValue> keyToGet =
                new HashMap<String, AttributeValue>();

        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal).build());

        try {

            // Create a GetItemRequest instance
            GetItemRequest request = GetItemRequest.builder()
                    .key(keyToGet)
                    .tableName(tableName)
                    .build();

            // Invoke the DynamoDbAsyncClient object's getItem
            java.util.Collection<AttributeValue> returnedItem = client.getItem(request).join().item().values();

            // Convert Set to Map
            Map<String, AttributeValue> map = returnedItem.stream().collect(Collectors.toMap(AttributeValue::s, s->s));
            Set<String> keys = map.keySet();
            for (String sinKey : keys) {
                System.out.format("%s: %s\n", sinKey, map.get(sinKey).toString());
            }

        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
```

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

## Hinzufügen eines neuen Elements in einer Tabelle
<a name="dynamodb-add-item"></a>

Erstellen Sie eine [Map](https://docs.oracle.com/javase/8/docs/api/index.html?java/util/Map.html) mit Schlüssel-Wert-Paaren, die die Attribute des Elements darstellen. Diese müssen Werte für die Primärschlüsselfelder der Tabelle enthalten. Wenn das Element mit dem Primärschlüssel bereits vorhanden ist, werden dessen Felder durch die Anforderung *aktualisiert*.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert, [ResourceNotFoundException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import java.util.HashMap;
```

 **Code** 

```
    public static void putItemInTable(DynamoDbClient ddb,
                                      String tableName,
                                      String key,
                                      String keyVal,
                                      String albumTitle,
                                      String albumTitleValue,
                                      String awards,
                                      String awardVal,
                                      String songTitle,
                                      String songTitleVal){

        HashMap<String,AttributeValue> itemValues = new HashMap<String,AttributeValue>();

        // Add all content to the table
        itemValues.put(key, AttributeValue.builder().s(keyVal).build());
        itemValues.put(songTitle, AttributeValue.builder().s(songTitleVal).build());
        itemValues.put(albumTitle, AttributeValue.builder().s(albumTitleValue).build());
        itemValues.put(awards, AttributeValue.builder().s(awardVal).build());

        PutItemRequest request = PutItemRequest.builder()
                .tableName(tableName)
                .item(itemValues)
                .build();

        try {
            ddb.putItem(request);
            System.out.println(tableName +" was successfully updated");

        } catch (ResourceNotFoundException e) {
            System.err.format("Error: The Amazon DynamoDB table \"%s\" can't be found.\n", tableName);
            System.err.println("Be sure that it exists and that you've typed its name correctly!");
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

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

## Aktualisieren eines vorhandenen Elements in einer Tabelle
<a name="dynamodb-update-item"></a>

Sie können ein Attribut für ein Element, das bereits in einer Tabelle vorhanden ist, aktualisieren, indem Sie die `updateItem`-Methode des DynamoDbClient aufrufen und einen Tabellennamen, Primärschlüsselwert und eine Zuordnung der Felder übergeben, die aktualisiert werden sollen.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert oder wenn das Element, das durch den von Ihnen übergebenen Primärschlüssel identifiziert wurde, nicht existiert, [ResourceNotFoundException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import software.amazon.awssdk.services.dynamodb.model.AttributeAction;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.AttributeValueUpdate;
import software.amazon.awssdk.services.dynamodb.model.ResourceNotFoundException;
import software.amazon.awssdk.services.dynamodb.model.UpdateItemRequest;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import java.util.HashMap;
```

 **Code** 

```
    public static void updateTableItem(DynamoDbClient ddb,
                                       String tableName,
                                       String key,
                                       String keyVal,
                                       String name,
                                       String updateVal){

        HashMap<String,AttributeValue> itemKey = new HashMap<String,AttributeValue>();

        itemKey.put(key, AttributeValue.builder().s(keyVal).build());

        HashMap<String,AttributeValueUpdate> updatedValues =
                new HashMap<String,AttributeValueUpdate>();

        // Update the column specified by name with updatedVal
        updatedValues.put(name, AttributeValueUpdate.builder()
                .value(AttributeValue.builder().s(updateVal).build())
                .action(AttributeAction.PUT)
                .build());

        UpdateItemRequest request = UpdateItemRequest.builder()
                .tableName(tableName)
                .key(itemKey)
                .attributeUpdates(updatedValues)
                .build();

        try {
            ddb.updateItem(request);
        } catch (ResourceNotFoundException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }

        System.out.println("Done!");
    }
```

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

## Löschen eines vorhandenen Elements aus einer Tabelle
<a name="dynamodb-delete-item"></a>

Sie können ein in einer Tabelle vorhandenes Element löschen, indem Sie die DynamoDbClient `deleteItem` Methode 'verwenden und einen Tabellennamen sowie den Primärschlüsselwert angeben.

**Anmerkung**  
Wenn die benannte Tabelle für Ihr Konto und Ihre Region nicht existiert oder wenn das Element, das durch den von Ihnen übergebenen Primärschlüssel identifiziert wurde, nicht existiert, [ResourceNotFoundException](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/ResourceNotFoundException.html)wird a ausgelöst.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest;
import software.amazon.awssdk.services.dynamodb.model.DynamoDbException;
import java.util.HashMap;
```

 **Code** 

```
  public static void deleteDynamoDBItem(DynamoDbClient ddb, String tableName, String key, String keyVal) {

        HashMap<String,AttributeValue> keyToGet =
                new HashMap<String,AttributeValue>();

        keyToGet.put(key, AttributeValue.builder()
                .s(keyVal)
                .build());

        DeleteItemRequest deleteReq = DeleteItemRequest.builder()
                .tableName(tableName)
                .key(keyToGet)
                .build();

        try {
            ddb.deleteItem(deleteReq);
        } catch (DynamoDbException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [Richtlinien für die Arbeit mit Elementen](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/best-practices.html) im Amazon DynamoDB Entwicklerhandbuch
+  [Arbeiten mit Elementen aus DynamoDB dem](https://docs.aws.amazon.com//amazondynamodb/latest/developerguide/WorkingWithItems.html) Amazon DynamoDB Entwicklerhandbuch

# Ordnen Sie Java-Objekte DynamoDB-Elementen zu mit dem AWS SDK for Java 2.x
<a name="dynamodb-enhanced-client"></a>

Die [DynamoDB Enhanced Client API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/package-summary.html) ist eine High-Level-Bibliothek, die der Nachfolger der `DynamoDBMapper` Klasse von im SDK for Java v1.x ist. Er bietet eine einfache Möglichkeit, clientseitige Klassen zu DynamoDB-Tabellen zuzuordnen. Sie definieren die Beziehungen zwischen Tabellen und ihren entsprechenden Datenklassen in Ihrem Code. Nach der Definition dieser Beziehungen können Sie verschiedene Operationen zum Erstellen, Lesen, Aktualisieren oder Löschen (Create, Read, Update, Delete, CRUD) für Tabellen oder Elemente in DynamoDB auf intuitive Weise ausführen.

Die DynamoDB Enhanced Client API umfasst auch die [Enhanced Document API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/package-summary.html), mit der Sie mit dokumentartigen Elementen arbeiten können, die keinem definierten Schema folgen. 

**Topics**
+ [Erste Schritte mit der DynamoDB Enhanced Client API](ddb-en-client-getting-started.md)
+ [Lernen Sie die Grundlagen der DynamoDB Enhanced Client API kennen](ddb-en-client-use.md)
+ [Verwenden Sie erweiterte Mapping-Funktionen](ddb-en-client-adv-features.md)
+ [Arbeiten Sie mit JSON-Dokumenten mit der Enhanced Document API für DynamoDB](ddb-en-client-doc-api.md)
+ [Verwenden Sie Erweiterungen, um DynamoDB Enhanced Client-Operationen anzupassen](ddb-en-client-extensions.md)
+ [Verwenden Sie die DynamoDB Enhanced Client API asynchron](ddb-en-client-async.md)
+ [Anmerkungen zu Datenklassen](ddb-en-client-anno-index.md)

# Erste Schritte mit der DynamoDB Enhanced Client API
<a name="ddb-en-client-getting-started"></a>

Das folgende Tutorial führt Sie in die Grundlagen ein, die Sie für die Arbeit mit der DynamoDB Enhanced Client API benötigen.

## Fügen Sie Abhängigkeiten hinzu
<a name="ddb-en-client-gs-dep"></a>

Um mit der Arbeit mit der DynamoDB Enhanced Client API in Ihrem Projekt zu beginnen, fügen Sie eine Abhängigkeit vom `dynamodb-enhanced` Maven-Artefakt hinzu. Dies wird in den folgenden Beispielen veranschaulicht. 

------
#### [ Maven ]

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

Suchen Sie im zentralen Maven-Repository nach der [neuesten Version](https://central.sonatype.com/artifact/software.amazon.awssdk/bom) und *<VERSION>* ersetzen Sie sie durch diesen Wert.

------
#### [ Gradle ]

```
repositories {
    mavenCentral()
}
dependencies {
    implementation(platform("software.amazon.awssdk:bom:<VERSION>"))
    implementation("software.amazon.awssdk:dynamodb-enhanced")
    ...
}
```

Suchen Sie im zentralen Maven-Repository nach der [neuesten Version](https://central.sonatype.com/artifact/software.amazon.awssdk/bom) und *<VERSION>* ersetzen Sie sie durch diesen Wert.

------

# Generieren Sie `TableSchema` aus einer Datenklasse eine
<a name="ddb-en-client-gs-tableschema"></a>

A `[TableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/TableSchema.html)` ermöglicht es dem erweiterten Client, DynamoDB-Attributwerte Ihren clientseitigen Klassen zuzuordnen. In diesem Tutorial erfahren Sie mehr über `TableSchema` s, die von einer statischen Datenklasse abgeleitet und mithilfe eines Builders aus Code generiert wurden.

## Verwenden Sie eine Datenklasse mit Anmerkungen
<a name="ddb-en-client-gs-tableschema-anno-bean"></a>

Das SDK for Java 2.x enthält eine [Reihe von Anmerkungen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/annotations/package-summary.html), die Sie mit einer Datenklasse verwenden können, um schnell eine `TableSchema` für die Zuordnung Ihrer Klassen zu Tabellen zu generieren.

[Erstellen Sie zunächst eine Datenklasse, die der Spezifikation entspricht. JavaBean ](https://download.oracle.com/otn-pub/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/beans.101.pdf) Die Spezifikation erfordert, dass eine Klasse einen öffentlichen Konstruktor ohne Argumente und Getter und Setter für jedes Attribut in der Klasse hat. Fügen Sie eine Anmerkung auf Klassenebene hinzu, um anzugeben, dass es sich bei der Datenklasse um eine handelt. `DynamoDbBean` Fügen Sie außerdem mindestens eine `DynamoDbPartitionKey` Anmerkung zum Getter- oder Setter-Wert für das Primärschlüsselattribut hinzu. 

Sie können [Anmerkungen auf Attributebene auf](ddb-en-client-anno-index.md) Getter oder Setter anwenden, aber nicht auf beide.

**Anmerkung**  
Der Begriff `property` wird normalerweise für einen Wert verwendet, der in a gekapselt ist. JavaBean In diesem Handbuch wird der Begriff jedoch `attribute` stattdessen verwendet, um mit der von DynamoDB verwendeten Terminologie konsistent zu sein.

Die folgende `Customer` Klasse zeigt Anmerkungen, die die Klassendefinition mit einer DynamoDB-Tabelle verknüpfen.

### `Customer`-Klasse
<a name="ddb-en-client-gs-tableschema-anno-bean-cust"></a>

```
package org.example.tests.model;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.time.Instant;

@DynamoDbBean
public class Customer {

    private String id;
    private String name;
    private String email;
    private Instant regDate;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }

    public void setId(String id) { this.id = id; }

    public String getCustName() { return this.name; }

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

    @DynamoDbSortKey
    public String getEmail() { return this.email; }

    public void setEmail(String email) { this.email = email; }

    public Instant getRegistrationDate() { return this.regDate; }

    public void setRegistrationDate(Instant registrationDate) { this.regDate = registrationDate; }

    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + ", email=" + email
                + ", regDate=" + regDate + "]";
    }
}
```

Nachdem Sie eine annotierte Datenklasse erstellt haben, verwenden Sie sie, um die zu erstellen`TableSchema`, wie im folgenden Codeausschnitt gezeigt.

```
static final TableSchema<Customer> customerTableSchema = TableSchema.fromBean(Customer.class);
```

A `TableSchema` ist so konzipiert, dass es statisch und unveränderlich ist. Sie können es normalerweise beim Laden der Klasse instanziieren.

Die statische `TableSchema.fromBean()` Factory-Methode untersucht die Bean, um die Zuordnung von Datenklassenattributen (Eigenschaften) zu und von DynamoDB-Attributen zu generieren.

Ein Beispiel für die Arbeit mit einem Datenmodell, das aus mehreren Datenklassen besteht, finden Sie in der `Person` Klasse im Abschnitt. [Arbeiten Sie mit Attributen wie Beans, Maps, Listen und Sets](ddb-en-client-adv-features-nested.md)

## Verwenden Sie einen Builder
<a name="ddb-en-client-gs-tableschema-builder"></a>

Sie können die Kosten für die Bean-Introspektion überspringen, wenn Sie das Tabellenschema im Code definieren. Wenn Sie das Schema codieren, muss Ihre Klasse weder den JavaBean Benennungsstandards entsprechen noch muss sie mit Anmerkungen versehen werden. Das folgende Beispiel verwendet einen Builder und entspricht dem `Customer` Klassenbeispiel, das Anmerkungen verwendet.

```
static final TableSchema<Customer> customerTableSchema =
                TableSchema.builder(Customer.class)
                        .newItemSupplier(Customer::new)
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(Customer::getId)
                                .setter(Customer::setId)
                                .tags(StaticAttributeTags.primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("email")
                                .getter(Customer::getEmail)
                                .setter(Customer::setEmail)
                                .tags(StaticAttributeTags.primarySortKey()))
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(Customer::getCustName)
                                .setter(Customer::setCustName))
                        .addAttribute(Instant.class, a -> a.name("registrationDate")
                                .getter(Customer::getRegistrationDate)
                                .setter(Customer::setRegistrationDate))
                        .build();
```

# Erstellen Sie einen erweiterten Client und `DynamoDbTable`
<a name="ddb-en-client-getting-started-dynamodbTable"></a>

## Erstellen Sie einen erweiterten Client
<a name="ddb-en-client-getting-started-dynamodbTable-eclient"></a>

Die [DynamoDbEnhancedClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html)Klasse oder ihr asynchrones Gegenstück, [DynamoDbEnhancedAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedAsyncClient.html), ist der Einstiegspunkt für die Arbeit mit der DynamoDB Enhanced Client API.

Der erweiterte Client benötigt einen Standard, um die Arbeit ausführen `[DynamoDbClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/DynamoDbClient.html)` zu können. Die API bietet zwei Möglichkeiten, eine `DynamoDbEnhancedClient` Instanz zu erstellen. Die erste Option, die im folgenden Ausschnitt gezeigt wird, erstellt einen Standard `DynamoDbClient` mit Standardeinstellungen, die aus den Konfigurationseinstellungen übernommen wurden.

```
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.create();
```

Wenn Sie den zugrunde liegenden Standardclient konfigurieren möchten, können Sie ihn der Builder-Methode des erweiterten Clients zur Verfügung stellen, wie im folgenden Codeausschnitt gezeigt.

```
// Configure an instance of the standard DynamoDbClient.
DynamoDbClient standardClient = DynamoDbClient.builder()
    .region(Region.US_EAST_1)
    .credentialsProvider(ProfileCredentialsProvider.create())
    .build();

// Use the configured standard client with the enhanced client.
DynamoDbEnhancedClient enhancedClient = DynamoDbEnhancedClient.builder()
    .dynamoDbClient(standardClient)
    .build();
```

## Erstellen einer `DynamoDbTable`-Instance
<a name="ddb-en-client-getting-started-dynamodbTable-table"></a>

Stellen Sie sich a [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)als die clientseitige Darstellung einer DynamoDB-Tabelle vor, die die von a bereitgestellte Zuordnungsfunktion verwendet. `TableSchema` Die `DynamoDbTable` Klasse stellt Methoden für CRUD-Operationen bereit, mit denen Sie mit einer einzelnen DynamoDB-Tabelle interagieren können.

`DynamoDbTable<T>`ist eine generische Klasse, die ein einzelnes Typargument akzeptiert, unabhängig davon, ob es sich um eine benutzerdefinierte Klasse handelt oder um eine, `EnhancedDocument` wenn mit dokumentartigen Elementen gearbeitet wird. Dieser Argumenttyp stellt die Beziehung zwischen der Klasse, die Sie verwenden, und der einzelnen DynamoDB-Tabelle her.

Verwenden Sie die `table()` Factory-Methode von`DynamoDbEnhancedClient`, um eine `DynamoDbTable` Instanz zu erstellen, wie im folgenden Codeausschnitt gezeigt.

```
static final DynamoDbTable<Customer> customerTable = 
        enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
```

`DynamoDbTable`Instanzen sind Kandidaten für Singletons, da sie unveränderlich sind und in Ihrer gesamten Anwendung verwendet werden können.

Ihr Code hat jetzt eine speicherinterne Darstellung einer DynamoDB-Tabelle, die mit Instanzen arbeiten kann. `Customer` Die tatsächliche DynamoDB-Tabelle ist möglicherweise vorhanden oder nicht. Wenn die angegebene Tabelle `Customer` bereits existiert, können Sie damit beginnen, CRUD-Operationen an ihr durchzuführen. Wenn sie nicht existiert, verwenden Sie die `DynamoDbTable` Instanz, um die Tabelle zu erstellen, wie im nächsten Abschnitt beschrieben.

# Erstellen Sie bei Bedarf eine DynamoDB-Tabelle
<a name="ddb-en-client-gs-ddbtable"></a>

Nachdem Sie eine `DynamoDbTable` Instanz erstellt haben, verwenden Sie sie, um eine *einmalige* Erstellung einer Tabelle in DynamoDB durchzuführen.

## Beispielcode für Tabelle erstellen
<a name="ddb-en-client-gs-ddbtable-createex"></a>

Im folgenden Beispiel wird eine DynamoDB-Tabelle erstellt, die auf der `Customer` Datenklasse basiert. 

In diesem Beispiel wird eine DynamoDB-Tabelle mit dem Namen erstellt, der mit dem Klassennamen `Customer` identisch ist, aber der Tabellenname kann auch ein anderer sein. Wie auch immer Sie die Tabelle benennen, Sie müssen diesen Namen in weiteren Anwendungen verwenden, um mit der Tabelle arbeiten zu können. Geben Sie der `table()` Methode diesen Namen jedes Mal, wenn Sie ein anderes `DynamoDbTable` Objekt erstellen, um mit der zugrunde liegenden DynamoDB-Tabelle zu arbeiten.

Mit dem an die `createTable` Methode übergebenen Java-Lambda-Parameter können Sie die Tabelle [anpassen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/CreateTableEnhancedRequest.Builder.html). `builder` In diesem Beispiel wird der [bereitgestellte Durchsatz konfiguriert](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.ProvisionedThroughput.Manual). Wenn Sie beim Erstellen einer Tabelle die Standardeinstellungen verwenden möchten, überspringen Sie den Builder, wie im folgenden Codeausschnitt gezeigt.

```
customerTable.createTable();
```

Wenn Standardeinstellungen verwendet werden, werden keine Werte für den bereitgestellten Durchsatz festgelegt. Stattdessen ist der Abrechnungsmodus für die Tabelle auf [On-Demand-Modus](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html#HowItWorks.OnDemand) eingestellt.

In dem Beispiel wird auch ein verwendet, `[DynamoDbWaiter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/waiters/DynamoDbWaiter.html)` bevor versucht wird, den in der Antwort erhaltenen Tabellennamen auszudrucken. Die Erstellung einer Tabelle dauert einige Zeit. Wenn Sie also einen Kellner verwenden, müssen Sie keine Logik schreiben, die den DynamoDB-Dienst abfragt, um festzustellen, ob die Tabelle existiert, bevor Sie die Tabelle verwenden.

### Importe
<a name="ddb-en-client-gs-ddbtable-imports"></a>

```
import com.example.dynamodb.Customer;
import software.amazon.awssdk.core.internal.waiters.ResponseOrException;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbEnhancedClient;
import software.amazon.awssdk.enhanced.dynamodb.DynamoDbTable;
import software.amazon.awssdk.enhanced.dynamodb.TableSchema;
import software.amazon.awssdk.enhanced.dynamodb.model.CreateTableEnhancedRequest;
import software.amazon.awssdk.services.dynamodb.model.DescribeTableResponse;
import software.amazon.awssdk.services.dynamodb.waiters.DynamoDbWaiter;
```

### Code
<a name="ddb-en-client-gs-ddbtable-code"></a>

```
 public static void createCustomerTable(DynamoDbTable<Customer> customerTable, DynamoDbClient standardClient) {
     // Create the DynamoDB table using the 'customerTable' DynamoDbTable instance.
     customerTable.createTable(builder -> builder
             .provisionedThroughput(b -> b
                     .readCapacityUnits(10L)
                     .writeCapacityUnits(10L)
                     .build())
     );
     // The DynamoDbClient instance (named 'standardClient') passed to the builder for the DynamoDbWaiter is the same instance
     // that was passed to the builder of the DynamoDbEnhancedClient instance that we created previously.
     // By using the same instance, it ensures that the same Region that was configured on the standard DynamoDbClient 
     // instance is used for other service clients that accept a DynamoDbClient during construction.
     try (DynamoDbWaiter waiter = DynamoDbWaiter.builder().client(standardClient).build()) { // DynamoDbWaiter is Autocloseable
         ResponseOrException<DescribeTableResponse> response = waiter
                 .waitUntilTableExists(builder -> builder.tableName("Customer").build())
                 .matched();
         DescribeTableResponse tableDescription = response.response().orElseThrow(
                 () -> new RuntimeException("Customer table was not created."));
         // The actual error can be inspected in response.exception()
         logger.info("Customer table was created.");
     }
 }
```

**Anmerkung**  
Die Attributnamen einer DynamoDB-Tabelle beginnen mit einem Kleinbuchstaben, wenn die Tabelle aus einer Datenklasse generiert wird. Wenn der Attributname der Tabelle mit einem Großbuchstaben beginnen soll, verwenden Sie die [`@DynamoDbAttribute(NAME)`Anmerkung](ddb-en-client-adv-features-inex-attr.md) und geben Sie den gewünschten Namen als Parameter an.

# Führen Sie Operationen aus
<a name="ddb-en-client-gs-use"></a>

Nachdem die Tabelle erstellt wurde, verwenden Sie die `DynamoDbTable` Instanz, um Operationen mit der DynamoDB-Tabelle durchzuführen. 

Im folgenden Beispiel `DynamoDbTable<Customer>` wird ein Singleton als Parameter zusammen mit einer [`Customer`Datenklasseninstanz](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) übergeben, um der Tabelle ein neues Element hinzuzufügen.

```
    public static void putItemExample(DynamoDbTable<Customer> customerTable, Customer customer){
        logger.info(customer.toString());
        customerTable.putItem(customer);
    }
```

## `Customer`-Objekt
<a name="perform_ops_create_customer_instatnce"></a>

```
        Customer customer = new Customer();
        customer.setId("1");
        customer.setCustName("Customer Name");
        customer.setEmail("customer@example.com");
        customer.setRegistrationDate(Instant.parse("2023-07-03T10:15:30.00Z"));
```

Bevor Sie das `customer` Objekt an den DynamoDB-Dienst senden, protokollieren Sie die Ausgabe der `toString()` Methode des Objekts, um sie mit dem zu vergleichen, was der erweiterte Client sendet.

```
Customer [id=1, name=Customer Name, email=customer@example.com, regDate=2023-07-03T10:15:30Z]
```

Die Protokollierung auf Wireebene zeigt die Nutzlast der generierten Anfrage. Der erweiterte Client generierte die Low-Level-Darstellung anhand der Datenklasse. Das `regDate` Attribut, ein `Instant` Typ in Java, wird als DynamoDB-Zeichenfolge dargestellt.

```
{
  "TableName": "Customer",
  "Item": {
    "registrationDate": {
      "S": "2023-07-03T10:15:30Z"
    },
    "id": {
      "S": "1"
    },
    "custName": {
      "S": "Customer Name"
    },
    "email": {
      "S": "customer@example.com"
    }
  }
}
```

# Arbeiten Sie mit einer vorhandenen Tabelle
<a name="ddb-en-client-gs-existingtable"></a>

Im vorherigen Abschnitt wurde gezeigt, wie eine DynamoDB-Tabelle erstellt wird, die mit einer Java-Datenklasse beginnt. Wenn Sie bereits über eine bestehende Tabelle verfügen und die Funktionen des erweiterten Clients nutzen möchten, können Sie eine Java-Datenklasse erstellen, die mit der Tabelle arbeitet. Sie müssen die DynamoDB-Tabelle untersuchen und der Datenklasse die erforderlichen Anmerkungen hinzufügen. 

Rufen Sie die Methode auf, bevor Sie mit einer vorhandenen Tabelle arbeiten. `DynamoDbEnhanced.table()` Dies wurde im vorherigen Beispiel mit der folgenden Anweisung durchgeführt.

```
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
```

Nachdem die `DynamoDbTable` Instanz zurückgegeben wurde, können Sie sofort mit der Arbeit an der zugrunde liegenden Tabelle beginnen. Sie müssen die Tabelle nicht neu erstellen, indem Sie die `DynamoDbTable.createTable()` Methode aufrufen.

Das folgende Beispiel veranschaulicht dies, indem sofort eine `Customer` Instanz aus der DynamoDB-Tabelle abgerufen wird.

```
DynamoDbTable<Customer> customerTable = enhancedClient.table("Customer", TableSchema.fromBean(Customer.class));
// The Customer table exists already and has an item with a primary key value of "1" and a sort key value of "customer@example.com".
customerTable.getItem(
        Key.builder().
                partitionValue("1").
                sortValue("customer@example.com").build());
```

**Wichtig**  
Der in der `table()` Methode verwendete Tabellenname muss mit dem vorhandenen DynamoDB-Tabellennamen übereinstimmen.

# Lernen Sie die Grundlagen der DynamoDB Enhanced Client API kennen
<a name="ddb-en-client-use"></a>

In diesem Thema werden die grundlegenden Funktionen der DynamoDB Enhanced Client API beschrieben und sie mit der [standardmäßigen DynamoDB-Client-API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/package-summary.html) verglichen.

Wenn Sie mit der DynamoDB Enhanced Client API noch nicht vertraut sind, empfehlen wir Ihnen, das [Einführungstutorial](ddb-en-client-getting-started.md) zu lesen, um sich mit den grundlegenden Klassen vertraut zu machen.

## DynamoDB-Elemente in Java
<a name="ddb-en-client-use-usecase"></a>

DynamoDB-Tabellen speichern Elemente. Abhängig von Ihrem Anwendungsfall können Elemente auf der Java-Seite die Form von statisch strukturierten Daten oder dynamisch erstellten Strukturen annehmen. 

Wenn Ihr Anwendungsfall Elemente mit einem konsistenten Satz von Attributen erfordert, verwenden Sie [annotierte Klassen](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean) oder verwenden Sie einen [Builder](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-builder), um die entsprechenden statisch typisierten Elemente zu generieren. `TableSchema` 

Wenn Sie Elemente speichern müssen, die aus unterschiedlichen Strukturen bestehen, können Sie alternativ eine erstellen. `DocumentTableSchema` `DocumentTableSchema`ist Teil der [Enhanced Document API](ddb-en-client-doc-api.md) und benötigt nur einen statisch typisierten Primärschlüssel und funktioniert mit `EnhancedDocument` Instanzen, die die Datenelemente enthalten. [Die Enhanced Document API wird in einem anderen Thema behandelt.](ddb-en-client-doc-api.md)

## Attributtypen für Datenmodellklassen
<a name="ddb-en-client-use-types"></a>

Obwohl DynamoDB im Vergleich zum Rich-Type-System [von Java eine geringe Anzahl von Attributtypen](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) unterstützt, bietet die DynamoDB Enhanced Client API Mechanismen zum Konvertieren von Mitgliedern einer Java-Klasse in und aus DynamoDB-Attributtypen.

Bei den Attributtypen (Eigenschaften) Ihrer Java-Datenklassen sollte es sich um Objekttypen und nicht um Primitive handeln. Verwenden Sie beispielsweise immer Datentypen `Long` und `Integer` Objekte, nicht `long` `int` Primitive.

[Standardmäßig unterstützt die DynamoDB Enhanced Client-API Attributkonverter für eine Vielzahl von Typen, wie [Integer [BigDecimal](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/BigDecimalAttributeConverter.html)](https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html), [String](https://docs.oracle.com/javase/8/docs/api/java/lang/String.html) und Instant.](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/InstantAsStringAttributeConverter.html) Die Liste wird in den [bekannten Implementierungsklassen der AttributeConverter Schnittstelle](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html) angezeigt. Die Liste enthält viele Typen und Sammlungen wie Karten, Listen und Sets.

Um die Daten für einen Attributtyp zu speichern, der standardmäßig nicht unterstützt wird oder nicht der JavaBean Konvention entspricht, können Sie eine benutzerdefinierte `AttributeConverter` Implementierung für die Konvertierung schreiben. Ein [Beispiel](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-example) finden Sie im Abschnitt zur Attributkonvertierung.

Um die Daten für einen Attributtyp zu speichern, dessen Klasse der Java-Beans-Spezifikation (oder einer [unveränderlichen Datenklasse](ddb-en-client-use-immut.md)) entspricht, können Sie zwei Ansätze wählen. 
+ Wenn Sie Zugriff auf die Quelldatei haben, können Sie die Klasse mit `@DynamoDbBean` (oder) annotieren. `@DynamoDbImmutable` Der Abschnitt, der verschachtelte Attribute behandelt, zeigt [Beispiele für](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-map-anno) die Verwendung von Klassen mit Anmerkungen.
+ Wenn Sie keinen Zugriff auf die Quelldatei der JavaBean Datenklasse für das Attribut haben (oder Sie die Quelldatei einer Klasse, auf die Sie Zugriff haben, nicht mit Anmerkungen versehen möchten), können Sie den Builder-Ansatz verwenden. Dadurch wird ein Tabellenschema erstellt, ohne die Schlüssel zu definieren. Anschließend können Sie dieses Tabellenschema in einem anderen Tabellenschema verschachteln, um die Zuordnung durchzuführen. Der Abschnitt mit verschachtelten Attributen enthält ein [Beispiel](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-map-builder), das die Verwendung verschachtelter Schemas zeigt.

### Null-Werte
<a name="ddb-en-client-use-types-nulls"></a>

Wenn Sie die `putItem` Methode verwenden, nimmt der erweiterte Client keine nullwertigen Attribute eines zugewiesenen Datenobjekts in die Anforderung an DynamoDB auf.

Das Standardverhalten des SDK für `updateItem` Anfragen entfernt Attribute aus dem Element in DynamoDB, die in dem Objekt, das Sie in der Methode einreichen, auf Null gesetzt sind. `updateItem` Wenn Sie beabsichtigen, einige Attributwerte zu aktualisieren und die anderen unverändert zu lassen, haben Sie zwei Möglichkeiten.
+ Rufen Sie das Element (mithilfe von`getItem`) ab, bevor Sie Änderungen an den Werten vornehmen. Mit diesem Ansatz übermittelt das SDK alle aktualisierten und alten Werte an DynamoDB.
+ Verwenden Sie entweder `[IgnoreNullsMode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/IgnoreNullsMode.html).SCALAR_ONLY` oder, `IgnoreNullsMode.MAPS_ONLY` wenn Sie die Anfrage erstellen, um das Element zu aktualisieren. Beide Modi ignorieren nullwertige Eigenschaften im Objekt, die skalare Attribute in DynamoDB darstellen. Das [Aktualisieren Sie Elemente, die komplexe Typen enthalten](ddb-en-client-adv-features-nested.md#ddb-en-client-adv-features-nested-updates) Thema in diesem Handbuch enthält weitere Informationen zu den `IgnoreNullsMode` Werten und zur Arbeit mit komplexen Typen.

Das folgende `ignoreNullsMode()` Beispiel zeigt die `updateItem()` Methode.

```
    public static void updateItemNullsExample() {
        Customer customer = new Customer();
        customer.setCustName("CustomerName");
        customer.setEmail("email");
        customer.setId("1");
        customer.setRegistrationDate(Instant.now());

        logger.info("Original customer: {}", customer);

        // Put item with values for all attributes.
        try {
            customerAsyncDynamoDbTable.putItem(customer).join();
        } catch (RuntimeException rte) {
            logger.error("A exception occurred during putItem: {}", rte.getCause().getMessage(), rte);
            return;
        }

        // Create a Customer instance with the same 'id' and 'email' values, but a different 'name' value.
        // Do not set the 'registrationDate' attribute.
        Customer customerForUpdate = new Customer();
        customerForUpdate.setCustName("NewName");
        customerForUpdate.setEmail("email");
        customerForUpdate.setId("1");

        // Update item without setting the 'registrationDate' property and set IgnoreNullsMode to SCALAR_ONLY.
        try {
            Customer updatedWithNullsIgnored = customerAsyncDynamoDbTable.updateItem(b -> b
                            .item(customerForUpdate)
                            .ignoreNullsMode(IgnoreNullsMode.SCALAR_ONLY))
                    .join();
            logger.info("Customer updated with nulls ignored: {}", updatedWithNullsIgnored.toString());
        } catch (RuntimeException rte) {
            logger.error("An exception occurred during updateItem: {}", rte.getCause().getMessage(), rte);
            return;
        }

        // Update item without setting the registrationDate attribute and not setting ignoreNulls to true.
        try {
            Customer updatedWithNullsUsed = customerAsyncDynamoDbTable.updateItem(customerForUpdate)
                    .join();
            logger.info("Customer updated with nulls used: {}", updatedWithNullsUsed.toString());
        } catch (RuntimeException rte) {
            logger.error("An exception occurred during updateItem: {}", rte.getCause().getMessage(), rte);
        }
    }


// Logged lines. 
Original customer: Customer [id=1, name=CustomerName, email=email, regDate=2024-10-11T14:12:30.222858Z]
Customer updated with nulls ignored: Customer [id=1, name=NewName, email=email, regDate=2024-10-11T14:12:30.222858Z]
Customer updated with nulls used: Customer [id=1, name=NewName, email=email, regDate=null]
```

## Grundlegende Methoden des DynamoDB Enhanced Client
<a name="ddb-en-client-use-basic-ops"></a>

Die grundlegenden Methoden des erweiterten Clients sind den DynamoDB-Dienstoperationen zugeordnet, nach denen sie benannt sind. Die folgenden Beispiele zeigen die einfachste Variante der einzelnen Methoden. Sie können jede Methode anpassen, indem Sie ein erweitertes Anforderungsobjekt übergeben. Verbesserte Anforderungsobjekte bieten die meisten Funktionen, die im Standard-DynamoDB-Client verfügbar sind. Sie sind in der AWS SDK for Java 2.x API-Referenz vollständig dokumentiert.

Das Beispiel verwendet das zuvor [`Customer`-Klasse](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) Gezeigte.

```
// CreateTable
customerTable.createTable();

// GetItem
Customer customer = customerTable.getItem(Key.builder().partitionValue("a123").build());

// UpdateItem
Customer updatedCustomer = customerTable.updateItem(customer);

// PutItem
customerTable.putItem(customer);

// DeleteItem
Customer deletedCustomer = customerTable.deleteItem(Key.builder().partitionValue("a123").sortValue(456).build());

// Query
PageIterable<Customer> customers = customerTable.query(keyEqualTo(k -> k.partitionValue("a123")));

// Scan
PageIterable<Customer> customers = customerTable.scan();

// BatchGetItem
BatchGetResultPageIterable batchResults = 
    enhancedClient.batchGetItem(r -> r.addReadBatch(ReadBatch.builder(Customer.class)
                                      .mappedTableResource(customerTable)
                                      .addGetItem(key1)
                                      .addGetItem(key2)
                                      .addGetItem(key3)
                                      .build()));

// BatchWriteItem
batchResults = enhancedClient.batchWriteItem(r -> r.addWriteBatch(WriteBatch.builder(Customer.class)
                                                   .mappedTableResource(customerTable)
                                                   .addPutItem(customer)
                                                   .addDeleteItem(key1)
                                                   .addDeleteItem(key1)
                                                   .build()));

// TransactGetItems
transactResults = enhancedClient.transactGetItems(r -> r.addGetItem(customerTable, key1)
                                                        .addGetItem(customerTable, key2));

// TransactWriteItems
enhancedClient.transactWriteItems(r -> r.addConditionCheck(customerTable, 
                                                           i -> i.key(orderKey)
                                                                 .conditionExpression(conditionExpression))
                                        .addUpdateItem(customerTable, customer)
                                        .addDeleteItem(customerTable, key));
```

## DynamoDB Enhanced Client mit dem Standard-DynamoDB-Client vergleichen
<a name="ddb-en-client-use-compare"></a>

Sowohl der [standardmäßige](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/package-summary.html) als auch der [erweiterte](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/package-summary.html) DynamoDB-Client APIs ermöglichen es Ihnen, mit DynamoDB-Tabellen zu arbeiten, um CRUD-Operationen (Create, Read, Update and Delete) auf Datenebene durchzuführen. Der Unterschied zwischen den Clients besteht darin, wie dies erreicht wird. APIs Mit dem Standard-Client arbeiten Sie direkt mit Datenattributen auf niedriger Ebene. Die erweiterte Client-API verwendet vertraute Java-Klassen und ist der Low-Level-API im Hintergrund zugeordnet.

Während beide Clients Operationen auf Datenebene APIs unterstützen, unterstützt der standardmäßige DynamoDB-Client auch Operationen auf Ressourcenebene. Operationen auf Ressourcenebene verwalten die Datenbank, z. B. das Erstellen von Backups, das Auflisten von Tabellen und das Aktualisieren von Tabellen. Die erweiterte Client-API unterstützt eine bestimmte Anzahl von Vorgängen auf Ressourcenebene, z. B. das Erstellen, Beschreiben und Löschen von Tabellen.

Um die unterschiedlichen Ansätze der beiden Clients zu veranschaulichen APIs, zeigen die folgenden Codebeispiele die Erstellung derselben `ProductCatalog` Tabelle mit dem Standard-Client und dem erweiterten Client.

### Vergleichen: Erstellen Sie eine Tabelle mit dem standardmäßigen DynamoDB-Client
<a name="ddb-en-client-use-compare-cs1"></a>

```
DependencyFactory.dynamoDbClient().createTable(builder -> builder
        .tableName(TABLE_NAME)
        .attributeDefinitions(
                b -> b.attributeName("id").attributeType(ScalarAttributeType.N),
                b -> b.attributeName("title").attributeType(ScalarAttributeType.S),
                b -> b.attributeName("isbn").attributeType(ScalarAttributeType.S)
        )
        .keySchema(
                builder1 -> builder1.attributeName("id").keyType(KeyType.HASH),
                builder2 -> builder2.attributeName("title").keyType(KeyType.RANGE)
        )
        .globalSecondaryIndexes(builder3 -> builder3
                        .indexName("products_by_isbn")
                        .keySchema(builder2 -> builder2
                                .attributeName("isbn").keyType(KeyType.HASH))
                        .projection(builder2 -> builder2
                                .projectionType(ProjectionType.INCLUDE)
                                .nonKeyAttributes("price", "authors"))
                        .provisionedThroughput(builder4 -> builder4
                                .writeCapacityUnits(5L).readCapacityUnits(5L))
        )
        .provisionedThroughput(builder1 -> builder1
                .readCapacityUnits(5L).writeCapacityUnits(5L))
);
```

### Vergleichen: Erstellen Sie eine Tabelle mit dem DynamoDB Enhanced Client
<a name="ddb-en-client-use-compare-cs2"></a>

```
DynamoDbEnhancedClient enhancedClient = DependencyFactory.enhancedClient();
productCatalog = enhancedClient.table(TABLE_NAME, TableSchema.fromImmutableClass(ProductCatalog.class));
productCatalog.createTable(b -> b
        .provisionedThroughput(b1 -> b1.readCapacityUnits(5L).writeCapacityUnits(5L))
        .globalSecondaryIndices(b2 -> b2.indexName("products_by_isbn")
                .projection(b4 -> b4
                        .projectionType(ProjectionType.INCLUDE)
                        .nonKeyAttributes("price", "authors"))
                .provisionedThroughput(b3 -> b3.writeCapacityUnits(5L).readCapacityUnits(5L))
        )
);
```

Der erweiterte Client verwendet die folgende Datenklasse mit Anmerkungen. Der DynamoDB Enhanced Client ordnet Java-Datentypen DynamoDB-Datentypen zu und sorgt so für weniger ausführlichen Code, der leichter nachzuvollziehen ist. `ProductCatalog`ist ein Beispiel für die Verwendung einer unveränderlichen Klasse mit dem DynamoDB Enhanced Client. Die Verwendung unveränderlicher Klassen für zugeordnete Datenklassen wird später in diesem [Thema erörtert](ddb-en-client-use-immut.md).

### `ProductCatalog`-Klasse
<a name="ddb-en-client-use-compare-cs3"></a>

```
package org.example.tests.model;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbIgnore;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.math.BigDecimal;
import java.util.Objects;
import java.util.Set;

@DynamoDbImmutable(builder = ProductCatalog.Builder.class)
public class ProductCatalog implements Comparable<ProductCatalog> {
    private Integer id;
    private String title;
    private String isbn;
    private Set<String> authors;
    private BigDecimal price;


    private ProductCatalog(Builder builder){
        this.authors = builder.authors;
        this.id = builder.id;
        this.isbn = builder.isbn;
        this.price = builder.price;
        this.title = builder.title;
    }

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

    @DynamoDbPartitionKey
    public Integer id() { return id; }
    
    @DynamoDbSortKey
    public String title() { return title; }
    
    @DynamoDbSecondaryPartitionKey(indexNames = "products_by_isbn")
    public String isbn() { return isbn; }
    public Set<String> authors() { return authors; }
    public BigDecimal price() { return price; }


    public static final class Builder {
      private Integer id;
      private String title;
      private String isbn;
      private Set<String> authors;
      private BigDecimal price;
      private Builder(){}

      public Builder id(Integer id) { this.id = id; return this; }
      public Builder title(String title) { this.title = title; return this; }
      public Builder isbn(String ISBN) { this.isbn = ISBN; return this; }
      public Builder authors(Set<String> authors) { this.authors = authors; return this; }
      public Builder price(BigDecimal price) { this.price = price; return this; }
      public ProductCatalog build() { return new ProductCatalog(this); }
  }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("ProductCatalog{");
        sb.append("id=").append(id);
        sb.append(", title='").append(title).append('\'');
        sb.append(", isbn='").append(isbn).append('\'');
        sb.append(", authors=").append(authors);
        sb.append(", price=").append(price);
        sb.append('}');
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ProductCatalog that = (ProductCatalog) o;
        return id.equals(that.id) && title.equals(that.title) && Objects.equals(isbn, that.isbn) && Objects.equals(authors, that.authors) && Objects.equals(price, that.price);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, title, isbn, authors, price);
    }

    @Override
    @DynamoDbIgnore
    public int compareTo(ProductCatalog other) {
        if (this.id.compareTo(other.id) != 0){
            return this.id.compareTo(other.id);
        } else {
            return this.title.compareTo(other.title);
        }
    }
}
```

Die folgenden beiden Codebeispiele für Batch-Schreibvorgänge veranschaulichen die Ausführlichkeit und die mangelnde Typsicherheit bei der Verwendung des Standardclients im Gegensatz zum erweiterten Client.

### Vergleich: Batch-Schreiben mit dem standardmäßigen DynamoDB-Client
<a name="ddb-en-client-use-compare-cs4"></a>

```
    public static void batchWriteStandard(DynamoDbClient dynamoDbClient, String tableName) {

        Map<String, AttributeValue> catalogItem = Map.of(
                "authors", AttributeValue.builder().ss("a", "b").build(),
                "id", AttributeValue.builder().n("1").build(),
                "isbn", AttributeValue.builder().s("1-565-85698").build(),
                "title", AttributeValue.builder().s("Title 1").build(),
                "price", AttributeValue.builder().n("52.13").build());

        Map<String, AttributeValue> catalogItem2 = Map.of(
                "authors", AttributeValue.builder().ss("a", "b", "c").build(),
                "id", AttributeValue.builder().n("2").build(),
                "isbn", AttributeValue.builder().s("1-208-98073").build(),
                "title", AttributeValue.builder().s("Title 2").build(),
                "price", AttributeValue.builder().n("21.99").build());

        Map<String, AttributeValue> catalogItem3 = Map.of(
                "authors", AttributeValue.builder().ss("g", "k", "c").build(),
                "id", AttributeValue.builder().n("3").build(),
                "isbn", AttributeValue.builder().s("7-236-98618").build(),
                "title", AttributeValue.builder().s("Title 3").build(),
                "price", AttributeValue.builder().n("42.00").build());

        Set<WriteRequest> writeRequests = Set.of(
                WriteRequest.builder().putRequest(b -> b.item(catalogItem)).build(),
                WriteRequest.builder().putRequest(b -> b.item(catalogItem2)).build(),
                WriteRequest.builder().putRequest(b -> b.item(catalogItem3)).build());

        Map<String, Set<WriteRequest>> productCatalogItems = Map.of(
                "ProductCatalog", writeRequests);

        BatchWriteItemResponse response = dynamoDbClient.batchWriteItem(b -> b.requestItems(productCatalogItems));

        logger.info("Unprocessed items: " + response.unprocessedItems().size());
    }
```

### Vergleich: Batch-Schreiben mit dem DynamoDB Enhanced Client
<a name="ddb-en-client-use-compare-cs5"></a>

```
    public static void batchWriteEnhanced(DynamoDbTable<ProductCatalog> productCatalog) {
        ProductCatalog prod = ProductCatalog.builder()
                .id(1)
                .isbn("1-565-85698")
                .authors(new HashSet<>(Arrays.asList("a", "b")))
                .price(BigDecimal.valueOf(52.13))
                .title("Title 1")
                .build();
        ProductCatalog prod2 = ProductCatalog.builder()
                .id(2)
                .isbn("1-208-98073")
                .authors(new HashSet<>(Arrays.asList("a", "b", "c")))
                .price(BigDecimal.valueOf(21.99))
                .title("Title 2")
                .build();
        ProductCatalog prod3 = ProductCatalog.builder()
                .id(3)
                .isbn("7-236-98618")
                .authors(new HashSet<>(Arrays.asList("g", "k", "c")))
                .price(BigDecimal.valueOf(42.00))
                .title("Title 3")
                .build();

        BatchWriteResult batchWriteResult = DependencyFactory.enhancedClient()
                .batchWriteItem(b -> b.writeBatches(
                        WriteBatch.builder(ProductCatalog.class)
                                .mappedTableResource(productCatalog)
                                .addPutItem(prod).addPutItem(prod2).addPutItem(prod3)
                                .build()
                ));
        logger.info("Unprocessed items: " + batchWriteResult.unprocessedPutItemsForTable(productCatalog).size());
    }
```

# Arbeiten Sie mit unveränderlichen Datenklassen
<a name="ddb-en-client-use-immut"></a>

Die Mapping-Funktion der DynamoDB Enhanced Client API funktioniert mit unveränderlichen Datenklassen. Eine unveränderliche Klasse hat nur Getter und erfordert eine Builder-Klasse, die das SDK verwendet, um Instances der Klasse zu erstellen. Anstatt die `@DynamoDbBean` Annotation zu verwenden, wie in der [Customer-Klasse](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) gezeigt, verwenden unveränderliche Klassen die `@DynamoDbImmutable` Annotation, die einen Parameter verwendet, der angibt, welche Builder-Klasse verwendet werden soll.

Die folgende Klasse ist eine unveränderliche Version von. `Customer`

```
package org.example.tests.model.immutable;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbImmutable;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.time.Instant;

@DynamoDbImmutable(builder = CustomerImmutable.Builder.class)
public class CustomerImmutable {
    private final String id;
    private final String name;
    private final String email;
    private final Instant regDate;

    private CustomerImmutable(Builder b) {
        this.id = b.id;
        this.email = b.email;
        this.name = b.name;
        this.regDate = b.regDate;
    }

    // This method will be automatically discovered and used by the TableSchema.
    public static Builder builder() { return new Builder(); }

    @DynamoDbPartitionKey
    public String id() { return this.id; }

    @DynamoDbSortKey
    public String email() { return this.email; }

    @DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name")
    public String name() { return this.name; }

    @DynamoDbSecondarySortKey(indexNames = {"customers_by_date", "customers_by_name"})
    public Instant regDate() { return this.regDate; }

    public static final class Builder {
        private String id;
        private String email;
        private String name;
        private Instant regDate;

        // The private Builder constructor is visible to the enclosing CustomerImmutable class.
        private Builder() {}

        public Builder id(String id) { this.id = id; return this; }
        public Builder email(String email) { this.email = email; return this; }
        public Builder name(String name) { this.name = name; return this; }
        public Builder regDate(Instant regDate) { this.regDate = regDate; return this; }

        // This method will be automatically discovered and used by the TableSchema.
        public CustomerImmutable build() { return new CustomerImmutable(this); }
    }
}
```

Sie müssen die folgenden Anforderungen erfüllen, wenn Sie eine Datenklasse mit annotieren. `@DynamoDbImmutable`

1. Jede Methode, bei der es sich nicht um eine Überschreibung von handelt `Object.class` und die nicht mit einer Anmerkung versehen wurde, `@DynamoDbIgnore` muss ein Getter für ein Attribut der DynamoDB-Tabelle sein.

1. Jeder Getter muss einen entsprechenden Setter in der Builder-Klasse haben, bei der Groß- und Kleinschreibung berücksichtigt wird.

1. Nur eine der folgenden Konstruktionsbedingungen muss erfüllt sein.
   + Die Builder-Klasse muss über einen öffentlichen Standardkonstruktor verfügen.
   + Die Datenklasse muss eine öffentliche statische Methode mit dem Namen haben`builder()`, die keine Parameter akzeptiert und eine Instanz der Builder-Klasse zurückgibt. Diese Option wird in der unveränderlichen `Customer` Klasse angezeigt.

1.  Die Builder-Klasse muss eine öffentliche Methode mit dem Namen haben`build()`, die keine Parameter akzeptiert und eine Instanz der unveränderlichen Klasse zurückgibt. 

Um eine `TableSchema` für Ihre unveränderliche Klasse zu erstellen, verwenden Sie die `fromImmutableClass()` Methode on, `TableSchema` wie im folgenden Codeausschnitt gezeigt.

```
static final TableSchema<CustomerImmutable> customerImmutableTableSchema = 
                         TableSchema.fromImmutableClass(CustomerImmutable.class);
```

So wie Sie eine DynamoDB-Tabelle aus einer veränderbaren Klasse erstellen können, können Sie eine aus einer unveränderlichen Klasse mit einem *einmaligen* Aufruf von `createTable()` of erstellen, `DynamoDbTable` wie im folgenden Codefragmentbeispiel gezeigt.

```
static void createTableFromImmutable(DynamoDbEnhancedClient enhancedClient, String tableName, DynamoDbWaiter waiter){
    // First, create an in-memory representation of the table using the 'table()' method of the DynamoDb Enhanced Client.
    // 'table()' accepts a name for the table and a TableSchema instance that you created previously.
    DynamoDbTable<CustomerImmutable> customerDynamoDbTable = enhancedClient
            .table(tableName, TableSchema.fromImmutableClass(CustomerImmutable.class));
        
    // Second, call the 'createTable()' method on the DynamoDbTable instance.
    customerDynamoDbTable.createTable();
    waiter.waitUntilTableExists(b -> b.tableName(tableName));
}
```

## Verwenden Sie Bibliotheken von Drittanbietern wie Lombok
<a name="ddb-en-client-use-immut-lombok"></a>

Bibliotheken von Drittanbietern, wie [Project Lombok](https://projectlombok.org/), helfen dabei, Standardcode zu generieren, der unveränderlichen Objekten zugeordnet ist. Die DynamoDB Enhanced Client API funktioniert mit diesen Bibliotheken, solange die Datenklassen den in diesem Abschnitt beschriebenen Konventionen entsprechen. 

Das folgende Beispiel zeigt die unveränderliche `CustomerImmutable` Klasse mit Lombok-Anmerkungen. Beachten Sie, wie die `onMethod` Funktion von Lombok attributbasierte DynamoDB-Anmerkungen, wie z. B., in den generierten Code kopiert. `@DynamoDbPartitionKey`

```
@Value
@Builder
@DynamoDbImmutable(builder = Customer.CustomerBuilder.class)
public class Customer {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;

    @Getter(onMethod_=@DynamoDbSortKey)
    private String email;

    @Getter(onMethod_=@DynamoDbSecondaryPartitionKey(indexNames = "customers_by_name"))
    private String name;

    @Getter(onMethod_=@DynamoDbSecondarySortKey(indexNames = {"customers_by_date", "customers_by_name"}))
    private Instant createdDate;
}
```

# Verwenden Sie Ausdrücke und Bedingungen
<a name="ddb-en-client-expressions"></a>

Ausdrücke in der DynamoDB Enhanced Client API sind Java-Repräsentationen von [DynamoDB-Ausdrücken](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.html).

Die DynamoDB Enhanced Client API verwendet drei Arten von Ausdrücken:

[Expression](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Expression.html)  
Die `Expression` Klasse wird verwendet, wenn Sie Bedingungen und Filter definieren.

[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html)  
Dieser Ausdruckstyp stellt [wichtige Bedingungen](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.KeyConditionExpressions) für Abfrageoperationen dar.

[https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/update/UpdateExpression.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/update/UpdateExpression.html)  
Diese Klasse hilft Ihnen beim Schreiben von [DynamoDB-Aktualisierungsausdrücken](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html) und wird derzeit im Erweiterungs-Framework verwendet, wenn Sie ein Element aktualisieren.

## Anatomie des Ausdrucks
<a name="ddb-en-client-expressions-compoonents"></a>

Ein Ausdruck setzt sich wie folgt zusammen:
+ Ein Zeichenkettenausdruck (erforderlich). Die Zeichenfolge enthält einen DynamoDB-Logikausdruck mit Platzhalternamen für Attributnamen und Attributwerte.
+ Eine Zuordnung von Ausdruckswerten (normalerweise erforderlich).
+ Eine Zuordnung von Ausdrucksnamen (optional).

Verwenden Sie einen Builder, um ein `Expression` Objekt zu generieren, das die folgende allgemeine Form annimmt.

```
Expression expression = Expression.builder()
                            .expression(<String>)
                            .expressionNames(<Map>)
                            .expressionValues(<Map>)
                           .build()
```

`Expression`s erfordern normalerweise eine Zuordnung von Ausdruckswerten. Die Map stellt die Werte für die Platzhalter im Zeichenkettenausdruck bereit. Der Map-Schlüssel besteht aus dem Platzhalternamen, dem ein Doppelpunkt (`:`) vorangestellt ist, und der Zuordnungswert ist eine Instanz von. [AttributeValue](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/AttributeValue.html) Die [AttributeValues](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/AttributeValues.html)Klasse verfügt über praktische Methoden zum Generieren einer `AttributeValue` Instanz aus einem Literal. Alternativ können Sie die verwenden, `AttributeValue.Builder` um eine `AttributeValue` Instanz zu generieren.

Das folgende Snippet zeigt eine Map mit zwei Einträgen nach Kommentarzeile 2. Die an die `expression()` Methode übergebene Zeichenfolge, die nach Kommentarzeile 1 angezeigt wird, enthält die Platzhalter, die DynamoDB vor der Ausführung des Vorgangs auflöst. Dieser Ausschnitt enthält keine Zuordnung von Ausdrucksnamen, da *Preis* ein zulässiger Attributname ist.

```
    public static void scanAsync(DynamoDbAsyncTable productCatalog) {
        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .consistentRead(true)
                .attributesToProject("id", "title", "authors", "price")
                .filterExpression(Expression.builder()
                        // 1. :min_value and :max_value are placeholders for the values provided by the map
                        .expression("price >= :min_value AND price <= :max_value")
                        // 2. Two values are needed for the expression and each is supplied as a map entry.
                        .expressionValues(
                                Map.of( ":min_value", numberValue(8.00),
                                        ":max_value", numberValue(400_000.00)))
                        .build())
                .build();
```

Wenn ein Attributname in der DynamoDB-Tabelle ein reserviertes Wort ist, mit einer Zahl beginnt oder ein Leerzeichen enthält, ist eine Zuordnung von Ausdrucksnamen für erforderlich. `Expression`

Wenn der Attributname beispielsweise `1price` anstelle von `price` im vorherigen Codebeispiel verwendet wurde, müsste das Beispiel wie im folgenden Beispiel geändert werden.

```
        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .filterExpression(Expression.builder()
                        .expression("#price >= :min_value AND #price <= :max_value")
                        .expressionNames( Map.of("#price", "1price") )
                        .expressionValues(
                                Map.of(":min_value", numberValue(8.00),
                                        ":max_value", numberValue(400_000.00)))
                        .build())
                .build();
```

Ein Platzhalter für einen Ausdrucksnamen beginnt mit dem Rautenzeichen (`#`). Ein Eintrag für die Zuordnung von Ausdrucksnamen verwendet den Platzhalter als Schlüssel und den Attributnamen als Wert. Die Map wird dem Ausdrucks-Generator mit der `expressionNames()` Methode hinzugefügt. DynamoDB löst den Attributnamen auf, bevor es den Vorgang ausführt.

Ausdruckswerte sind nicht erforderlich, wenn eine Funktion im Zeichenkettenausdruck verwendet wird. Ein Beispiel für eine Ausdrucksfunktion ist`attribute_exists(<attribute_name>)`.

Im folgenden Beispiel wird eine erstellt`Expression`, die eine [DynamoDB-Funktion](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) verwendet. Die Ausdruckszeichenfolge in diesem Beispiel verwendet keine Platzhalter. Dieser Ausdruck könnte bei einer `putItem` Operation verwendet werden, um zu überprüfen, ob in der Datenbank bereits ein Element vorhanden ist, dessen Wert dem `movie` Attribut des Datenobjekts `movie` entspricht.

```
Expression exp = Expression.builder().expression("attribute_not_exists (movie)").build();
```

Das DynamoDB Developer Guide enthält vollständige Informationen zu den [Low-Level-Ausdrücken, die mit](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.html) DynamoDB verwendet werden.

## Bedingungsausdrücke und Bedingungen
<a name="ddb-en-client-expressions-cond"></a>

Wenn Sie die `deleteItem()` Methoden `putItem()``updateItem()`, und sowie Transaktions- und Batchoperationen verwenden, verwenden Sie `[Expression](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Expression.html)` Objekte, um Bedingungen anzugeben, die DynamoDB erfüllen muss, um mit dem Vorgang fortzufahren. Diese Ausdrücke sind benannte Bedingungsausdrücke. Ein Beispiel finden Sie in dem Bedingungsausdruck, der in der `addDeleteItem()` Methode (nach Kommentarzeile 1) des [Transaktionsbeispiels](ddb-en-client-use-multiop-trans.md#ddb-en-client-use-multiop-trans-writeitems-opcondition) in dieser Anleitung verwendet wurde.

Wenn Sie mit den `query()` Methoden arbeiten, wird eine Bedingung als ausgedrückt [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html). Die `QueryConditional` Klasse verfügt über mehrere statische praktische Methoden, mit deren Hilfe Sie die Kriterien schreiben können, die bestimmen, welche Elemente aus DynamoDB gelesen werden sollen.

Beispiele `QueryConditionals` dafür finden Sie im ersten Codebeispiel des [`Query`Beispiele für Methoden](ddb-en-client-use-multirecord.md#ddb-en-client-use-multirecord-query-example) Abschnitts dieses Handbuchs.

## Filterausdrücke
<a name="ddb-en-client-expressions-filter"></a>

Filterausdrücke werden bei Scan- und Abfragevorgängen verwendet, um die zurückgegebenen Elemente zu filtern. 

Ein Filterausdruck wird angewendet, nachdem alle Daten aus der Datenbank gelesen wurden, sodass die Lesekosten dieselben sind, als ob es keinen Filter gäbe. Im *Amazon DynamoDB Developer Guide* finden Sie weitere Informationen zur Verwendung von Filterausdrücken für [Abfrage](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html#Query.FilterExpression) - und [Scanvorgänge](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html#Scan.FilterExpression).

Das folgende Beispiel zeigt einen Filterausdruck, der einer Scananforderung hinzugefügt wurde. Die Kriterien beschränken die Anzahl der zurückgesendeten Artikel auf Artikel mit einem Preis zwischen 8,00 und einschließlich 80,00€.

```
        Map<String, AttributeValue> expressionValues = Map.of(
                ":min_value", numberValue(8.00),
                ":max_value", numberValue(80.00));

        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .consistentRead(true)
                // 1. the 'attributesToProject()' method allows you to specify which values you want returned.
                .attributesToProject("id", "title", "authors", "price")
                // 2. Filter expression limits the items returned that match the provided criteria.
                .filterExpression(Expression.builder()
                        .expression("price >= :min_value AND price <= :max_value")
                        .expressionValues(expressionValues)
                        .build())
                .build();
```

## Aktualisierungsausdrücke
<a name="ddb-en-client-expressions-update"></a>

Die Methode des DynamoDB Enhanced Client bietet eine `updateItem()` Standardmethode zum Aktualisieren von Elementen in DynamoDB. Wenn Sie jedoch mehr Funktionen benötigen, [UpdateExpressions](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/update/UpdateExpression.html)stellen Sie eine typsichere Darstellung der Syntax von [DynamoDB-Aktualisierungsausdrücken](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html) bereit. Sie können es beispielsweise verwenden, um Werte `UpdateExpressions` zu erhöhen, ohne zuerst Elemente aus DynamoDB zu lesen, oder um einzelne Mitglieder zu einer Liste hinzuzufügen. Aktualisierungsausdrücke sind derzeit in benutzerdefinierten Erweiterungen für die `updateItem()` Methode verfügbar.

Ein Beispiel, das Aktualisierungsausdrücke verwendet, finden Sie im [Beispiel für eine benutzerdefinierte Erweiterung](ddb-en-client-extensions-custom.md) in diesem Handbuch.

Weitere Informationen zu Aktualisierungsausdrücken finden Sie im [Amazon DynamoDB Developer Guide](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html).

# Arbeiten Sie mit paginierten Ergebnissen: Scans und Abfragen
<a name="ddb-en-client-use-multirecord"></a>

*Die `scan` `batch` Methoden `query` und der DynamoDB Enhanced Client API geben Antworten mit einer oder mehreren Seiten zurück.* Eine Seite enthält ein oder mehrere Elemente. Ihr Code kann die Antwort pro Seite oder einzelne Elemente verarbeiten.

Eine vom synchronen Client zurückgegebene paginierte Antwort gibt ein [PageIterable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/PageIterable.html)Objekt zurück, wohingegen eine vom asynchronen `DynamoDbEnhancedClient` `DynamoDbEnhancedAsyncClient` Client zurückgegebene Antwort ein Objekt zurückgibt. [PagePublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/PagePublisher.html)

Dieser Abschnitt befasst sich mit der Verarbeitung paginierter Ergebnisse und enthält Beispiele für die Verwendung von Scan und Abfrage. APIs

## Scannen einer Tabelle
<a name="ddb-en-client-use-multirecord-scan"></a>

Die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbAsyncTable.html#scan(java.util.function.Consumer)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbAsyncTable.html#scan(java.util.function.Consumer))Methode des SDK entspricht der gleichnamigen [DynamoDB-Operation](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html). Die DynamoDB Enhanced Client API bietet dieselben Optionen, verwendet jedoch ein vertrautes Objektmodell und übernimmt die Paginierung für Sie.

Zunächst untersuchen wir die `PageIterable` Schnittstelle, indem wir uns die `scan` Methode der synchronen Mapping-Klasse ansehen. [DynamoDbTable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)

### Verwenden Sie die synchrone API
<a name="ddb-en-client-use-multirecord-scan-sync"></a>

Das folgende Beispiel zeigt die `scan` Methode, die einen [Ausdruck](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Expression.html) verwendet, um die zurückgegebenen Elemente zu filtern. Das [ProductCatalog](ddb-en-client-use.md#ddb-en-client-use-compare-cs3)ist das Modellobjekt, das zuvor gezeigt wurde.

Der nach Kommentarzeile 2 angezeigte Filterausdruck beschränkt die Anzahl der zurückgegebenen `ProductCatalog` Artikel auf Artikel mit einem Preiswert zwischen 8,00 und 80,00 (einschließlich).

In diesem Beispiel werden auch die `isbn` Werte ausgeschlossen, indem die `attributesToProject` Methode verwendet wird, die nach Kommentarzeile 1 gezeigt wird.

Nach Kommentarzeile 3 wird das `PageIterable` Objekt,`pagedResults`, von der `scan` Methode zurückgegeben. Die `stream` Methode von `PageIterable` gibt ein [https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html)Objekt zurück, mit dem Sie die Seiten bearbeiten können. In diesem Beispiel wird die Anzahl der Seiten gezählt und protokolliert.

Beginnend mit Kommentarzeile 4 zeigt das Beispiel zwei Varianten des Zugriffs auf die `ProductCatalog` Elemente. Die Version nach der Kommentarzeile 4a durchläuft jede Seite und sortiert und protokolliert die Elemente auf jeder Seite. Die Version nach der Kommentarzeile 4b überspringt die Seiteniteration und greift direkt auf die Elemente zu.

Die `PageIterable` Schnittstelle bietet aufgrund ihrer beiden übergeordneten Schnittstellen — und — mehrere Möglichkeiten zur Verarbeitung von Ergebnissen. [https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html](https://docs.oracle.com/javase/8/docs/api/java/lang/Iterable.html) `Iterable`bringt `forEach` die `spliterator` Methoden `iterator` und und `SdkIterable` bringt die `stream` Methode.

```
    public static void scanSync(DynamoDbTable<ProductCatalog> productCatalog) {

        Map<String, AttributeValue> expressionValues = Map.of(
                ":min_value", numberValue(8.00),
                ":max_value", numberValue(80.00));

        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .consistentRead(true)
                // 1. the 'attributesToProject()' method allows you to specify which values you want returned.
                .attributesToProject("id", "title", "authors", "price")
                // 2. Filter expression limits the items returned that match the provided criteria.
                .filterExpression(Expression.builder()
                        .expression("price >= :min_value AND price <= :max_value")
                        .expressionValues(expressionValues)
                        .build())
                .build();

        // 3. A PageIterable object is returned by the scan method.
        PageIterable<ProductCatalog> pagedResults = productCatalog.scan(request);
        logger.info("page count: {}", pagedResults.stream().count());

        // 4. Log the returned ProductCatalog items using two variations.
        // 4a. This version sorts and logs the items of each page.
        pagedResults.stream().forEach(p -> p.items().stream()
                .sorted(Comparator.comparing(ProductCatalog::price))
                .forEach(
                        item -> logger.info(item.toString())
                ));
        // 4b. This version sorts and logs all items for all pages.
        pagedResults.items().stream()
                .sorted(Comparator.comparing(ProductCatalog::price))
                .forEach(
                        item -> logger.info(item.toString())
                );
    }
```

### Verwenden Sie die asynchrone API
<a name="ddb-en-client-use-multirecord-scan-async"></a>

Die asynchrone `scan` Methode gibt Ergebnisse als `PagePublisher` Objekt zurück. Die `PagePublisher` Schnittstelle verfügt über zwei `subscribe` Methoden, mit denen Sie Antwortseiten verarbeiten können. Eine `subscribe` Methode stammt von der `org.reactivestreams.Publisher` übergeordneten Schnittstelle. Um Seiten mit dieser ersten Option zu verarbeiten, übergeben Sie der `subscribe` Methode eine `[Subscriber](https://www.reactive-streams.org/reactive-streams-1.0.0-javadoc/org/reactivestreams/Subscriber.html)` Instanz. Das erste Beispiel, das folgt, zeigt die Verwendung der `subscribe` Methode.

Die zweite `subscribe` Methode stammt von der [SdkPublisher](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/SdkPublisher.html)Schnittstelle. Diese Version von `subscribe` akzeptiert [https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html](https://docs.oracle.com/javase/8/docs/api/java/util/function/Consumer.html)eher a als `Subscriber` a. Diese `subscribe` Methodenvariante wird im zweiten Beispiel gezeigt, das folgt.

Das folgende Beispiel zeigt die asynchrone Version der `scan` Methode, die denselben Filterausdruck wie im vorherigen Beispiel verwendet. 

Gibt nach Kommentarzeile 3 ein `PagePublisher` Objekt `DynamoDbAsyncTable.scan` zurück. In der nächsten Zeile erstellt der Code eine Instanz der `org.reactivestreams.Subscriber` Schnittstelle`ProductCatalogSubscriber`, die die vierte Zeile `PagePublisher` nach dem Kommentar abonniert.

Das `Subscriber` Objekt sammelt die `ProductCatalog` Elemente von jeder Seite in der `onNext` Methode nach der Kommentarzeile 8 im `ProductCatalogSubscriber` Klassenbeispiel. Die Elemente werden in der privaten `List` Variablen gespeichert und im aufrufenden Code mit der `ProductCatalogSubscriber.getSubscribedItems()` Methode aufgerufen. Dies wird nach Kommentarzeile 5 aufgerufen.

Nachdem die Liste abgerufen wurde, sortiert der Code alle `ProductCatalog` Artikel nach Preis und protokolliert jeden Artikel.

Die Klasse [CountDownLatch](https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html)in der `ProductCatalogSubscriber` Klasse blockiert den aufrufenden Thread, bis alle Elemente zur Liste hinzugefügt wurden, bevor sie nach Kommentarzeile 5 weitermacht. 

```
    public static void scanAsync(DynamoDbAsyncTable productCatalog) {
        ScanEnhancedRequest request = ScanEnhancedRequest.builder()
                .consistentRead(true)
                .attributesToProject("id", "title", "authors", "price")
                .filterExpression(Expression.builder()
                        // 1. :min_value and :max_value are placeholders for the values provided by the map
                        .expression("price >= :min_value AND price <= :max_value")
                        // 2. Two values are needed for the expression and each is supplied as a map entry.
                        .expressionValues(
                                Map.of( ":min_value", numberValue(8.00),
                                        ":max_value", numberValue(400_000.00)))
                        .build())
                .build();

        // 3. A PagePublisher object is returned by the scan method.
        PagePublisher<ProductCatalog> pagePublisher = productCatalog.scan(request);
        ProductCatalogSubscriber subscriber = new ProductCatalogSubscriber();
        // 4. Subscribe the ProductCatalogSubscriber to the PagePublisher.
        pagePublisher.subscribe(subscriber);
        // 5. Retrieve all collected ProductCatalog items accumulated by the subscriber.
        subscriber.getSubscribedItems().stream()
                .sorted(Comparator.comparing(ProductCatalog::price))
                .forEach(item ->
                        logger.info(item.toString()));
        // 6. Use a Consumer to work through each page.
        pagePublisher.subscribe(page -> page
                        .items().stream()
                        .sorted(Comparator.comparing(ProductCatalog::price))
                        .forEach(item ->
                                logger.info(item.toString())))
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
        // 7. Use a Consumer to work through each ProductCatalog item.
        pagePublisher.items()
                .subscribe(product -> logger.info(product.toString()))
                .exceptionally(failure -> {
                    logger.error("ERROR  - ", failure);
                    return null;
                })
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
    }
```

```
    private static class ProductCatalogSubscriber implements Subscriber<Page<ProductCatalog>> {
        private CountDownLatch latch = new CountDownLatch(1);
        private Subscription subscription;
        private List<ProductCatalog> itemsFromAllPages = new ArrayList<>();

        @Override
        public void onSubscribe(Subscription sub) {
            subscription = sub;
            subscription.request(1L);
            try {
                latch.await(); // Called by main thread blocking it until latch is released.
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void onNext(Page<ProductCatalog> productCatalogPage) {
            // 8. Collect all the ProductCatalog instances in the page, then ask the publisher for one more page.
            itemsFromAllPages.addAll(productCatalogPage.items());
            subscription.request(1L);
        }

        @Override
        public void onError(Throwable throwable) {
        }

        @Override
        public void onComplete() {
            latch.countDown(); // Call by subscription thread; latch releases.
        }

        List<ProductCatalog> getSubscribedItems() {
            return this.itemsFromAllPages;
        }
    }
```

Das folgende Codefragmentbeispiel verwendet die Version der `PagePublisher.subscribe` Methode, die eine Eingabe `Consumer` nach der Kommentarzeile 6 akzeptiert. Der Java-Lambda-Parameter verbraucht Seiten, die jedes Element weiterverarbeiten. In diesem Beispiel wird jede Seite verarbeitet und die Elemente auf jeder Seite werden sortiert und anschließend protokolliert.

```
        // 6. Use a Consumer to work through each page.
        pagePublisher.subscribe(page -> page
                        .items().stream()
                        .sorted(Comparator.comparing(ProductCatalog::price))
                        .forEach(item ->
                                logger.info(item.toString())))
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
```

Die `items` Methode `PagePublisher` entpackt die Modellinstanzen, sodass Ihr Code die Elemente direkt verarbeiten kann. Dieser Ansatz wird im folgenden Snippet gezeigt.

```
        // 7. Use a Consumer to work through each ProductCatalog item.
        pagePublisher.items()
                .subscribe(product -> logger.info(product.toString()))
                .exceptionally(failure -> {
                    logger.error("ERROR  - ", failure);
                    return null;
                })
                .join(); // If needed, blocks the subscribe() method thread until it is finished processing.
```

## Tabellen abfragen
<a name="ddb-en-client-use-multirecord-query"></a>

Sie können den DynamoDB Enhanced Client verwenden, um Ihre Tabelle abzufragen und mehrere Elemente abzurufen, die bestimmten Kriterien entsprechen. Die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html#query(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html#query(software.amazon.awssdk.enhanced.dynamodb.model.QueryEnhancedRequest))Methode findet Elemente auf der Grundlage von Primärschlüsselwerten anhand der `@DynamoDbPartitionKey` und optionaler `@DynamoDbSortKey` Anmerkungen, die in Ihrer Datenklasse definiert sind.

Die `query()` Methode erfordert einen Partitionsschlüsselwert und akzeptiert optional Sortierschlüsselbedingungen, um die Ergebnisse weiter zu verfeinern. Wie die `scan` API geben Abfragen a `PageIterable` für synchrone Aufrufe und a `PagePublisher` für asynchrone Aufrufe zurück.

### `Query`Beispiele für Methoden
<a name="ddb-en-client-use-multirecord-query-example"></a>

Das folgende `query()` Methodencodebeispiel verwendet die `MovieActor` Klasse. Die Datenklasse definiert einen zusammengesetzten Primärschlüssel, der aus dem **`movie`**Attribut als Partitionsschlüssel und dem **`actor`**Attribut als Sortierschlüssel besteht. 

#### `MovieActor`-Klasse
<a name="ddb-en-client-use-movieactor-class"></a>

```
package org.example.tests.model;

import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbAttribute;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.util.Objects;

@DynamoDbBean
public class MovieActor implements Comparable<MovieActor> {

    private String movieName;
    private String actorName;
    private String actingAward;
    private Integer actingYear;
    private String actingSchoolName;

    @DynamoDbPartitionKey
    @DynamoDbAttribute("movie")
    public String getMovieName() {
        return movieName;
    }

    public void setMovieName(String movieName) {
        this.movieName = movieName;
    }

    @DynamoDbSortKey
    @DynamoDbAttribute("actor")
    public String getActorName() {
        return actorName;
    }

    public void setActorName(String actorName) {
        this.actorName = actorName;
    }

    @DynamoDbSecondaryPartitionKey(indexNames = "acting_award_year")
    @DynamoDbAttribute("actingaward")
    public String getActingAward() {
        return actingAward;
    }

    public void setActingAward(String actingAward) {
        this.actingAward = actingAward;
    }

    @DynamoDbSecondarySortKey(indexNames = {"acting_award_year", "movie_year"})
    @DynamoDbAttribute("actingyear")
    public Integer getActingYear() {
        return actingYear;
    }

    public void setActingYear(Integer actingYear) {
        this.actingYear = actingYear;
    }

    @DynamoDbAttribute("actingschoolname")
    public String getActingSchoolName() {
        return actingSchoolName;
    }

    public void setActingSchoolName(String actingSchoolName) {
        this.actingSchoolName = actingSchoolName;
    }

    @Override
    public String toString() {
        final StringBuffer sb = new StringBuffer("MovieActor{");
        sb.append("movieName='").append(movieName).append('\'');
        sb.append(", actorName='").append(actorName).append('\'');
        sb.append(", actingAward='").append(actingAward).append('\'');
        sb.append(", actingYear=").append(actingYear);
        sb.append(", actingSchoolName='").append(actingSchoolName).append('\'');
        sb.append('}');
        return sb.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MovieActor that = (MovieActor) o;
        return Objects.equals(movieName, that.movieName) && Objects.equals(actorName, that.actorName) && Objects.equals(actingAward, that.actingAward) && Objects.equals(actingYear, that.actingYear) && Objects.equals(actingSchoolName, that.actingSchoolName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(movieName, actorName, actingAward, actingYear, actingSchoolName);
    }

    @Override
    public int compareTo(MovieActor o) {
        if (this.movieName.compareTo(o.movieName) != 0){
            return this.movieName.compareTo(o.movieName);
        } else {
            return this.actorName.compareTo(o.actorName);
        }
    }
}
```

In den folgenden Codebeispielen werden die folgenden Elemente abgefragt.

#### Elemente in der `MovieActor` Tabelle
<a name="ddb-en-client-use-movieactor-items"></a>

```
MovieActor{movieName='movie01', actorName='actor0', actingAward='actingaward0', actingYear=2001, actingSchoolName='null'}
MovieActor{movieName='movie01', actorName='actor1', actingAward='actingaward1', actingYear=2001, actingSchoolName='actingschool1'}
MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
MovieActor{movieName='movie01', actorName='actor3', actingAward='actingaward3', actingYear=2001, actingSchoolName='null'}
MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
MovieActor{movieName='movie02', actorName='actor0', actingAward='actingaward0', actingYear=2002, actingSchoolName='null'}
MovieActor{movieName='movie02', actorName='actor1', actingAward='actingaward1', actingYear=2002, actingSchoolName='actingschool1'}
MovieActor{movieName='movie02', actorName='actor2', actingAward='actingaward2', actingYear=2002, actingSchoolName='actingschool2'}
MovieActor{movieName='movie02', actorName='actor3', actingAward='actingaward3', actingYear=2002, actingSchoolName='null'}
MovieActor{movieName='movie02', actorName='actor4', actingAward='actingaward4', actingYear=2002, actingSchoolName='actingschool4'}
MovieActor{movieName='movie03', actorName='actor0', actingAward='actingaward0', actingYear=2003, actingSchoolName='null'}
MovieActor{movieName='movie03', actorName='actor1', actingAward='actingaward1', actingYear=2003, actingSchoolName='actingschool1'}
MovieActor{movieName='movie03', actorName='actor2', actingAward='actingaward2', actingYear=2003, actingSchoolName='actingschool2'}
MovieActor{movieName='movie03', actorName='actor3', actingAward='actingaward3', actingYear=2003, actingSchoolName='null'}
MovieActor{movieName='movie03', actorName='actor4', actingAward='actingaward4', actingYear=2003, actingSchoolName='actingschool4'}
```

Der folgende Code definiert zwei `QueryConditional` Instanzen: `keyEqual` (nach Kommentarzeile 1) und `sortGreaterThanOrEqualTo` (nach Kommentarzeile 1a).

#### Fragen Sie Elemente anhand des Partitionsschlüssels ab
<a name="keyEqual-query-conditional-example"></a>

Die `keyEqual` Instanz gleicht Elementen mit einem Partitionsschlüsselwert von ab **`movie01`**. 

In diesem Beispiel wird auch ein Filterausdruck nach Kommentarzeile 2 definiert, der alle Elemente herausfiltert, die keinen **`actingschoolname`**Wert haben.

Der `QueryEnhancedRequest` kombiniert die Schlüsselbedingung und den Filterausdruck für die Abfrage.

```
    public static void query(DynamoDbTable movieActorTable) {

        // 1. Define a QueryConditional instance to return items matching a partition value.
        QueryConditional keyEqual = QueryConditional.keyEqualTo(b -> b.partitionValue("movie01"));
        // 1a. Define a QueryConditional that adds a sort key criteria to the partition value criteria.
        QueryConditional sortGreaterThanOrEqualTo = QueryConditional.sortGreaterThanOrEqualTo(b -> b.partitionValue("movie01").sortValue("actor2"));
        // 2. Define a filter expression that filters out items whose attribute value is null.
        final Expression filterOutNoActingschoolname = Expression.builder().expression("attribute_exists(actingschoolname)").build();

        // 3. Build the query request.
        QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()
                .queryConditional(keyEqual)
                .filterExpression(filterOutNoActingschoolname)
                .build();
        // 4. Perform the query using the "keyEqual" conditional and filter expression.
        PageIterable<MovieActor> pagedResults = movieActorTable.query(tableQuery);
        logger.info("page count: {}", pagedResults.stream().count()); // Log  number of pages.

        pagedResults.items().stream()
                .sorted()
                .forEach(
                        item -> logger.info(item.toString()) // Log the sorted list of items.
                );
```

**Example — Ausgabe unter Verwendung der `keyEqual` Abfragebedingung**  
Das Folgende ist die Ausgabe der Ausführung der Methode. In der Ausgabe werden Elemente mit dem `movieName` Wert **movie01** und keine Elemente mit dem Wert `actingSchoolName` gleich angezeigt. **`null`**  

```
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:46 - page count: 1
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor1', actingAward='actingaward1', actingYear=2001, actingSchoolName='actingschool1'}
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
2023-03-05 13:11:05 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
```

#### Fragen Sie Elemente nach Partitionsschlüssel und Sortierschlüssel ab
<a name="sort-type-query-conditional-example"></a>

**Der `sortGreaterThanOrEqualTo` `QueryConditional` verfeinert die Übereinstimmung mit den Partitionsschlüsseln (**movie01**), indem eine Sortierschlüsselbedingung für Werte hinzugefügt wird, die größer oder gleich actor2 sind.**

[`QueryConditional`Methoden](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html), die mit beginnen, `sort` erfordern, dass ein Partitionsschlüsselwert übereinstimmt und die Abfrage durch einen Vergleich auf der Grundlage des Sortierschlüsselwerts weiter verfeinert wird. `Sort`bedeutet im Methodennamen nicht, dass die Ergebnisse sortiert sind, sondern dass ein Sortierschlüsselwert für den Vergleich verwendet wird.

Im folgenden Snippet ändern wir die Abfrageanfrage, die zuvor nach Kommentarzeile 3 angezeigt wurde. Dieses Snippet ersetzt die Abfragebedingung „keyEqual“ durch die Abfragebedingung "sortGreaterThanOrEqualTo", die nach der Kommentarzeile 1a definiert wurde. Der folgende Code entfernt auch den Filterausdruck.

```
        QueryEnhancedRequest tableQuery = QueryEnhancedRequest.builder()
                .queryConditional(sortGreaterThanOrEqualTo).build();
```

**Example — Ausgabe unter Verwendung der `sortGreaterThanOrEqualTo` Abfragebedingung**  
In der folgenden Ausgabe werden die Ergebnisse der Abfrage angezeigt. **Die Abfrage gibt Elemente zurück, deren `movieName` Wert **movie01** entspricht, und nur Elemente, deren `actorName` Wert größer oder gleich actor2 ist.** Da wir den Filter entfernen, gibt die Abfrage Elemente zurück, die keinen Wert für das Attribut haben. `actingSchoolName`  

```
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:46 - page count: 1
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor3', actingAward='actingaward3', actingYear=2001, actingSchoolName='null'}
2023-03-05 13:15:00 [main] INFO  org.example.tests.QueryDemo:51 - MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
```

# Führen Sie Batch-Operationen durch
<a name="ddb-en-client-use-multiop-batch"></a>

Die DynamoDB Enhanced Client API bietet zwei Batch-Methoden, [`batchGetItem`()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#batchGetItem(java.util.function.Consumer)) und [`batchWriteItem`(](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#batchWriteItem(java.util.function.Consumer))).

## `batchGetItem()`Beispiel für
<a name="ddb-en-client-use-multiop-batch-get"></a>

Mit [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#batchGetItem(java.util.function.Consumer)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#batchGetItem(java.util.function.Consumer))dieser Methode können Sie bis zu 100 einzelne Elemente aus mehreren Tabellen in einer Gesamtanforderung abrufen. Im folgenden Beispiel werden die zuvor gezeigten [`MovieActor`](ddb-en-client-use-multirecord.md#ddb-en-client-use-movieactor-class)Datenklassen [`Customer`](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust)und verwendet.

Im Beispiel nach den Zeilen 1 und 2 erstellen Sie `[ReadBatch](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/ReadBatch.html)` Objekte, die Sie später nach Kommentarzeile 3 als Parameter `batchGetItem()` zur Methode hinzufügen. 

Der Code nach der ersten Kommentarzeile erstellt den Batch, der aus der `Customer` Tabelle gelesen werden soll. Der Code nach der Kommentarzeile 1a zeigt die Verwendung eines `[GetItemEnhancedRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/GetItemEnhancedRequest.Builder.html)` Builders, der einen Primärschlüsselwert und einen Sortierschlüsselwert verwendet, um das zu lesende Element anzugeben. Wenn die Datenklasse über einen zusammengesetzten Schlüssel verfügt, müssen Sie sowohl den Partitionsschlüsselwert als auch den Sortierschlüsselwert angeben. 

Im Gegensatz zur Angabe von Schlüsselwerten für die Anforderung eines Elements können Sie eine Datenklasse verwenden, um ein Element anzufordern, wie nach Kommentarzeile 1b gezeigt. Das SDK extrahiert die Schlüsselwerte hinter den Kulissen, bevor die Anfrage gesendet wird.

[Wenn Sie das Element mithilfe des schlüsselbasierten Ansatzes angeben, wie in den beiden Anweisungen nach 2a gezeigt, können Sie auch angeben, dass DynamoDB einen stark konsistenten Lesevorgang durchführen soll.](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadConsistency.html) Wenn die `consistentRead()` Methode verwendet wird, muss sie für alle angeforderten Elemente für dieselbe Tabelle verwendet werden.

Verwenden Sie die `[resultsForTable() ](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/BatchGetResultPage.html#resultsForTable(software.amazon.awssdk.enhanced.dynamodb.MappedTableResource))` Methode, die nach Kommentarzeile 4 angezeigt wird, um die von DynamoDB gefundenen Elemente abzurufen. Rufen Sie die Methode für jede Tabelle auf, die in der Anforderung gelesen wurde. `resultsForTable()`gibt eine Liste der gefundenen Elemente zurück, die Sie mit einer beliebigen `java.util.List` Methode verarbeiten können. In diesem Beispiel wird jedes Element protokolliert.

Um Elemente zu finden, die DynamoDB nicht verarbeitet hat, verwenden Sie den Ansatz nach Kommentarzeile 5. Die `BatchGetResultPage` Klasse verfügt über die `[unprocessedKeysForTable()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/BatchGetResultPage.html#unprocessedKeysForTable(software.amazon.awssdk.enhanced.dynamodb.MappedTableResource))` Methode, mit der Sie auf jeden Schlüssel zugreifen können, der nicht verarbeitet wurde. Die [BatchGetItem API-Referenz](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html) enthält weitere Informationen zu Situationen, die zu unverarbeiteten Elementen führen.

```
    public static void batchGetItemExample(DynamoDbEnhancedClient enhancedClient,
                                           DynamoDbTable<Customer> customerTable,
                                           DynamoDbTable<MovieActor> movieActorTable) {

        Customer customer2 = new Customer();
        customer2.setId("2");
        customer2.setEmail("cust2@example.org");

        // 1. Build a batch to read from the Customer table.
        ReadBatch customerBatch = ReadBatch.builder(Customer.class)
                .mappedTableResource(customerTable)
                // 1a. Specify the primary key value and sort key value for the item.
                .addGetItem(b -> b.key(k -> k.partitionValue("1").sortValue("cust1@orgname.org")))
                // 1b. Alternatively, supply a data class instances to provide the primary key values.
                .addGetItem(customer2)
                .build();

        // 2. Build a batch to read from the MovieActor table.
        ReadBatch moveActorBatch = ReadBatch.builder(MovieActor.class)
                .mappedTableResource(movieActorTable)
                // 2a. Call consistentRead(Boolean.TRUE) for each item for the same table.
                .addGetItem(b -> b.key(k -> k.partitionValue("movie01").sortValue("actor1")).consistentRead(Boolean.TRUE))
                .addGetItem(b -> b.key(k -> k.partitionValue("movie01").sortValue("actor4")).consistentRead(Boolean.TRUE))
                .build();

        // 3. Add ReadBatch objects to the request.
        BatchGetResultPageIterable resultPages = enhancedClient.batchGetItem(b -> b.readBatches(customerBatch, moveActorBatch));

        // 4. Retrieve the successfully requested items from each table.
        resultPages.resultsForTable(customerTable).forEach(item -> logger.info(item.toString()));
        resultPages.resultsForTable(movieActorTable).forEach(item -> logger.info(item.toString()));

        // 5. Retrieve the keys of the items requested but not processed by the service.
        resultPages.forEach((BatchGetResultPage pageResult) -> {
            pageResult.unprocessedKeysForTable(customerTable).forEach(key -> logger.info("Unprocessed item key: " + key.toString()));
            pageResult.unprocessedKeysForTable(movieActorTable).forEach(key -> logger.info("Unprocessed item key: " + key.toString()));
        });
    }
```

Gehen Sie davon aus, dass sich die folgenden Elemente in den beiden Tabellen befinden, bevor Sie den Beispielcode ausführen.

### Elemente in Tabellen
<a name="ddb-en-client-use-multiop-batch-get-tableitems"></a>

```
Customer [id=1, name=CustName1, email=cust1@example.org, regDate=2023-03-31T15:46:27.688Z]
Customer [id=2, name=CustName2, email=cust2@example.org, regDate=2023-03-31T15:46:28.688Z]
Customer [id=3, name=CustName3, email=cust3@example.org, regDate=2023-03-31T15:46:29.688Z]
Customer [id=4, name=CustName4, email=cust4@example.org, regDate=2023-03-31T15:46:30.688Z]
Customer [id=5, name=CustName5, email=cust5@example.org, regDate=2023-03-31T15:46:31.689Z]
MovieActor{movieName='movie01', actorName='actor0', actingAward='actingaward0', actingYear=2001, actingSchoolName='null'}
MovieActor{movieName='movie01', actorName='actor1', actingAward='actingaward1', actingYear=2001, actingSchoolName='actingschool1'}
MovieActor{movieName='movie01', actorName='actor2', actingAward='actingaward2', actingYear=2001, actingSchoolName='actingschool2'}
MovieActor{movieName='movie01', actorName='actor3', actingAward='actingaward3', actingYear=2001, actingSchoolName='null'}
MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
```

Die folgende Ausgabe zeigt die zurückgegebenen und protokollierten Elemente nach Kommentarzeile 4.

```
Customer [id=1, name=CustName1, email=cust1@example.org, regDate=2023-03-31T15:46:27.688Z]
Customer [id=2, name=CustName2, email=cust2@example.org, regDate=2023-03-31T15:46:28.688Z]
MovieActor{movieName='movie01', actorName='actor4', actingAward='actingaward4', actingYear=2001, actingSchoolName='actingschool4'}
MovieActor{movieName='movie01', actorName='actor1', actingAward='actingaward1', actingYear=2001, actingSchoolName='actingschool1'}
```

## `batchWriteItem()`Beispiel für
<a name="ddb-en-client-use-multiop-batch-write"></a>

Die `batchWriteItem()` Methode fügt mehrere Elemente in eine oder mehrere Tabellen ein oder löscht sie. Sie können bis zu 25 einzelne Put- oder Löschvorgänge in der Anfrage angeben. Im folgenden Beispiel werden die zuvor gezeigten Klassen [`ProductCatalog`](ddb-en-client-use.md#ddb-en-client-use-compare-cs3)und [`MovieActor`](ddb-en-client-use-multirecord.md#ddb-en-client-use-movieactor-class)Modellklassen verwendet.

`WriteBatch`Objekte werden nach den Kommentarzeilen 1 und 2 erstellt. Für die `ProductCatalog` Tabelle fügt der Code ein Element ein und löscht ein Element. Für die `MovieActor` Tabelle nach Kommentarzeile 2 fügt der Code zwei Elemente ein und löscht eines.

Die `batchWriteItem` Methode wird nach Kommentarzeile 3 aufgerufen. Der `[builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/BatchWriteItemEnhancedRequest.Builder.html)` Parameter stellt die Batch-Anfragen für jede Tabelle bereit.

Das zurückgegebene `[BatchWriteResult](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/BatchWriteResult.html)` Objekt bietet separate Methoden für jeden Vorgang, um unverarbeitete Anfragen anzuzeigen. Der Code nach der Kommentarzeile 4a stellt die Schlüssel für unverarbeitete Löschanfragen bereit und der Code nach der Kommentarzeile 4b stellt die unverarbeiteten PUT-Elemente bereit.

```
    public static void batchWriteItemExample(DynamoDbEnhancedClient enhancedClient,
                                             DynamoDbTable<ProductCatalog> catalogTable,
                                             DynamoDbTable<MovieActor> movieActorTable) {

        // 1. Build a batch to write to the ProductCatalog table.
        WriteBatch products = WriteBatch.builder(ProductCatalog.class)
                .mappedTableResource(catalogTable)
                .addPutItem(b -> b.item(getProductCatItem1()))
                .addDeleteItem(b -> b.key(k -> k
                        .partitionValue(getProductCatItem2().id())
                        .sortValue(getProductCatItem2().title())))
                .build();

        // 2. Build a batch to write to the MovieActor table.
        WriteBatch movies = WriteBatch.builder(MovieActor.class)
                .mappedTableResource(movieActorTable)
                .addPutItem(getMovieActorYeoh())
                .addPutItem(getMovieActorBlanchettPartial())
                .addDeleteItem(b -> b.key(k -> k
                        .partitionValue(getMovieActorStreep().getMovieName())
                        .sortValue(getMovieActorStreep().getActorName())))
                .build();

        // 3. Add WriteBatch objects to the request.
        BatchWriteResult batchWriteResult = enhancedClient.batchWriteItem(b -> b.writeBatches(products, movies));
        // 4. Retrieve keys for items the service did not process.
        // 4a. 'unprocessedDeleteItemsForTable()' returns keys for delete requests that did not process.
        if (batchWriteResult.unprocessedDeleteItemsForTable(movieActorTable).size() > 0) {
            batchWriteResult.unprocessedDeleteItemsForTable(movieActorTable).forEach(key ->
                    logger.info(key.toString()));
        }
        // 4b. 'unprocessedPutItemsForTable()' returns keys for put requests that did not process.
        if (batchWriteResult.unprocessedPutItemsForTable(catalogTable).size() > 0) {
            batchWriteResult.unprocessedPutItemsForTable(catalogTable).forEach(key ->
                    logger.info(key.toString()));
        }
    }
```

Die folgenden Hilfsmethoden stellen die Modellobjekte für die Put- und Delete-Operationen bereit.

### Hilfsmethoden
<a name="ddb-en-client-use-multiop-batch-write-helpers"></a>

```
 1.     public static ProductCatalog getProductCatItem1() {
 2.         return ProductCatalog.builder()
 3.                 .id(2)
 4.                 .isbn("1-565-85698")
 5.                 .authors(new HashSet<>(Arrays.asList("a", "b")))
 6.                 .price(BigDecimal.valueOf(30.22))
 7.                 .title("Title 55")
 8.                 .build();
 9.     }
10. 
11.     public static ProductCatalog getProductCatItem2() {
12.         return ProductCatalog.builder()
13.                 .id(4)
14.                 .price(BigDecimal.valueOf(40.00))
15.                 .title("Title 1")
16.                 .build();
17.     }  
18. 
19.     public static MovieActor getMovieActorBlanchettPartial() {
20.         MovieActor movieActor = new MovieActor();
21.         movieActor.setActorName("Cate Blanchett");
22.         movieActor.setMovieName("Blue Jasmine");
23.         movieActor.setActingYear(2023);
24.         movieActor.setActingAward("Best Actress");
25.         return movieActor;
26.     }
27. 
28.     public static MovieActor getMovieActorStreep() {
29.         MovieActor movieActor = new MovieActor();
30.         movieActor.setActorName("Meryl Streep");
31.         movieActor.setMovieName("Sophie's Choice");
32.         movieActor.setActingYear(1982);
33.         movieActor.setActingAward("Best Actress");
34.         movieActor.setActingSchoolName("Yale School of Drama");
35.         return movieActor;
36.     }
37. 
38.     public static MovieActor getMovieActorYeoh(){
39.         MovieActor movieActor = new MovieActor();
40.         movieActor.setActorName("Michelle Yeoh");
41.         movieActor.setMovieName("Everything Everywhere All at Once");
42.         movieActor.setActingYear(2023);
43.         movieActor.setActingAward("Best Actress");
44.         movieActor.setActingSchoolName("Royal Academy of Dance");
45.         return movieActor;
46.     }
```

Gehen Sie davon aus, dass die Tabellen die folgenden Elemente enthalten, bevor Sie den Beispielcode ausführen.

```
MovieActor{movieName='Blue Jasmine', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2013, actingSchoolName='National Institute of Dramatic Art'}
MovieActor{movieName='Sophie's Choice', actorName='Meryl Streep', actingAward='Best Actress', actingYear=1982, actingSchoolName='Yale School of Drama'}
ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=10}
```

Nach Abschluss des Beispielcodes enthalten die Tabellen die folgenden Elemente.

```
MovieActor{movieName='Blue Jasmine', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2013, actingSchoolName='null'}
MovieActor{movieName='Everything Everywhere All at Once', actorName='Michelle Yeoh', actingAward='Best Actress', actingYear=2023, actingSchoolName='Royal Academy of Dance'}
ProductCatalog{id=2, title='Title 55', isbn='1-565-85698', authors=[a, b], price=30.22}
```

Beachten Sie in der `MovieActor` Tabelle, dass das `Blue Jasmine` Filmelement durch das Element ersetzt wurde, das in der Put-Anfrage verwendet wurde, die mit der `getMovieActorBlanchettPartial()` Helper-Methode abgerufen wurde. Wenn kein Data-Bean-Attributwert angegeben wurde, wird der Wert in der Datenbank entfernt. Aus diesem Grund ist das Ergebnis `actingSchoolName` für das `Blue Jasmine` Filmelement Null.

**Anmerkung**  
In der API-Dokumentation wird zwar darauf hingewiesen, dass Bedingungsausdrücke verwendet werden können und dass verbrauchte Kapazität und Erfassungsmetriken mit einzelnen [Put](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/PutItemEnhancedRequest.html) - und [Löschanforderungen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/DeleteItemEnhancedRequest.html) zurückgegeben werden können, dies ist jedoch in einem Batch-Write-Szenario nicht der Fall. Um die Leistung von Batch-Vorgängen zu verbessern, werden diese einzelnen Optionen ignoriert.

# Führen Sie Transaktionsoperationen durch
<a name="ddb-en-client-use-multiop-trans"></a>

Die DynamoDB Enhanced Client API stellt die `transactGetItems()` und die `transactWriteItems()` Methoden bereit. Die Transaktionsmethoden des SDK for Java sorgen für Atomizität, Konsistenz, Isolierung und Haltbarkeit (ACID) in DynamoDB-Tabellen und helfen Ihnen so, die Datenkorrektheit in Ihren Anwendungen aufrechtzuerhalten.

## `transactGetItems()`Beispiel für
<a name="ddb-en-client-use-multiop-trans-getitems"></a>

Die `[transactGetItems()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#transactGetItems(java.util.function.Consumer))` Methode akzeptiert bis zu 100 individuelle Anfragen für Elemente. Alle Elemente werden in einer einzigen atomaren Transaktion gelesen. Das *Amazon DynamoDB DynamoDB-Entwicklerhandbuch* enthält Informationen zu den [Bedingungen, die dazu führen, dass eine `transactGetItems()` Methode fehlschlägt](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txgetitems), sowie über die Isolationsstufe, die beim Aufrufen verwendet wird. `[transactGetItem()](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-isolation)`

Nach Kommentarzeile 1 im folgenden Beispiel ruft der Code die `transactGetItems()` Methode mit einem `[builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/TransactGetItemsEnhancedRequest.Builder.html)` Parameter auf. Der Builder `[addGetItem()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/TransactGetItemsEnhancedRequest.Builder.html#addGetItem(software.amazon.awssdk.enhanced.dynamodb.MappedTableResource,T))` wird dreimal mit einem Datenobjekt aufgerufen, das die Schlüsselwerte enthält, die das SDK verwendet, um die endgültige Anfrage zu generieren.

Die Anfrage gibt nach Kommentarzeile 2 eine Liste von `[Document](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Document.html)` Objekten zurück. Die zurückgegebene Dokumentenliste enthält [Dokumentinstanzen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Document.html) von Elementdaten, die nicht Null sind, und zwar in derselben Reihenfolge wie angefordert. Die `[Document.getItem(MappedTableResource<T> mappedTableResource)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/Document.html#getItem(software.amazon.awssdk.enhanced.dynamodb.MappedTableResource))` Methode konvertiert ein untypisiertes `Document` Objekt in ein typisiertes Java-Objekt, wenn Elementdaten zurückgegeben wurden, andernfalls gibt die Methode Null zurück.

```
    public static void transactGetItemsExample(DynamoDbEnhancedClient enhancedClient,
                                               DynamoDbTable<ProductCatalog> catalogTable,
                                               DynamoDbTable<MovieActor> movieActorTable) {

        // 1. Request three items from two tables using a builder.
        final List<Document> documents = enhancedClient.transactGetItems(b -> b
                .addGetItem(catalogTable, Key.builder().partitionValue(2).sortValue("Title 55").build())
                .addGetItem(movieActorTable, Key.builder().partitionValue("Sophie's Choice").sortValue("Meryl Streep").build())
                .addGetItem(movieActorTable, Key.builder().partitionValue("Blue Jasmine").sortValue("Cate Blanchett").build())
                .build());

        // 2. A list of Document objects is returned in the same order as requested.
        ProductCatalog title55 = documents.get(0).getItem(catalogTable);
        if (title55 != null) {
            logger.info(title55.toString());
        }

        MovieActor sophiesChoice = documents.get(1).getItem(movieActorTable);
        if (sophiesChoice != null) {
            logger.info(sophiesChoice.toString());
        }

        // 3. The getItem() method returns null if the Document object contains no item from DynamoDB.
        MovieActor blueJasmine = documents.get(2).getItem(movieActorTable);
        if (blueJasmine != null) {
            logger.info(blueJasmine.toString());
        }
    }
```

Die DynamoDB-Tabellen enthalten die folgenden Elemente, bevor das Codebeispiel ausgeführt wird.

```
ProductCatalog{id=2, title='Title 55', isbn='orig_isbn', authors=[b, g], price=10}
MovieActor{movieName='Sophie's Choice', actorName='Meryl Streep', actingAward='Best Actress', actingYear=1982, actingSchoolName='Yale School of Drama'}
```

Die folgende Ausgabe wird protokolliert. Wenn ein Element angefordert, aber nicht gefunden wird, wird es nicht zurückgegeben, wie es bei der Anfrage für den genannten Film der Fall ist`Blue Jasmine`.

```
ProductCatalog{id=2, title='Title 55', isbn='orig_isbn', authors=[b, g], price=10}
MovieActor{movieName='Sophie's Choice', actorName='Meryl Streep', actingAward='Best Actress', actingYear=1982, actingSchoolName='Yale School of Drama'}
```

## Beispiele für `transactWriteItems()`
<a name="ddb-en-client-use-multiop-trans-writeitems"></a>

Der `[transactWriteItems()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#transactWriteItems(java.util.function.Consumer))` akzeptiert bis zu 100 Put-, Aktualisierungs- oder Löschaktionen in einer einzigen atomaren Transaktion über mehrere Tabellen hinweg. Das *Amazon DynamoDB DynamoDB-Entwicklerhandbuch* enthält Einzelheiten zu Einschränkungen und Fehlerbedingungen des [zugrunde liegenden DynamoDB-Servicebetriebs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/transaction-apis.html#transaction-apis-txwriteitems).

### Einfaches Beispiel
<a name="ddb-en-client-use-multiop-trans-writeitems-basic"></a>

Im folgenden Beispiel werden vier Operationen für zwei Tabellen angefordert. Die entsprechenden Modellklassen [`ProductCatalog`](ddb-en-client-use.md#ddb-en-client-use-compare-cs3)und [`MovieActor`](ddb-en-client-use-multirecord.md#ddb-en-client-use-movieactor-class)wurden bereits gezeigt.

Jede der drei möglichen Operationen — Put, Update und Delete — verwendet einen speziellen Anforderungsparameter, um die Details anzugeben. 

Der Code nach der ersten Kommentarzeile zeigt die einfache Variante der Methode. `addPutItem()` Die Methode akzeptiert ein `[MappedTableResource](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/MappedTableResource.html)` Objekt und die zu setzende Datenobjektinstanz. Die Anweisung nach Kommentarzeile 2 zeigt die Variante, die eine `[TransactPutItemEnhancedRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/TransactPutItemEnhancedRequest.html)` Instanz akzeptiert. Mit dieser Variante können Sie der Anfrage weitere Optionen hinzufügen, z. B. einen Bedingungsausdruck. Ein nachfolgendes [Beispiel](#ddb-en-client-use-multiop-trans-writeitems-opcondition) zeigt einen Bedingungsausdruck für eine einzelne Operation.

Nach Kommentarzeile 3 wird ein Aktualisierungsvorgang angefordert. `[TransactUpdateItemEnhancedRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/TransactUpdateItemEnhancedRequest.Builder.html)`hat eine `ignoreNulls()` Methode, mit der Sie konfigurieren können, was das SDK mit `null` Werten im Modellobjekt macht. Wenn die `ignoreNulls()` Methode true zurückgibt, entfernt das SDK nicht die Attributwerte der Tabelle für Datenobjektattribute, die `null` Wenn die `ignoreNulls()` Methode false zurückgibt, fordert das SDK den DynamoDB-Dienst auf, die Attribute aus dem Element in der Tabelle zu entfernen. Der Standardwert für `ignoreNulls` ist False.

Die Aussage nach Kommentarzeile 4 zeigt die Variante einer Löschanforderung, die ein Datenobjekt akzeptiert. Der erweiterte Client extrahiert die Schlüsselwerte, bevor er die endgültige Anfrage sendet.

```
    public static void transactWriteItems(DynamoDbEnhancedClient enhancedClient,
                                          DynamoDbTable<ProductCatalog> catalogTable,
                                          DynamoDbTable<MovieActor> movieActorTable) {

        enhancedClient.transactWriteItems(b -> b
                // 1. Simplest variation of put item request.
                .addPutItem(catalogTable, getProductCatId2())
                // 2. Put item request variation that accommodates condition expressions.
                .addPutItem(movieActorTable, TransactPutItemEnhancedRequest.builder(MovieActor.class)
                        .item(getMovieActorStreep())
                        .conditionExpression(Expression.builder().expression("attribute_not_exists (movie)").build())
                        .build())
                // 3. Update request that does not remove attribute values on the table if the data object's value is null.
                .addUpdateItem(catalogTable, TransactUpdateItemEnhancedRequest.builder(ProductCatalog.class)
                        .item(getProductCatId4ForUpdate())
                        .ignoreNulls(Boolean.TRUE)
                        .build())
                // 4. Variation of delete request that accepts a data object. The key values are extracted for the request.
                .addDeleteItem(movieActorTable, getMovieActorBlanchett())
        );
    }
```

Die folgenden Hilfsmethoden stellen die Datenobjekte für die `add*Item` Parameter bereit.

#### Hilfsmethoden
<a name="ddb-en-client-use-multiop-trans-writeitems-basic-helpers"></a>

```
    public static ProductCatalog getProductCatId2() {
        return ProductCatalog.builder()
                .id(2)
                .isbn("1-565-85698")
                .authors(new HashSet<>(Arrays.asList("a", "b")))
                .price(BigDecimal.valueOf(30.22))
                .title("Title 55")
                .build();
    }

    public static ProductCatalog getProductCatId4ForUpdate() {
        return ProductCatalog.builder()
                .id(4)
                .price(BigDecimal.valueOf(40.00))
                .title("Title 1")
                .build();
    }

    public static MovieActor getMovieActorBlanchett() {
        MovieActor movieActor = new MovieActor();
        movieActor.setActorName("Cate Blanchett");
        movieActor.setMovieName("Tar");
        movieActor.setActingYear(2022);
        movieActor.setActingAward("Best Actress");
        movieActor.setActingSchoolName("National Institute of Dramatic Art");
        return movieActor;
    }

    public static MovieActor getMovieActorStreep() {
        MovieActor movieActor = new MovieActor();
        movieActor.setActorName("Meryl Streep");
        movieActor.setMovieName("Sophie's Choice");
        movieActor.setActingYear(1982);
        movieActor.setActingAward("Best Actress");
        movieActor.setActingSchoolName("Yale School of Drama");
        return movieActor;
    }
```

Die DynamoDB-Tabellen enthalten die folgenden Elemente, bevor das Codebeispiel ausgeführt wird.

```
1 | ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=10}
2 | MovieActor{movieName='Tar', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2022, actingSchoolName='National Institute of Dramatic Art'}
```

Die folgenden Elemente befinden sich in den Tabellen, nachdem die Ausführung des Codes abgeschlossen ist.

```
3 | ProductCatalog{id=2, title='Title 55', isbn='1-565-85698', authors=[a, b], price=30.22}
4 | ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=40.0}
5 | MovieActor{movieName='Sophie's Choice', actorName='Meryl Streep', actingAward='Best Actress', actingYear=1982, actingSchoolName='Yale School of Drama'}
```

Das Element in Zeile 2 wurde gelöscht und die Zeilen 3 und 5 zeigen die Elemente, die eingefügt wurden. Zeile 4 zeigt die Aktualisierung von Zeile 1. Der `price` Wert ist der einzige Wert, der sich für den Artikel geändert hat. Wenn False zurückgegeben `ignoreNulls()` worden wäre, würde Zeile 4 wie die folgende Zeile aussehen.

```
ProductCatalog{id=4, title='Title 1', isbn='null', authors=null, price=40.0}
```

### Beispiel für eine Zustandsprüfung
<a name="ddb-en-client-use-multiop-trans-writeitems-checkcond"></a>

Das folgende Beispiel zeigt die Verwendung einer Zustandsprüfung. Eine Zustandsprüfung wird verwendet, um zu überprüfen, ob ein Element vorhanden ist, oder um den Zustand bestimmter Attribute eines Elements in der Datenbank zu überprüfen. Der Artikel, der bei der Zustandsprüfung geprüft wurde, kann nicht für einen anderen Vorgang in der Transaktion verwendet werden.

**Anmerkung**  
Sie können nicht in derselben Transaktion mit mehreren Operationen auf das gleiche Element abzielen. Sie können beispielsweise nicht eine Zustandsprüfung durchführen und gleichzeitig versuchen, denselben Artikel in derselben Transaktion zu aktualisieren.

Das Beispiel zeigt einen von jedem Operationstyp in einer transaktionalen Anforderung zum Schreiben von Elementen. Nach Kommentarzeile 2 gibt die `addConditionCheck()` Methode die Bedingung an, dass die Transaktion fehlschlägt, wenn der `conditionExpression` Parameter als 0 ausgewertet wird. `false` Der Bedingungsausdruck, der von der im Block Helper-Methoden gezeigten Methode zurückgegeben wird, prüft, ob das Preisjahr für den Film ungleich `Sophie's Choice` ist. `1982` Ist dies der Fall, wird der Ausdruck als 0 ausgewertet `false` und die Transaktion schlägt fehl.

In diesem Handbuch werden [Ausdrücke](ddb-en-client-expressions.md) in einem anderen Thema ausführlich behandelt.

```
    public static void conditionCheckFailExample(DynamoDbEnhancedClient enhancedClient,
                                                 DynamoDbTable<ProductCatalog> catalogTable,
                                                 DynamoDbTable<MovieActor> movieActorTable) {

        try {
            enhancedClient.transactWriteItems(b -> b
                    // 1. Perform one of each type of operation with the next three methods.
                    .addPutItem(catalogTable, TransactPutItemEnhancedRequest.builder(ProductCatalog.class)
                            .item(getProductCatId2()).build())
                    .addUpdateItem(catalogTable, TransactUpdateItemEnhancedRequest.builder(ProductCatalog.class)
                            .item(getProductCatId4ForUpdate())
                            .ignoreNulls(Boolean.TRUE).build())
                    .addDeleteItem(movieActorTable, TransactDeleteItemEnhancedRequest.builder()
                            .key(b1 -> b1
                                    .partitionValue(getMovieActorBlanchett().getMovieName())
                                    .sortValue(getMovieActorBlanchett().getActorName())).build())
                    // 2. Add a condition check on a table item that is not involved in another operation in this request.
                    .addConditionCheck(movieActorTable, ConditionCheck.builder()
                            .conditionExpression(buildConditionCheckExpression())
                            .key(k -> k
                                    .partitionValue("Sophie's Choice")
                                    .sortValue("Meryl Streep"))
                            // 3. Specify the request to return existing values from the item if the condition evaluates to true.
                            .returnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD)
                            .build())
                    .build());
        // 4. Catch the exception if the transaction fails and log the information.
        } catch (TransactionCanceledException ex) {
            ex.cancellationReasons().stream().forEach(cancellationReason -> {
                logger.info(cancellationReason.toString());
            });
        }
    }
```

Die folgenden Hilfsmethoden wurden im vorherigen Codebeispiel verwendet.

#### Hilfsmethoden
<a name="ddb-en-client-use-multiop-trans-writeitems-checkcond-helpers"></a>

```
    private static Expression buildConditionCheckExpression() {
        Map<String, AttributeValue> expressionValue = Map.of(
                ":year", numberValue(1982));

        return Expression.builder()
                .expression("actingyear <> :year")
                .expressionValues(expressionValue)
                .build();
    }

    public static ProductCatalog getProductCatId2() {
        return ProductCatalog.builder()
                .id(2)
                .isbn("1-565-85698")
                .authors(new HashSet<>(Arrays.asList("a", "b")))
                .price(BigDecimal.valueOf(30.22))
                .title("Title 55")
                .build();
    }

    public static ProductCatalog getProductCatId4ForUpdate() {
        return ProductCatalog.builder()
                .id(4)
                .price(BigDecimal.valueOf(40.00))
                .title("Title 1")
                .build();
    }

    public static MovieActor getMovieActorBlanchett() {
        MovieActor movieActor = new MovieActor();
        movieActor.setActorName("Cate Blanchett");
        movieActor.setMovieName("Blue Jasmine");
        movieActor.setActingYear(2013);
        movieActor.setActingAward("Best Actress");
        movieActor.setActingSchoolName("National Institute of Dramatic Art");
        return movieActor;
    }
```

Die DynamoDB-Tabellen enthalten die folgenden Elemente, bevor das Codebeispiel ausgeführt wird.

```
1 | ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=10}
2 | MovieActor{movieName='Sophie's Choice', actorName='Meryl Streep', actingAward='Best Actress', actingYear=1982, actingSchoolName='Yale School of Drama'}
3 | MovieActor{movieName='Tar', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2022, actingSchoolName='National Institute of Dramatic Art'}
```

Die folgenden Elemente befinden sich in den Tabellen, nachdem die Ausführung des Codes abgeschlossen ist.

```
ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=10}
MovieActor{movieName='Sophie's Choice', actorName='Meryl Streep', actingAward='Best Actress', actingYear=1982, actingSchoolName='Yale School of Drama'}
MovieActor{movieName='Tar', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2022, actingSchoolName='National Institute of Dramatic Art'}
```

Die Elemente in den Tabellen bleiben unverändert, da die Transaktion fehlgeschlagen ist. Der `actingYear` Wert für den Film `Sophie's Choice` entspricht dem Wert`1982`, der in Zeile 2 der Elemente in der Tabelle vor dem Aufruf der `transactWriteItem()` Methode angegeben wurde.

Um die Stornierungsinformationen für die Transaktion zu erfassen, schließen Sie den `transactWriteItems()` Methodenaufruf in einen `try` Block ein und fügen Sie `catch` den [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TransactionCanceledException.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/TransactionCanceledException.html). Nach Kommentarzeile 4 des Beispiels protokolliert der Code jedes `[CancellationReason](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/CancellationReason.html)` Objekt. Da der Code nach der dritten Kommentarzeile des Beispiels angibt, dass Werte für das Element zurückgegeben werden sollen, das zum Fehlschlagen der Transaktion geführt hat, zeigt das Protokoll die unformatierten Datenbankwerte für das `Sophie's Choice` Filmelement an.

```
CancellationReason(Code=None)
CancellationReason(Code=None)
CancellationReason(Code=None)
CancellationReason(Item={actor=AttributeValue(S=Meryl Streep), movie=AttributeValue(S=Sophie's Choice), actingaward=AttributeValue(S=Best Actress), actingyear=AttributeValue(N=1982), actingschoolname=AttributeValue(S=Yale School of Drama)}, ¬
    Code=ConditionalCheckFailed, Message=The conditional request failed.)
```

### Beispiel für eine einzelne Betriebsbedingung
<a name="ddb-en-client-use-multiop-trans-writeitems-opcondition"></a>

Das folgende Beispiel zeigt die Verwendung einer Bedingung für eine einzelne Operation in einer Transaktionsanforderung. Der Löschvorgang nach der ersten Kommentarzeile enthält eine Bedingung, die den Wert des Zielelements der Operation mit der Datenbank vergleicht. In diesem Beispiel gibt der Bedingungsausdruck, der mit der Hilfsmethode nach Kommentarzeile 2 erstellt wurde, an, dass das Element aus der Datenbank gelöscht werden soll, wenn das Schauspieljahr des Films nicht 2013 entspricht.

[Ausdrücke](ddb-en-client-expressions.md) werden später in diesem Handbuch behandelt.

```
    public static void singleOperationConditionFailExample(DynamoDbEnhancedClient enhancedClient,
                                                           DynamoDbTable<ProductCatalog> catalogTable,
                                                           DynamoDbTable<MovieActor> movieActorTable) {
        try {
            enhancedClient.transactWriteItems(b -> b
                    .addPutItem(catalogTable, TransactPutItemEnhancedRequest.builder(ProductCatalog.class)
                            .item(getProductCatId2())
                            .build())
                    .addUpdateItem(catalogTable, TransactUpdateItemEnhancedRequest.builder(ProductCatalog.class)
                            .item(getProductCatId4ForUpdate())
                            .ignoreNulls(Boolean.TRUE).build())
                    // 1. Delete operation that contains a condition expression
                    .addDeleteItem(movieActorTable, TransactDeleteItemEnhancedRequest.builder()
                            .key((Key.Builder k) -> {
                                MovieActor blanchett = getMovieActorBlanchett();
                                k.partitionValue(blanchett.getMovieName())
                                        .sortValue(blanchett.getActorName());
                            })
                            .conditionExpression(buildDeleteItemExpression())
                            .returnValuesOnConditionCheckFailure(ReturnValuesOnConditionCheckFailure.ALL_OLD)
                            .build())
                    .build());
        } catch (TransactionCanceledException ex) {
            ex.cancellationReasons().forEach(cancellationReason -> logger.info(cancellationReason.toString()));
        }
    }

    // 2. Provide condition expression to check if 'actingyear' is not equal to 2013.
    private static Expression buildDeleteItemExpression() {
        Map<String, AttributeValue> expressionValue = Map.of(
                ":year", numberValue(2013));

        return Expression.builder()
                .expression("actingyear <> :year")
                .expressionValues(expressionValue)
                .build();
    }
```

Die folgenden Hilfsmethoden wurden im vorherigen Codebeispiel verwendet.

#### Hilfsmethoden
<a name="ddb-en-client-use-multiop-trans-writeitems-opcondition-helpers"></a>

```
    public static ProductCatalog getProductCatId2() {
        return ProductCatalog.builder()
                .id(2)
                .isbn("1-565-85698")
                .authors(new HashSet<>(Arrays.asList("a", "b")))
                .price(BigDecimal.valueOf(30.22))
                .title("Title 55")
                .build();
    }

    public static ProductCatalog getProductCatId4ForUpdate() {
        return ProductCatalog.builder()
                .id(4)
                .price(BigDecimal.valueOf(40.00))
                .title("Title 1")
                .build();
    }
    public static MovieActor getMovieActorBlanchett() {
        MovieActor movieActor = new MovieActor();
        movieActor.setActorName("Cate Blanchett");
        movieActor.setMovieName("Blue Jasmine");
        movieActor.setActingYear(2013);
        movieActor.setActingAward("Best Actress");
        movieActor.setActingSchoolName("National Institute of Dramatic Art");
        return movieActor;
    }
```

Die DynamoDB-Tabellen enthalten die folgenden Elemente, bevor das Codebeispiel ausgeführt wird.

```
1 | ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=10}
2 | MovieActor{movieName='Blue Jasmine', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2013, actingSchoolName='National Institute of Dramatic Art'}
```

Die folgenden Elemente befinden sich in den Tabellen, nachdem die Ausführung des Codes abgeschlossen ist.

```
ProductCatalog{id=4, title='Title 1', isbn='orig_isbn', authors=[b, g], price=10}
2023-03-15 11:29:07 [main] INFO  org.example.tests.TransactDemoTest:168 - MovieActor{movieName='Blue Jasmine', actorName='Cate Blanchett', actingAward='Best Actress', actingYear=2013, actingSchoolName='National Institute of Dramatic Art'}
```

Die Elemente in den Tabellen bleiben unverändert, da die Transaktion fehlgeschlagen ist. Der `actingYear` Wert für den Film `Blue Jasmine` entspricht `2013` in Zeile 2 der Elementliste, bevor das Codebeispiel ausgeführt wird.

Die folgenden Zeilen werden in der Konsole protokolliert.

```
CancellationReason(Code=None)
CancellationReason(Code=None)
CancellationReason(Item={actor=AttributeValue(S=Cate Blanchett), movie=AttributeValue(S=Blue Jasmine), actingaward=AttributeValue(S=Best Actress), actingyear=AttributeValue(N=2013), actingschoolname=AttributeValue(S=National Institute of Dramatic Art)}, 
    Code=ConditionalCheckFailed, Message=The conditional request failed)
```

# Verwenden Sie sekundäre Indizes
<a name="ddb-en-client-use-secindex"></a>

Sekundäre Indizes verbessern den Datenzugriff, indem sie alternative Schlüssel definieren, die Sie bei Abfrage- und Scanvorgängen verwenden. Globale Sekundärindizes (GSI) haben einen Partitionsschlüssel und einen Sortierschlüssel, die sich von denen in der Basistabelle unterscheiden können. Im Gegensatz dazu verwenden lokale Sekundärindizes (LSI) den Partitionsschlüssel des Primärindexes.

## Kommentieren Sie die Datenklasse mit Anmerkungen zum sekundären Index
<a name="ddb-en-client-use-secindex-annomodel"></a>

Für Attribute, die an sekundären Indizes beteiligt sind, ist entweder die `@DynamoDbSecondarySortKey` Anmerkung `@DynamoDbSecondaryPartitionKey` oder erforderlich.

Die folgende Klasse zeigt Anmerkungen für zwei Indizes. Die angegebene GSI *SubjectLastPostedDateIndex*verwendet das `Subject` Attribut für den Partitionsschlüssel und das `LastPostedDateTime` für den Sortierschlüssel. Die benannte LSI *ForumLastPostedDateIndex*verwendet den `ForumName` als Partitionsschlüssel und `LastPostedDateTime` als Sortierschlüssel.

Beachten Sie, dass das `Subject` Attribut eine doppelte Rolle spielt. Es ist der Sortierschlüssel des Primärschlüssels und der Partitionsschlüssel der genannten *SubjectLastPostedDateIndex*GSI.

### `MessageThread`-Klasse
<a name="ddb-en-client-use-secindex-class"></a>

Die `MessageThread` Klasse eignet sich als Datenklasse für die [Thread-Beispieltabelle](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/AppendixSampleTables.html) im *Amazon DynamoDB Developer Guide*.

#### Importe
<a name="ddb-en-client-use-secindex-classimports"></a>

```
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbBean;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondaryPartitionKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSecondarySortKey;
import software.amazon.awssdk.enhanced.dynamodb.mapper.annotations.DynamoDbSortKey;

import java.util.List;
```

```
@DynamoDbBean
public class MessageThread {
    private String ForumName;
    private String Subject;
    private String Message;
    private String LastPostedBy;
    private String LastPostedDateTime;
    private Integer Views;
    private Integer Replies;
    private Integer Answered;
    private List<String> Tags;

    @DynamoDbPartitionKey
    public String getForumName() {
        return ForumName;
    }

    public void setForumName(String forumName) {
        ForumName = forumName;
    }

    // Sort key for primary index and partition key for GSI "SubjectLastPostedDateIndex".
    @DynamoDbSortKey
    @DynamoDbSecondaryPartitionKey(indexNames = "SubjectLastPostedDateIndex")
    public String getSubject() {
        return Subject;
    }

    public void setSubject(String subject) {
        Subject = subject;
    }

    // Sort key for GSI "SubjectLastPostedDateIndex" and sort key for LSI "ForumLastPostedDateIndex".
    @DynamoDbSecondarySortKey(indexNames = {"SubjectLastPostedDateIndex", "ForumLastPostedDateIndex"})
    public String getLastPostedDateTime() {
        return LastPostedDateTime;
    }

    public void setLastPostedDateTime(String lastPostedDateTime) {
        LastPostedDateTime = lastPostedDateTime;
    }
    public String getMessage() {
        return Message;
    }

    public void setMessage(String message) {
        Message = message;
    }

    public String getLastPostedBy() {
        return LastPostedBy;
    }

    public void setLastPostedBy(String lastPostedBy) {
        LastPostedBy = lastPostedBy;
    }

    public Integer getViews() {
        return Views;
    }

    public void setViews(Integer views) {
        Views = views;
    }

    @DynamoDbSecondaryPartitionKey(indexNames = "ForumRepliesIndex")
    public Integer getReplies() {
        return Replies;
    }

    public void setReplies(Integer replies) {
        Replies = replies;
    }

    public Integer getAnswered() {
        return Answered;
    }

    public void setAnswered(Integer answered) {
        Answered = answered;
    }

    public List<String> getTags() {
        return Tags;
    }

    public void setTags(List<String> tags) {
        Tags = tags;
    }

    public MessageThread() {
        this.Answered = 0;
        this.LastPostedBy = "";
        this.ForumName = "";
        this.Message = "";
        this.LastPostedDateTime = "";
        this.Replies = 0;
        this.Views = 0;
        this.Subject = "";
    }

    @Override
    public String toString() {
        return "MessageThread{" +
                "ForumName='" + ForumName + '\'' +
                ", Subject='" + Subject + '\'' +
                ", Message='" + Message + '\'' +
                ", LastPostedBy='" + LastPostedBy + '\'' +
                ", LastPostedDateTime='" + LastPostedDateTime + '\'' +
                ", Views=" + Views +
                ", Replies=" + Replies +
                ", Answered=" + Answered +
                ", Tags=" + Tags +
                '}';
    }
}
```

## Erstellen Sie den Index
<a name="ddb-en-client-use-secindex-confindex"></a>

Ab Version 2.20.86 des SDK for Java generiert die `createTable()` Methode automatisch Sekundärindizes aus Datenklassenanmerkungen. Standardmäßig werden alle Attribute aus der Basistabelle in einen Index kopiert, und die bereitgestellten Durchsatzwerte betragen 20 Lesekapazitätseinheiten und 20 Schreibkapazitätseinheiten.

Wenn Sie jedoch eine SDK-Version vor 2.20.86 verwenden, müssen Sie den Index zusammen mit der Tabelle erstellen, wie im folgenden Beispiel gezeigt. In diesem Beispiel werden die beiden Indizes für die Tabelle erstellt. `Thread` Der [Builder-Parameter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/CreateTableEnhancedRequest.Builder.html) verfügt über Methoden zur Konfiguration beider Indextypen, wie nach den Kommentarzeilen 1 und 2 gezeigt. Sie verwenden die `indexName()` Methode des Indexgenerators, um die in den Datenklassenanmerkungen angegebenen Indexnamen dem gewünschten Indextyp zuzuordnen.

Dieser Code konfiguriert alle Tabellenattribute so, dass sie nach den Kommentarzeilen 3 und 4 in beiden Indizes landen. Weitere Informationen zu [Attributprojektionen](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LSI.html#LSI.Projections) finden Sie im *Amazon DynamoDB Developer Guide*.

```
    public static void createMessageThreadTable(DynamoDbTable<MessageThread> messageThreadDynamoDbTable, DynamoDbClient dynamoDbClient) {
        messageThreadDynamoDbTable.createTable(b -> b
                // 1. Generate the GSI.
                .globalSecondaryIndices(gsi -> gsi.indexName("SubjectLastPostedDateIndex")
                        // 3. Populate the GSI with all attributes.
                        .projection(p -> p
                                .projectionType(ProjectionType.ALL))
                )
                // 2. Generate the LSI.
                .localSecondaryIndices(lsi -> lsi.indexName("ForumLastPostedDateIndex")
                        // 4. Populate the LSI with all attributes.
                        .projection(p -> p
                                .projectionType(ProjectionType.ALL))
                )
        );
```

## Abfragen mithilfe eines Indexes
<a name="ddb-en-client-use-secindex-query"></a>

Im folgenden Beispiel wird der lokale sekundäre Index *ForumLastPostedDateIndex* abgefragt.

Nach Kommentarzeile 2 erstellen Sie ein [QueryConditional](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/QueryConditional.html)Objekt, das für den Aufruf der [DynamoDbIndex.query ()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbIndex.html#query(java.util.function.Consumer)) -Methode erforderlich ist. 

Sie erhalten nach Kommentarzeile 3 einen Verweis auf den Index, den Sie abfragen möchten, indem Sie den Namen des Indexes übergeben. Nach Kommentarzeile 4 rufen Sie die `query()` Methode für den Index auf und übergeben das `QueryConditional` Objekt. 

Sie konfigurieren die Abfrage auch so, dass sie drei Attributwerte zurückgibt, wie nach Kommentarzeile 5 gezeigt. Wenn nicht aufgerufen `attributesToProject()` wird, gibt die Abfrage alle Attributwerte zurück. Beachten Sie, dass die angegebenen Attributnamen mit Kleinbuchstaben beginnen. Diese Attributnamen stimmen mit den in der Tabelle verwendeten überein, nicht unbedingt mit den Attributnamen der Datenklasse.

Folgen Sie der Kommentarzeile 6 und wiederholen Sie die Ergebnisse, protokollieren Sie jedes von der Abfrage zurückgegebene Element und speichern Sie es auch in der Liste, um zum Aufrufer zurückzukehren.

```
public class IndexScanExamples {
    private static Logger logger = LoggerFactory.getLogger(IndexScanExamples.class);

    public static List<MessageThread> queryUsingSecondaryIndices(String lastPostedDate,
                                                                 DynamoDbTable<MessageThread> threadTable) {
        // 1. Log the parameter value.
        logger.info("lastPostedDate value: {}", lastPostedDate);

        // 2. Create a QueryConditional whose sort key value must be greater than or equal to the parameter value.
        QueryConditional queryConditional = QueryConditional.sortGreaterThanOrEqualTo(qc ->
                qc.partitionValue("Forum02").sortValue(lastPostedDate));

        // 3. Specify the index name to query.
        final DynamoDbIndex<MessageThread> forumLastPostedDateIndex = threadTable.index("ForumLastPostedDateIndex");

        // 4. Perform the query using the QueryConditional object.
        final SdkIterable<Page<MessageThread>> pagedResult = forumLastPostedDateIndex.query(q -> q
                .queryConditional(queryConditional)
                // 5. Request three attribute in the results.
                .attributesToProject("forumName", "subject", "lastPostedDateTime"));

        List<MessageThread> collectedItems = new ArrayList<>();
        // 6. Iterate through pages response and sort the items.
        pagedResult.stream().forEach(page -> page.items().stream()
                .sorted(Comparator.comparing(MessageThread::getLastPostedDateTime))
                .forEach(mt -> {
                    // 7. Log the returned items and add the collection to return to the caller.
                    logger.info(mt.toString());
                    collectedItems.add(mt);
                }));
        return collectedItems;
    }
```

Die folgenden Elemente sind in der Datenbank vorhanden, bevor die Abfrage ausgeführt wird.

```
MessageThread{ForumName='Forum01', Subject='Subject01', Message='Message01', LastPostedBy='', LastPostedDateTime='2023.03.28', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject02', Message='Message02', LastPostedBy='', LastPostedDateTime='2023.03.29', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject04', Message='Message04', LastPostedBy='', LastPostedDateTime='2023.03.31', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject08', Message='Message08', LastPostedBy='', LastPostedDateTime='2023.04.04', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject10', Message='Message10', LastPostedBy='', LastPostedDateTime='2023.04.06', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum03', Subject='Subject03', Message='Message03', LastPostedBy='', LastPostedDateTime='2023.03.30', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum03', Subject='Subject06', Message='Message06', LastPostedBy='', LastPostedDateTime='2023.04.02', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum03', Subject='Subject09', Message='Message09', LastPostedBy='', LastPostedDateTime='2023.04.05', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum05', Subject='Subject05', Message='Message05', LastPostedBy='', LastPostedDateTime='2023.04.01', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum07', Subject='Subject07', Message='Message07', LastPostedBy='', LastPostedDateTime='2023.04.03', Views=0, Replies=0, Answered=0, Tags=null}
```

Die Protokollierungsanweisungen in den Zeilen 1 und 6 führen zu der folgenden Konsolenausgabe.

```
lastPostedDate value: 2023.03.31
MessageThread{ForumName='Forum02', Subject='Subject04', Message='', LastPostedBy='', LastPostedDateTime='2023.03.31', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject08', Message='', LastPostedBy='', LastPostedDateTime='2023.04.04', Views=0, Replies=0, Answered=0, Tags=null}
MessageThread{ForumName='Forum02', Subject='Subject10', Message='', LastPostedBy='', LastPostedDateTime='2023.04.06', Views=0, Replies=0, Answered=0, Tags=null}
```

Die Abfrage hat Elemente mit dem `forumName` Wert *Forum02* und einem `lastPostedDateTime` Wert größer oder gleich *2023.03.31* zurückgegeben. Die Ergebnisse zeigen `message` Werte mit einer leeren Zeichenfolge, obwohl die `message` Attribute Werte im Index haben. Das liegt daran, dass das Nachrichtenattribut im Code nach Kommentarzeile 5 nicht projiziert wurde. 

# Verwenden Sie erweiterte Mapping-Funktionen
<a name="ddb-en-client-adv-features"></a>

Erfahren Sie mehr über erweiterte Tabellenschemafunktionen in der DynamoDB Enhanced Client API.

## Machen Sie sich mit Tabellenschematypen vertraut
<a name="ddb-en-client-adv-features-schm-overview"></a>

`[TableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/TableSchema.html)`ist die Schnittstelle zur Mapping-Funktionalität der DynamoDB Enhanced Client API. Sie kann ein Datenobjekt einer Map von und zu einer Map von zuordnen. [AttributeValues](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/dynamodb/model/AttributeValue.html) Ein `TableSchema` Objekt muss die Struktur der Tabelle kennen, die es abbildet. Diese Strukturinformationen werden in einem [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/TableMetadata.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/TableMetadata.html)Objekt gespeichert.

Die erweiterte Client-API hat mehrere Implementierungen von`TableSchema`, die im Folgenden aufgeführt sind. 

### Aus kommentierten Klassen generiertes Tabellenschema
<a name="ddb-en-client-adv-features-schema-mapped"></a>

Das Erstellen eines `TableSchema` aus annotierten Klassen ist ein relativ teurer Vorgang. Wir empfehlen daher, dies einmal beim Start der Anwendung zu tun.

 [ BeanTableSchema ](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchema.html)   
Diese Implementierung basiert auf Attributen und Anmerkungen einer Bean-Klasse. Ein Beispiel für diesen Ansatz wird im [Abschnitt Erste Schritte](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean) demonstriert.  
Wenn `BeanTableSchema` sich a nicht wie erwartet verhält, aktivieren Sie die Debug-Protokollierung für. `software.amazon.awssdk.enhanced.dynamodb.beans`

[ImmutableTableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/ImmutableTableSchema.html)  
Diese Implementierung basiert auf einer unveränderlichen Datenklasse. Dieser Ansatz wird im [Arbeiten Sie mit unveränderlichen Datenklassen](ddb-en-client-use-immut.md) Abschnitt beschrieben.

### Mit einem Builder generiertes Tabellenschema
<a name="ddb-en-client-adv-features-schema-static"></a>

Die folgenden `TableSchema` s werden mithilfe eines Builders aus Code erstellt. Dieser Ansatz ist kostengünstiger als der Ansatz, bei dem annotierte Datenklassen verwendet werden. Der Builder-Ansatz vermeidet die Verwendung von Anmerkungen und erfordert keine JavaBean Benennungsstandards.

[StaticTableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/StaticTableSchema.html)  
Diese Implementierung wurde für veränderbare Datenklassen entwickelt. Im Abschnitt „Erste Schritte“ dieses Handbuchs wurde gezeigt, wie Sie [`StaticTableSchema`mithilfe eines Builders eine generieren](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-builder).

[StaticImmutableTableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/StaticImmutableTableSchema.html)  
Ähnlich wie beim Erstellen eines generieren Sie eine Implementierung dieses Typs`StaticTableSchema`, indem Sie einen [Builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/StaticImmutableTableSchema.html) für die `TableSchema` Verwendung mit unveränderlichen Datenklassen verwenden.

### Tabellenschema für Daten ohne festes Schema
<a name="ddb-en-client-adv-features-schema-document"></a>

[DocumentTableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/DocumentTableSchema.html)  
Im Gegensatz zu anderen Implementierungen von `TableSchema` definieren Sie keine Attribute für eine `DocumentTableSchema` Instanz. Normalerweise geben Sie nur Primärschlüssel und Anbieter von Attributkonvertern an. Eine `EnhancedDocument` Instanz stellt die Attribute bereit, die Sie aus einzelnen Elementen oder aus einer JSON-Zeichenfolge erstellen.

# Fügen Sie Attribute explizit ein oder schließen Sie sie aus
<a name="ddb-en-client-adv-features-inex-attr"></a>

Die DynamoDB Enhanced Client API bietet Anmerkungen, um Datenklassenattribute daran zu hindern, zu Attributen in einer Tabelle zu werden. Mit der API können Sie auch einen Attributnamen verwenden, der sich vom Attributnamen der Datenklasse unterscheidet.

## Attribute ausschließen
<a name="ddb-en-client-adv-features-inex-attr-ex"></a>

Um Attribute zu ignorieren, die keiner DynamoDB-Tabelle zugeordnet werden sollten, markieren Sie das Attribut mit der Anmerkung. `@DynamoDbIgnore`

```
private String internalKey;

@DynamoDbIgnore
public String getInternalKey() { return this.internalKey; }
public void setInternalKey(String internalKey) { this.internalKey = internalKey;}
```

## Attribute einbeziehen
<a name="ddb-en-client-adv-features-inex-attr-in"></a>

Um den Namen eines in der DynamoDB-Tabelle verwendeten Attributs zu ändern, markieren Sie es mit der `@DynamoDbAttribute` Anmerkung und geben Sie einen anderen Namen ein.

```
private String internalKey;

@DynamoDbAttribute("renamedInternalKey")
public String getInternalKey() { return this.internalKey; }
public void setInternalKey(String internalKey) { this.internalKey = internalKey;}
```

# Steuern Sie die Attributkonvertierung
<a name="ddb-en-client-adv-features-conversion"></a>

Standardmäßig stellt ein Tabellenschema über eine Standardimplementierung der `[AttributeConverterProvider](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverterProvider.html)` Schnittstelle Konverter für viele gängige Java-Typen bereit. Das allgemeine Standardverhalten lässt sich durch eine benutzerdefinierte `AttributeConverterProvider`-Implementierung ändern. Ebenso können Sie den Konverter für ein einzelnes Attribut anpassen.

Eine Liste der verfügbaren Konverter finden Sie im Java-Dokument zur [AttributeConverter](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/AttributeConverter.html)Schnittstelle.

## Stellen Sie Anbieter für benutzerdefinierte Attributkonverter bereit
<a name="ddb-en-client-adv-features-conversion-prov"></a>

Sie können über die `@DynamoDbBean` `(converterProviders = {…})` Anmerkung ein einzelnes `AttributeConverterProvider` oder eine Kette von bestellten `AttributeConverterProvider` S angeben. Jeder benutzerdefinierte `AttributeConverterProvider` Benutzer muss die `AttributeConverterProvider` Schnittstelle erweitern.

Beachten Sie, dass Sie, wenn Sie Ihre eigene Kette von Anbietern für Attributkonverter angeben, den Standardkonverter-Anbieter außer Kraft setzen`DefaultAttributeConverterProvider`. Wenn Sie die Funktionalität von verwenden möchten`DefaultAttributeConverterProvider`, müssen Sie sie in die Kette aufnehmen. 

Es ist auch möglich, die Bean mit einem leeren Array `{}` zu annotieren. Dadurch wird die Verwendung aller Anbieter für Attributkonverter deaktiviert, einschließlich der Standardanbieter. In diesem Fall müssen alle Attribute, die zugeordnet werden sollen, über einen eigenen Attributkonverter verfügen.

Der folgende Ausschnitt zeigt einen einzelnen Konverter-Anbieter.

```
@DynamoDbBean(converterProviders = ConverterProvider1.class)
public class Customer {

}
```

Der folgende Ausschnitt zeigt die Verwendung einer Kette von Konverteranbietern. Da der SDK-Standard zuletzt bereitgestellt wird, hat er die niedrigste Priorität.

```
@DynamoDbBean(converterProviders = {
   ConverterProvider1.class, 
   ConverterProvider2.class,
   DefaultAttributeConverterProvider.class})
public class Customer {

}
```

Die Schema-Builder für statische Tabellen verfügen über eine `attributeConverterProviders()` Methode, die auf die gleiche Weise funktioniert. Dies wird im folgenden Ausschnitt gezeigt.

```
private static final StaticTableSchema<Customer> CUSTOMER_TABLE_SCHEMA =
  StaticTableSchema.builder(Customer.class)
    .newItemSupplier(Customer::new)
    .addAttribute(String.class, a -> a.name("name")
                                     a.getter(Customer::getName)
                                     a.setter(Customer::setName))
    .attributeConverterProviders(converterProvider1, converterProvider2)
    .build();
```

## Überschreiben Sie die Zuordnung eines einzelnen Attributs
<a name="ddb-en-client-adv-features-conversion-single"></a>

Um die Art und Weise, wie ein einzelnes Attribut zugeordnet wird, zu überschreiben, geben Sie an `AttributeConverter` für das Attribut ein. Dieser Zusatz hat Vorrang vor allen Konvertern, die von `AttributeConverterProviders` im Tabellenschema bereitgestellt werden. Dadurch wird ein benutzerdefinierter Konverter nur für dieses Attribut hinzugefügt. Andere Attribute, auch solche desselben Typs, verwenden diesen Konverter nur, wenn er explizit für diese anderen Attribute angegeben ist.

Die `@DynamoDbConvertedBy` Anmerkung wird verwendet, um die benutzerdefinierte `AttributeConverter` Klasse anzugeben, wie im folgenden Codeausschnitt gezeigt.

```
@DynamoDbBean
public class Customer {
    private String name;

    @DynamoDbConvertedBy(CustomAttributeConverter.class)
    public String getName() { return this.name; }
    public void setName(String name) { this.name = name;}
}
```

Die Builder für statische Schemas verfügen über eine entsprechende Methode zur Erstellung von Attributen. `attributeConverter()` Diese Methode benötigt eine Instanz von a, `AttributeConverter` wie im Folgenden gezeigt.

```
private static final StaticTableSchema<Customer> CUSTOMER_TABLE_SCHEMA =
  StaticTableSchema.builder(Customer.class)
    .newItemSupplier(Customer::new)
    .addAttribute(String.class, a -> a.name("name")
                                     a.getter(Customer::getName)
                                     a.setter(Customer::setName)
                                     a.attributeConverter(customAttributeConverter))
    .build();
```

## Beispiel
<a name="ddb-en-client-adv-features-conversion-example"></a>

Dieses Beispiel zeigt eine `AttributeConverterProvider` Implementierung, die einen Attributkonverter für [https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/HttpCookie.html](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/net/HttpCookie.html)Objekte bereitstellt. 

Die folgende `SimpleUser` Klasse enthält ein Attribut mit dem Namen`lastUsedCookie`, das eine Instanz von ist`HttpCookie`.

Der Parameter für die `@DynamoDbBean` Anmerkungen listet die beiden `AttributeConverterProvider` Klassen auf, die Konverter bereitstellen.

------
#### [ Class with annotations ]

```
    @DynamoDbBean(converterProviders = {CookieConverterProvider.class, DefaultAttributeConverterProvider.class})
    public static final class SimpleUser {
        private String name;
        private HttpCookie lastUsedCookie;

        @DynamoDbPartitionKey
        public String getName() {
            return name;
        }

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

        public HttpCookie getLastUsedCookie() {
            return lastUsedCookie;
        }

        public void setLastUsedCookie(HttpCookie lastUsedCookie) {
            this.lastUsedCookie = lastUsedCookie;
        }
```

------
#### [ Static table schema ]

```
    private static final TableSchema<SimpleUser> SIMPLE_USER_TABLE_SCHEMA =
            TableSchema.builder(SimpleUser.class)
                    .newItemSupplier(SimpleUser::new)
                    .attributeConverterProviders(CookieConverterProvider.create(), AttributeConverterProvider.defaultProvider())
                    .addAttribute(String.class, a -> a.name("name")
                            .setter(SimpleUser::setName)
                            .getter(SimpleUser::getName)
                            .tags(StaticAttributeTags.primaryPartitionKey()))
                    .addAttribute(HttpCookie.class, a -> a.name("lastUsedCookie")
                            .setter(SimpleUser::setLastUsedCookie)
                            .getter(SimpleUser::getLastUsedCookie))
                    .build();
```

------

Das `CookieConverterProvider` folgende Beispiel bietet eine Instanz `HttpCookeConverter` von.

```
    public static final class CookieConverterProvider implements AttributeConverterProvider {
        private final Map<EnhancedType<?>, AttributeConverter<?>> converterCache = ImmutableMap.of(
                // 1. Add HttpCookieConverter to the internal cache.
                EnhancedType.of(HttpCookie.class), new HttpCookieConverter());

        public static CookieConverterProvider create() {
            return new CookieConverterProvider();
        }

        // The SDK calls this method to find out if the provider contains a AttributeConverter instance
        // for the EnhancedType<T> argument.
        @SuppressWarnings("unchecked")
        @Override
        public <T> AttributeConverter<T> converterFor(EnhancedType<T> enhancedType) {
            return (AttributeConverter<T>) converterCache.get(enhancedType);
        }
    }
```

### Konvertierungscode
<a name="ddb-en-client-adv-features-conversion-example-code"></a>

In der `transformFrom()` Methode der folgenden `HttpCookieConverter` Klasse empfängt der Code eine `HttpCookie` Instanz und wandelt sie in eine DynamoDB-Map um, die als Attribut gespeichert wird.

Die `transformTo()` Methode empfängt einen DynamoDB-Zuordnungsparameter und ruft dann den `HttpCookie` Konstruktor auf, der einen Namen und einen Wert benötigt.

```
    public static final class HttpCookieConverter implements AttributeConverter<HttpCookie> {

        @Override
        public AttributeValue transformFrom(HttpCookie httpCookie) {

            return AttributeValue.fromM(
            Map.of ("cookieName", AttributeValue.fromS(httpCookie.getName()),
                    "cookieValue", AttributeValue.fromS(httpCookie.getValue()))
            );
        }

        @Override
        public HttpCookie transformTo(AttributeValue attributeValue) {
            Map<String, AttributeValue> map = attributeValue.m();
            return new HttpCookie(
                    map.get("cookieName").s(),
                    map.get("cookieValue").s());
        }

        @Override
        public EnhancedType<HttpCookie> type() {
            return EnhancedType.of(HttpCookie.class);
        }

        @Override
        public AttributeValueType attributeValueType() {
            return AttributeValueType.M;
        }
    }
```

# Ändern Sie das Aktualisierungsverhalten von Attributen
<a name="ddb-en-client-adv-features-upd-behavior"></a>

Sie können das Aktualisierungsverhalten einzelner Attribute anpassen, wenn Sie einen *Aktualisierungsvorgang* durchführen. [Einige Beispiele für Aktualisierungsvorgänge in der DynamoDB Enhanced Client API sind [updateItem () und ()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html#updateItem(T)). transactWriteItems](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html#transactWriteItems(java.util.function.Consumer))

Stellen Sie sich zum Beispiel vor, Sie möchten einen *am erstellten* Zeitstempel in Ihrem Datensatz speichern. Sie möchten jedoch, dass sein Wert nur geschrieben wird, wenn für das Attribut noch kein Wert in der Datenbank vorhanden ist. In diesem Fall verwenden Sie das `[WRITE\$1IF\$1NOT\$1EXISTS](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/UpdateBehavior.html#WRITE_IF_NOT_EXISTS)` Aktualisierungsverhalten.

Das folgende Beispiel zeigt die Anmerkung, die dem `createdOn` Attribut das Verhalten hinzufügt.

```
@DynamoDbBean
public class Customer extends GenericRecord {
    private String id;
    private Instant createdOn;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }
    public void setId(String id) { this.name = id; }

    @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS)
    public Instant getCreatedOn() { return this.createdOn; }    
    public void setCreatedOn(Instant createdOn) { this.createdOn = createdOn; }
}
```

Sie können dasselbe Aktualisierungsverhalten deklarieren, wenn Sie ein statisches Tabellenschema erstellen, wie im folgenden Beispiel nach Kommentarzeile 1 gezeigt.

```
static final TableSchema<Customer> CUSTOMER_TABLE_SCHEMA =
     TableSchema.builder(Customer.class)
       .newItemSupplier(Customer::new)
       .addAttribute(String.class, a -> a.name("id")
                                         .getter(Customer::getId)
                                         .setter(Customer::setId)
                                         .tags(StaticAttributeTags.primaryPartitionKey()))
       .addAttribute(Instant.class, a -> a.name("createdOn")
                                          .getter(Customer::getCreatedOn)
                                          .setter(Customer::setCreatedOn)
                                          // 1. Add an UpdateBehavior.
                                          .tags(StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS)))
       .build();
```

# Reduzieren Sie Attribute aus anderen Klassen
<a name="ddb-en-client-adv-features-flatmap"></a>

Wenn die Attribute für Ihre Tabelle entweder durch Vererbung oder Zusammensetzung auf mehrere verschiedene Java-Klassen verteilt sind, bietet die DynamoDB Enhanced Client-API Unterstützung, um die Attribute zu einer Klasse zusammenzufassen.

## Verwenden Sie Vererbung
<a name="ddb-en-client-adv-features-flatmap-inheritance"></a>

Wenn Ihre Klassen Vererbung verwenden, verwenden Sie die folgenden Methoden, um die Hierarchie zu vereinfachen.

### Verwenden Sie Beans mit Anmerkungen
<a name="ddb-en-client-adv-features-flatmap-inheritance-anno"></a>

Für den Annotationsansatz müssen beide Klassen die `@DynamoDbBean` Annotation enthalten und eine Klasse muss eine oder mehrere Primärschlüssel-Annotationen enthalten.

Im Folgenden werden Beispiele für Datenklassen gezeigt, die eine Vererbungsbeziehung haben.

------
#### [ Standard data class ]

```
@DynamoDbBean
public class Customer extends GenericRecord {
    private String name;

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

@DynamoDbBean
public abstract class GenericRecord {
    private String id;
    private String createdDate;

    @DynamoDbPartitionKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

Die [`onMethod`Option](https://projectlombok.org/features/experimental/onX) von Lombok kopiert attributbasierte DynamoDB-Anmerkungen, wie z. B., in den generierten Code. `@DynamoDbPartitionKey`

```
@DynamoDbBean
@Data
@ToString(callSuper = true)
public class Customer extends GenericRecord {
    private String name;
}

@Data
@DynamoDbBean
public abstract class GenericRecord {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;
    private String createdDate;
}
```

------

### Verwenden Sie statische Schemas
<a name="ddb-en-client-adv-features-flatmap-inheritance-static"></a>

Verwenden Sie für den statischen Schemaansatz die `extend()` Methode des Builders, um die Attribute der übergeordneten Klasse auf die untergeordnete Klasse zu reduzieren. Dies wird im folgenden Beispiel nach Kommentarzeile 1 gezeigt.

```
        StaticTableSchema<org.example.tests.model.inheritance.stat.GenericRecord> GENERIC_RECORD_SCHEMA =
                StaticTableSchema.builder(org.example.tests.model.inheritance.stat.GenericRecord.class)
                        // The partition key will be inherited by the top level mapper.
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(org.example.tests.model.inheritance.stat.GenericRecord::getId)
                                .setter(org.example.tests.model.inheritance.stat.GenericRecord::setId)
                                .tags(primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("created_date")
                                .getter(org.example.tests.model.inheritance.stat.GenericRecord::getCreatedDate)
                                .setter(org.example.tests.model.inheritance.stat.GenericRecord::setCreatedDate))
                        .build();

        StaticTableSchema<org.example.tests.model.inheritance.stat.Customer> CUSTOMER_SCHEMA =
                StaticTableSchema.builder(org.example.tests.model.inheritance.stat.Customer.class)
                        .newItemSupplier(org.example.tests.model.inheritance.stat.Customer::new)
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(org.example.tests.model.inheritance.stat.Customer::getName)
                                .setter(org.example.tests.model.inheritance.stat.Customer::setName))
                        // 1. Use the extend() method to collapse the parent attributes onto the child class.
                        .extend(GENERIC_RECORD_SCHEMA)     // All the attributes of the GenericRecord schema are added to Customer.
                        .build();
```

Das vorherige Beispiel für ein statisches Schema verwendet die folgenden Datenklassen. Da die Zuordnung beim Erstellen des statischen Tabellenschemas definiert wird, benötigen die Datenklassen keine Anmerkungen.

#### Datenklassen
<a name="gunk"></a>

------
#### [ Standard data class ]

```
public class Customer extends GenericRecord {
    private String name;

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


public abstract class GenericRecord {
    private String id;
    private String createdDate;

    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
```

------
#### [ Lombok ]

```
@Data
@ToString(callSuper = true)
public class Customer extends GenericRecord{
    private String name;
}

@Data
public abstract class GenericRecord {
    private String id;
    private String createdDate;
}
```

------

## Verwenden Sie Zusammensetzung
<a name="ddb-en-client-adv-features-flatmap-comp"></a>

Wenn in Ihren Klassen Komposition verwendet wird, verwenden Sie die folgenden Methoden, um die Hierarchie zu vereinfachen.

### Verwenden Sie Beans mit Anmerkungen
<a name="ddb-en-client-adv-features-flatmap-comp-anno"></a>

Die `@DynamoDbFlatten` Anmerkung reduziert die enthaltene Klasse.

In den folgenden Beispielen für Datenklassen wird die `@DynamoDbFlatten` Anmerkung verwendet, um der Klasse effektiv alle Attribute der enthaltenen `GenericRecord` Klasse hinzuzufügen. `Customer`

------
#### [ Standard data class ]

```
@DynamoDbBean
public class Customer {
    private String name;
    private GenericRecord record;

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

    @DynamoDbFlatten
    public GenericRecord getRecord() { return this.record; }
    public void setRecord(GenericRecord record) { this.record = record; }

@DynamoDbBean
public class GenericRecord {
    private String id;
    private String createdDate;

    @DynamoDbPartitionKey
    public String getId() { return this.id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return this.createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

```
@Data
@DynamoDbBean
public class Customer {
    private String name;
    @Getter(onMethod_=@DynamoDbFlatten)
    private GenericRecord record;
}

@Data
@DynamoDbBean
public class GenericRecord {
    @Getter(onMethod_=@DynamoDbPartitionKey)
    private String id;
    private String createdDate;
}
```

------

Sie können die Annotation Flatten verwenden, um so viele verschiedene geeignete Klassen wie nötig zu reduzieren. Die folgenden Einschränkungen gelten:
+ Alle Attributnamen müssen eindeutig sein, nachdem sie reduziert wurden.
+ Es darf nie mehr als einen Partitionsschlüssel, Sortierschlüssel oder Tabellennamen geben.

### Verwenden Sie statische Schemas
<a name="ddb-en-client-adv-features-flatmap-comp-static"></a>

Wenn Sie ein statisches Tabellenschema erstellen, verwenden Sie die `flatten()` Methode des Builders. Sie stellen auch die Getter- und Setter-Methoden bereit, die die enthaltene Klasse identifizieren.

```
        StaticTableSchema<GenericRecord> GENERIC_RECORD_SCHEMA =
                StaticTableSchema.builder(GenericRecord.class)
                        .newItemSupplier(GenericRecord::new)
                        .addAttribute(String.class, a -> a.name("id")
                                .getter(GenericRecord::getId)
                                .setter(GenericRecord::setId)
                                .tags(primaryPartitionKey()))
                        .addAttribute(String.class, a -> a.name("created_date")
                                .getter(GenericRecord::getCreatedDate)
                                .setter(GenericRecord::setCreatedDate))
                        .build();

        StaticTableSchema<Customer> CUSTOMER_SCHEMA =
                StaticTableSchema.builder(Customer.class)
                        .newItemSupplier(Customer::new)
                        .addAttribute(String.class, a -> a.name("name")
                                .getter(Customer::getName)
                                .setter(Customer::setName))
                        // Because we are flattening a component object, we supply a getter and setter so the
                        // mapper knows how to access it.
                        .flatten(GENERIC_RECORD_SCHEMA, Customer::getRecord, Customer::setRecord)
                        .build();
```

Das vorherige Beispiel für ein statisches Schema verwendet die folgenden Datenklassen.

#### Datenklassen
<a name="ddb-en-client-adv-features-flatmap-comp-static-supporting"></a>

------
#### [ Standard data class ]

```
public class Customer {
    private String name;
    private GenericRecord record;

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

    public GenericRecord getRecord() { return this.record; }
    public void setRecord(GenericRecord record) { this.record = record; }

public class GenericRecord {
    private String id;
    private String createdDate;

    public String getId() { return this.id; }
    public void setId(String id) { this.id = id; }

    public String getCreatedDate() { return this.createdDate; }
    public void setCreatedDate(String createdDate) { this.createdDate = createdDate; }
}
```

------
#### [ Lombok ]

```
@Data
public class Customer {
    private String name;
    private GenericRecord record;
}

@Data
public class GenericRecord {
    private String id;
    private String createdDate;
}
```

------

Sie können das Builder-Muster verwenden, um so viele verschiedene in Frage kommende Klassen zu reduzieren, wie Sie möchten.

## Implikationen für anderen Code
<a name="ddb-en-client-adv-features-flatmap-compare"></a>

Wenn Sie das `@DynamoDbFlatten` Attribut (oder die `flatten()` Builder-Methode) verwenden, enthält das Element in DynamoDB ein Attribut für jedes Attribut des erstellten Objekts. Es enthält auch die Attribute des zusammengesetzten Objekts. 

Wenn Sie dagegen eine Datenklasse mit einer zusammengesetzten Klasse annotieren und diese nicht verwenden`@DynamoDbFlatten`, wird das Element zusammen mit dem zusammengesetzten Objekt als einzelnes Attribut gespeichert.

Vergleichen Sie beispielsweise die im [Beispiel „Reduzieren mit Komposition“ gezeigte `Customer` Klasse mit](#ddb-en-client-adv-features-flatmap-comp-anno) und ohne Reduzierung des Attributs. `record` Sie können den Unterschied mit JSON visualisieren, wie in der folgenden Tabelle dargestellt.


****  

| Mit Abflachen | Ohne Abflachen | 
| --- | --- | 
| 3 Attribute | 2 Attribute | 
|  <pre>{<br />  "id": "1",<br />  "createdDate": "today",<br />  "name": "my name"<br />}</pre>  |  <pre>{<br />  "id": "1",<br />  "record": {<br />      "createdDate": "today",<br />      "name": "my name"<br />  }<br />}</pre>  | 

Der Unterschied wird wichtig, wenn Sie anderen Code haben, der auf die DynamoDB-Tabelle zugreift und erwartet, bestimmte Attribute zu finden.

# Arbeiten Sie mit Attributen wie Beans, Maps, Listen und Sets
<a name="ddb-en-client-adv-features-nested"></a>

Eine Bean-Definition, wie die unten gezeigte `Person` Klasse, könnte Eigenschaften (oder Attribute) definieren, die sich auf Typen mit zusätzlichen Attributen beziehen. In der `Person` Klasse `mainAddress` handelt es sich beispielsweise um eine Eigenschaft, die sich auf ein `Address` Bean bezieht, das zusätzliche Wertattribute definiert. `addresses`bezieht sich auf eine Java-Map, deren Elemente sich auf `Address` Beans beziehen. Diese komplexen Typen können als Container mit einfachen Attributen betrachtet werden, die Sie für ihren Datenwert im Kontext von DynamoDB verwenden. 

*DynamoDB bezeichnet die Werteigenschaften verschachtelter Elemente wie Maps, Listen oder Beans als verschachtelte Attribute.* Im [Amazon DynamoDB Developer Guide](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html#HowItWorks.DataTypes) wird die gespeicherte Form einer Java-Map, -Liste oder -Bean als *Dokumenttyp* bezeichnet. Einfache Attribute, die Sie in Java für ihren Datenwert verwenden, werden in DynamoDB als *skalare Typen* bezeichnet. *Mengen, die mehrere skalare Elemente desselben Typs enthalten und als Mengentypen bezeichnet werden.* 

Es ist wichtig zu wissen, dass die DynamoDB Enhanced Client-API eine Eigenschaft, die Bean ist, beim Speichern in einen DynamoDB-Kartendokumenttyp konvertiert.

## `Person`-Klasse
<a name="ddb-en-client-adv-features-nested-person"></a>

```
@DynamoDbBean
public class Person {
    private Integer id;
    private String firstName;
    private String lastName;
    private Integer age;
    private Address mainAddress;
    private Map<String, Address> addresses;
    private List<PhoneNumber> phoneNumbers;
    private Set<String> hobbies;

    @DynamoDbPartitionKey
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Address getMainAddress() {
        return mainAddress;
    }

    public void setMainAddress(Address mainAddress) {
        this.mainAddress = mainAddress;
    }

    public Map<String, Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(Map<String, Address> addresses) {
        this.addresses = addresses;
    }

    public List<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }

    public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
        this.phoneNumbers = phoneNumbers;
    }

    public Set<String> getHobbies() {
        return hobbies;
    }

    public void setHobbies(Set<String> hobbies) {
        this.hobbies = hobbies;
    }

    @Override
    public String toString() {
        return "Person{" +
               "addresses=" + addresses +
               ", id=" + id +
               ", firstName='" + firstName + '\'' +
               ", lastName='" + lastName + '\'' +
               ", age=" + age +
               ", mainAddress=" + mainAddress +
               ", phoneNumbers=" + phoneNumbers +
               ", hobbies=" + hobbies +
               '}';
    }
}
```

## `Address`-Klasse
<a name="ddb-en-client-adv-features-nested-address"></a>

```
@DynamoDbBean
public class Address {
    private String street;
    private String city;
    private String state;
    private String zipCode;

    public Address() {
    }

    public String getStreet() {
        return this.street;
    }

    public String getCity() {
        return this.city;
    }

    public String getState() {
        return this.state;
    }

    public String getZipCode() {
        return this.zipCode;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public void setState(String state) {
        this.state = state;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Address address = (Address) o;
        return Objects.equals(street, address.street) && Objects.equals(city, address.city) && Objects.equals(state, address.state) && Objects.equals(zipCode, address.zipCode);
    }

    @Override
    public int hashCode() {
        return Objects.hash(street, city, state, zipCode);
    }

    @Override
    public String toString() {
        return "Address{" +
                "street='" + street + '\'' +
                ", city='" + city + '\'' +
                ", state='" + state + '\'' +
                ", zipCode='" + zipCode + '\'' +
                '}';
    }
}
```

## `PhoneNumber`-Klasse
<a name="ddb-en-client-adv-features-nested-phonenumber"></a>

```
@DynamoDbBean
public class PhoneNumber {
    String type;
    String number;

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    @Override
    public String toString() {
        return "PhoneNumber{" +
                "type='" + type + '\'' +
                ", number='" + number + '\'' +
                '}';
    }
}
```

## Speichern Sie komplexe Typen
<a name="ddb-en-client-adv-features-nested-mapping"></a>

### Verwenden Sie annotierte Datenklassen
<a name="ddb-en-client-adv-features-nested-map-anno"></a>

Sie speichern verschachtelte Attribute für benutzerdefinierte Klassen, indem Sie sie einfach mit Anmerkungen versehen. Die `Address` Klasse und die `PhoneNumber` Klasse, die zuvor gezeigt wurden, sind nur mit der Anmerkung annotiert. `@DynamoDbBean` Wenn die DynamoDB Enhanced Client-API das Tabellenschema für die `Person` Klasse mit dem folgenden Codeausschnitt erstellt, erkennt die API die Verwendung der `PhoneNumber` Klassen `Address` und und erstellt die entsprechenden Mappings für die Arbeit mit DynamoDB.

```
TableSchema<Person> personTableSchema = TableSchema.fromBean(Person.class);
```

### Verwenden Sie abstrakte Schemas mit Buildern
<a name="ddb-en-client-adv-features-nested-map-builder"></a>

Der alternative Ansatz besteht darin, Schema-Builder für statische Tabellen für jede verschachtelte Bean-Klasse zu verwenden, wie im folgenden Code gezeigt.

Die Tabellenschemas für die `PhoneNumber` Klassen `Address` und sind abstrakt in dem Sinne, dass sie nicht mit einer DynamoDB-Tabelle verwendet werden können. Das liegt daran, dass ihnen Definitionen für den Primärschlüssel fehlen. Sie werden jedoch als verschachtelte Schemas im Tabellenschema für die `Person` Klasse verwendet.

Nach den Kommentarzeilen 1 und 2 in der Definition von sehen Sie den Code`PERSON_TABLE_SCHEMA`, der die abstrakten Tabellenschemas verwendet. Die Verwendung von `documentOf` in der `EnhanceType.documentOf(...)` Methode bedeutet nicht, dass die Methode einen `EnhancedDocument` Typ der Enhanced Document API zurückgibt. Die `documentOf(...)` Methode gibt in diesem Kontext ein Objekt zurück, das weiß, wie es sein Klassenargument mithilfe des Tabellenschema-Arguments DynamoDB-Tabellenattributen zuordnen kann.

#### Statischer Schemacode
<a name="ddb-en-client-adv-features-nested-map-builder-code"></a>

```
    // Abstract table schema that cannot be used to work with a DynamoDB table,
    // but can be used as a nested schema.
    public static final TableSchema<Address> TABLE_SCHEMA_ADDRESS = TableSchema.builder(Address.class)
        .newItemSupplier(Address::new)
        .addAttribute(String.class, a -> a.name("street")
            .getter(Address::getStreet)
            .setter(Address::setStreet))
        .addAttribute(String.class, a -> a.name("city")
            .getter(Address::getCity)
            .setter(Address::setCity))
        .addAttribute(String.class, a -> a.name("zipcode")
            .getter(Address::getZipCode)
            .setter(Address::setZipCode))
        .addAttribute(String.class, a -> a.name("state")
            .getter(Address::getState)
            .setter(Address::setState))
        .build();

    // Abstract table schema that cannot be used to work with a DynamoDB table,
    // but can be used as a nested schema.
    public static final TableSchema<PhoneNumber> TABLE_SCHEMA_PHONENUMBER = TableSchema.builder(PhoneNumber.class)
        .newItemSupplier(PhoneNumber::new)
        .addAttribute(String.class, a -> a.name("type")
            .getter(PhoneNumber::getType)
            .setter(PhoneNumber::setType))
        .addAttribute(String.class, a -> a.name("number")
            .getter(PhoneNumber::getNumber)
            .setter(PhoneNumber::setNumber))
        .build();

    // A static table schema that can be used with a DynamoDB table.
    // The table schema contains two nested schemas that are used to perform mapping to/from DynamoDB.
    public static final TableSchema<Person> PERSON_TABLE_SCHEMA =
        TableSchema.builder(Person.class)
            .newItemSupplier(Person::new)
            .addAttribute(Integer.class, a -> a.name("id")
                .getter(Person::getId)
                .setter(Person::setId)
                .addTag(StaticAttributeTags.primaryPartitionKey()))
            .addAttribute(String.class, a -> a.name("firstName")
                .getter(Person::getFirstName)
                .setter(Person::setFirstName))
            .addAttribute(String.class, a -> a.name("lastName")
                .getter(Person::getLastName)
                .setter(Person::setLastName))
            .addAttribute(Integer.class, a -> a.name("age")
                .getter(Person::getAge)
                .setter(Person::setAge))
            .addAttribute(EnhancedType.documentOf(Address.class, TABLE_SCHEMA_ADDRESS), a -> a.name("mainAddress")
                .getter(Person::getMainAddress)
                .setter(Person::setMainAddress))
            .addAttribute(EnhancedType.listOf(String.class), a -> a.name("hobbies")
                .getter(Person::getHobbies)
                .setter(Person::setHobbies))
            .addAttribute(EnhancedType.mapOf(
                EnhancedType.of(String.class),
                // 1. Use mapping functionality of the Address table schema.
                EnhancedType.documentOf(Address.class, TABLE_SCHEMA_ADDRESS)), a -> a.name("addresses")
                .getter(Person::getAddresses)
                .setter(Person::setAddresses))
            .addAttribute(EnhancedType.listOf(
                // 2. Use mapping functionality of the PhoneNumber table schema.
                EnhancedType.documentOf(PhoneNumber.class, TABLE_SCHEMA_PHONENUMBER)), a -> a.name("phoneNumbers")
                .getter(Person::getPhoneNumbers)
                .setter(Person::setPhoneNumbers))
            .build();
```

## Projektattribute komplexer Typen
<a name="ddb-en-client-adv-features-nested-projection"></a>

Für `query()` und `scan()` Methoden können Sie mithilfe von Methodenaufrufen wie `addNestedAttributeToProject()` und angeben, welche Attribute in den Ergebnissen zurückgegeben werden sollen`attributesToProject()`. Die DynamoDB Enhanced Client API konvertiert die Parameter des Java-Methodenaufrufs in [Projektionsausdrücke](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.ProjectionExpressions.html), bevor die Anforderung gesendet wird.

Das folgende Beispiel füllt die `Person` Tabelle mit zwei Elementen und führt dann drei Scanvorgänge durch. 

Beim ersten Scan werden alle Elemente in der Tabelle abgerufen, um die Ergebnisse mit den anderen Scanvorgängen zu vergleichen. 

Der zweite Scan verwendet die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/ScanEnhancedRequest.Builder.html#addNestedAttributeToProject(software.amazon.awssdk.enhanced.dynamodb.NestedAttributeName)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/ScanEnhancedRequest.Builder.html#addNestedAttributeToProject(software.amazon.awssdk.enhanced.dynamodb.NestedAttributeName))Builder-Methode, um nur den `street` Attributwert zurückzugeben.

Der dritte Scanvorgang verwendet die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/ScanEnhancedRequest.Builder.html#attributesToProject(java.lang.String...)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/ScanEnhancedRequest.Builder.html#attributesToProject(java.lang.String...))Builder-Methode, um die Daten für das Attribut der ersten Ebene zurückzugeben,`hobbies`. Der Attributtyp von `hobbies` ist eine Liste. Um auf einzelne Listenelemente zuzugreifen, führen Sie einen `get()` Vorgang in der Liste aus.

```
        personDynamoDbTable = getDynamoDbEnhancedClient().table("Person", PERSON_TABLE_SCHEMA);
        PersonUtils.createPersonTable(personDynamoDbTable, getDynamoDbClient());
        // Use a utility class to add items to the Person table.
        List<Person> personList = PersonUtils.getItemsForCount(2);
        // This utility method performs a put against DynamoDB to save the instances in the list argument.
        PersonUtils.putCollection(getDynamoDbEnhancedClient(), personList, personDynamoDbTable);

        // The first scan logs all items in the table to compare to the results of the subsequent scans.
        final PageIterable<Person> allItems = personDynamoDbTable.scan();
        allItems.items().forEach(p ->
                // 1. Log what is in the table.
                logger.info(p.toString()));

        // Scan for nested attributes.
        PageIterable<Person> streetScanResult = personDynamoDbTable.scan(b -> b
                // Use the 'addNestedAttributeToProject()' or 'addNestedAttributesToProject()' to access data nested in maps in DynamoDB.
                .addNestedAttributeToProject(
                        NestedAttributeName.create("addresses", "work", "street")
                ));

        streetScanResult.items().forEach(p ->
                //2. Log the results of requesting nested attributes.
                logger.info(p.toString()));

        // Scan for a top-level list attribute.
        PageIterable<Person> hobbiesScanResult = personDynamoDbTable.scan(b -> b
                // Use the 'attributesToProject()' method to access first-level attributes.
                .attributesToProject("hobbies"));

        hobbiesScanResult.items().forEach((p) -> {
            // 3. Log the results of the request for the 'hobbies' attribute.
            logger.info(p.toString());
            // To access an item in a list, first get the parent attribute, 'hobbies', then access items in the list.
            String hobby = p.getHobbies().get(1);
            // 4. Log an item in the list.
            logger.info(hobby);
        });
```

```
// Logged results from comment line 1.
Person{id=2, firstName='first name 2', lastName='last name 2', age=11, addresses={work=Address{street='street 21', city='city 21', state='state 21', zipCode='33333'}, home=Address{street='street 2', city='city 2', state='state 2', zipCode='22222'}}, phoneNumbers=[PhoneNumber{type='home', number='222-222-2222'}, PhoneNumber{type='work', number='333-333-3333'}], hobbies=[hobby 2, hobby 21]}
Person{id=1, firstName='first name 1', lastName='last name 1', age=11, addresses={work=Address{street='street 11', city='city 11', state='state 11', zipCode='22222'}, home=Address{street='street 1', city='city 1', state='state 1', zipCode='11111'}}, phoneNumbers=[PhoneNumber{type='home', number='111-111-1111'}, PhoneNumber{type='work', number='222-222-2222'}], hobbies=[hobby 1, hobby 11]}

// Logged results from comment line 2.
Person{id=null, firstName='null', lastName='null', age=null, addresses={work=Address{street='street 21', city='null', state='null', zipCode='null'}}, phoneNumbers=null, hobbies=null}
Person{id=null, firstName='null', lastName='null', age=null, addresses={work=Address{street='street 11', city='null', state='null', zipCode='null'}}, phoneNumbers=null, hobbies=null}

// Logged results from comment lines 3 and 4.
Person{id=null, firstName='null', lastName='null', age=null, addresses=null, phoneNumbers=null, hobbies=[hobby 2, hobby 21]}
hobby 21
Person{id=null, firstName='null', lastName='null', age=null, addresses=null, phoneNumbers=null, hobbies=[hobby 1, hobby 11]}
hobby 11
```

**Anmerkung**  
Wenn die `attributesToProject()` Methode einer anderen Builder-Methode folgt, die Attribute hinzufügt, die Sie projizieren möchten, `attributesToProject()` ersetzt die mitgelieferte Liste der Attributnamen alle anderen Attributnamen.  
Ein Scan, der mit der `ScanEnhancedRequest` Instanz im folgenden Codeausschnitt durchgeführt wird, gibt nur Hobbydaten zurück.  

```
ScanEnhancedRequest lastOverwrites = ScanEnhancedRequest.builder()
        .addNestedAttributeToProject(
                NestedAttributeName.create("addresses", "work", "street"))
        .addAttributeToProject("firstName")
        // If the 'attributesToProject()' method follows other builder methods that add attributes for projection,
        // its list of attributes replace all previous attributes.
        .attributesToProject("hobbies")
        .build();
PageIterable<Person> hobbiesOnlyResult = personDynamoDbTable.scan(lastOverwrites);
hobbiesOnlyResult.items().forEach(p ->
        logger.info(p.toString()));

// Logged results.
Person{id=null, firstName='null', lastName='null', age=null, addresses=null, phoneNumbers=null, hobbies=[hobby 2, hobby 21]}
Person{id=null, firstName='null', lastName='null', age=null, addresses=null, phoneNumbers=null, hobbies=[hobby 1, hobby 11]}
```
Der folgende Codeausschnitt verwendet die Methode zuerst. `attributesToProject()` Bei dieser Reihenfolge werden alle anderen angeforderten Attribute beibehalten.  

```
ScanEnhancedRequest attributesPreserved = ScanEnhancedRequest.builder()
        // Use 'attributesToProject()' first so that the method call does not replace all other attributes
        // that you want to project.
        .attributesToProject("firstName")
        .addNestedAttributeToProject(
                NestedAttributeName.create("addresses", "work", "street"))
        .addAttributeToProject("hobbies")
        .build();
PageIterable<Person> allAttributesResult = personDynamoDbTable.scan(attributesPreserved);
allAttributesResult.items().forEach(p ->
        logger.info(p.toString()));

// Logged results.
Person{id=null, firstName='first name 2', lastName='null', age=null, addresses={work=Address{street='street 21', city='null', state='null', zipCode='null'}}, phoneNumbers=null, hobbies=[hobby 2, hobby 21]}
Person{id=null, firstName='first name 1', lastName='null', age=null, addresses={work=Address{street='street 11', city='null', state='null', zipCode='null'}}, phoneNumbers=null, hobbies=[hobby 1, hobby 11]}
```

## Verwenden Sie komplexe Typen in Ausdrücken
<a name="ddb-en-client-adv-features-nested-expressions"></a>

Sie können komplexe Typen in Ausdrücken wie Filterausdrücken und Bedingungsausdrücken verwenden, indem Sie Dereferenzierungsoperatoren verwenden, um in der Struktur des komplexen Typs zu navigieren. Verwenden Sie für Objekte und Maps das `. (dot)` und für Listenelemente use `[n]` (eckige Klammern um die Sequenznummer des Elements). Sie können nicht auf einzelne Elemente einer Menge verweisen, aber Sie können die [`contains`Funktion](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.OperatorsAndFunctions.html#Expressions.OperatorsAndFunctions.Functions) verwenden.

Das folgende Beispiel zeigt zwei Filterausdrücke, die bei Scanvorgängen verwendet werden. Die Filterausdrücke geben die Übereinstimmungsbedingungen für Elemente an, die Sie in den Ergebnissen haben möchten. In dem Beispiel werden `Person` die zuvor gezeigten `PhoneNumber` Klassen`Address`, und verwendet.

```
    public void scanUsingFilterOfNestedAttr() {
        // The following is a filter expression for an attribute that is a map of Address objects.
        // By using this filter expression, the SDK returns Person objects that have an address
        // with 'mailing' as a key and 'MS2' for a state value.
        Expression addressFilter = Expression.builder()
                .expression("addresses.#type.#field = :value")
                .putExpressionName("#type", "mailing")
                .putExpressionName("#field", "state")
                .putExpressionValue(":value", AttributeValue.builder().s("MS2").build())
                .build();

        PageIterable<Person> addressFilterResults = personDynamoDbTable.scan(rb -> rb.
                filterExpression(addressFilter));
        addressFilterResults.items().stream().forEach(p -> logger.info("Person: {}", p));

        assert addressFilterResults.items().stream().count() == 1;


        // The following is a filter expression for an attribute that is a list of phone numbers.
        // By using this filter expression, the SDK returns Person objects whose second phone number
        // in the list has a type equal to 'cell'.
        Expression phoneFilter = Expression.builder()
                .expression("phoneNumbers[1].#type = :type")
                .putExpressionName("#type", "type")
                .putExpressionValue(":type", AttributeValue.builder().s("cell").build())
                .build();

        PageIterable<Person> phoneFilterResults = personDynamoDbTable.scan(rb -> rb
                .filterExpression(phoneFilter)
                .attributesToProject("id", "firstName", "lastName", "phoneNumbers")
        );

        phoneFilterResults.items().stream().forEach(p -> logger.info("Person: {}", p));

        assert phoneFilterResults.items().stream().count() == 1;
        assert phoneFilterResults.items().stream().findFirst().get().getPhoneNumbers().get(1).getType().equals("cell");
    }
```

### Hilfsmethode, die die Tabelle auffüllt
<a name="nested-expressions-helper-method"></a>

```
    public static void populateDatabase() {
        Person person1 = new Person();
        person1.setId(1);
        person1.setFirstName("FirstName1");
        person1.setLastName("LastName1");

        Address billingAddr1 = new Address();
        billingAddr1.setState("BS1");
        billingAddr1.setCity("BillingTown1");

        Address mailing1 = new Address();
        mailing1.setState("MS1");
        mailing1.setCity("MailingTown1");

        person1.setAddresses(Map.of("billing", billingAddr1, "mailing", mailing1));

        PhoneNumber pn1_1 = new PhoneNumber();
        pn1_1.setType("work");
        pn1_1.setNumber("111-111-1111");

        PhoneNumber pn1_2 = new PhoneNumber();
        pn1_2.setType("home");
        pn1_2.setNumber("222-222-2222");

        List<PhoneNumber> phoneNumbers1 = List.of(pn1_1, pn1_2);
        person1.setPhoneNumbers(phoneNumbers1);

        personDynamoDbTable.putItem(person1);

        Person person2 = person1;
        person2.setId(2);
        person2.setFirstName("FirstName2");
        person2.setLastName("LastName2");

        Address billingAddress2 = billingAddr1;
        billingAddress2.setCity("BillingTown2");
        billingAddress2.setState("BS2");

        Address mailing2 = mailing1;
        mailing2.setCity("MailingTown2");
        mailing2.setState("MS2");

        person2.setAddresses(Map.of("billing", billingAddress2, "mailing", mailing2));

        PhoneNumber pn2_1 = new PhoneNumber();
        pn2_1.setType("work");
        pn2_1.setNumber("333-333-3333");

        PhoneNumber pn2_2 = new PhoneNumber();
        pn2_2.setType("cell");
        pn2_2.setNumber("444-444-4444");

        List<PhoneNumber> phoneNumbers2 = List.of(pn2_1, pn2_2);
        person2.setPhoneNumbers(phoneNumbers2);

        personDynamoDbTable.putItem(person2);
    }
```

### JSON-Darstellung von Elementen in der Datenbank
<a name="nested-attributes-expression-json-items"></a>

```
{
 "id": 1,
 "addresses": {
  "billing": {
   "city": "BillingTown1",
   "state": "BS1",
   "street": null,
   "zipCode": null
  },
  "mailing": {
   "city": "MailingTown1",
   "state": "MS1",
   "street": null,
   "zipCode": null
  }
 },
 "firstName": "FirstName1",
 "lastName": "LastName1",
 "phoneNumbers": [
  {
   "number": "111-111-1111",
   "type": "work"
  },
  {
   "number": "222-222-2222",
   "type": "home"
  }
 ]
}

{
 "id": 2,
 "addresses": {
  "billing": {
   "city": "BillingTown2",
   "state": "BS2",
   "street": null,
   "zipCode": null
  },
  "mailing": {
   "city": "MailingTown2",
   "state": "MS2",
   "street": null,
   "zipCode": null
  }
 },
 "firstName": "FirstName2",
 "lastName": "LastName2",
 "phoneNumbers": [
  {
   "number": "333-333-3333",
   "type": "work"
  },
  {
   "number": "444-444-4444",
   "type": "cell"
  }
 ]
}
```

## Aktualisieren Sie Elemente, die komplexe Typen enthalten
<a name="ddb-en-client-adv-features-nested-updates"></a>

Um ein Element zu aktualisieren, das komplexe Typen enthält, haben Sie zwei grundlegende Methoden:
+ Ansatz 1: Rufen Sie zuerst das Element ab (mithilfe von`getItem`), aktualisieren Sie das Objekt und rufen Sie es dann auf`DynamoDbTable#updateItem`.
+ Ansatz 2: Rufen Sie das Element nicht ab, sondern erstellen Sie eine neue Instanz, legen Sie die Eigenschaften fest, die Sie aktualisieren möchten, und leiten Sie die Instanz weiter, `DynamoDbTable#updateItem` indem Sie den entsprechenden Wert von festlegen [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/IgnoreNullsMode.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/IgnoreNullsMode.html). Bei diesem Ansatz müssen Sie das Element nicht abrufen, bevor Sie es aktualisieren.

Die in diesem Abschnitt gezeigten Beispiele verwenden die zuvor aufgeführten `PhoneNumber` Klassen `Person``Address`, und.

### Aktualisierungsansatz 1: Abrufen, dann aktualisieren
<a name="ddb-en-client-adv-features-nested-updates-retreive"></a>

Mit diesem Ansatz stellen Sie sicher, dass beim Update keine Daten verloren gehen. Die DynamoDB Enhanced Client API erstellt die Bean mit den Attributen des in DynamoDB gespeicherten Elements neu, einschließlich Werten komplexer Typen. Anschließend müssen Sie die Getter und Setter verwenden, um die Bean zu aktualisieren. Der Nachteil dieses Ansatzes sind die Kosten, die Ihnen entstehen, wenn Sie den Artikel zuerst abrufen.

Das folgende Beispiel zeigt, dass keine Daten verloren gehen, wenn Sie das Element zuerst abrufen, bevor Sie es aktualisieren.

```
    public void retrieveThenUpdateExample()  {
        // Assume that we ran this code yesterday.
        Person person = new Person();
        person.setId(1);
        person.setFirstName("FirstName");
        person.setLastName("LastName");

        Address mainAddress = new Address();
        mainAddress.setStreet("123 MyStreet");
        mainAddress.setCity("MyCity");
        mainAddress.setState("MyState");
        mainAddress.setZipCode("MyZipCode");
        person.setMainAddress(mainAddress);

        PhoneNumber homePhone = new PhoneNumber();
        homePhone.setNumber("1111111");
        homePhone.setType("HOME");
        person.setPhoneNumbers(List.of(homePhone));

        personDynamoDbTable.putItem(person);

        // Assume that we are running this code now.
        // First, retrieve the item
        Person retrievedPerson = personDynamoDbTable.getItem(Key.builder().partitionValue(1).build());

        // Make any updates.
        retrievedPerson.getMainAddress().setCity("YourCity");

        // Save the updated bean. 'updateItem' returns the bean as it appears after the update.
        Person updatedPerson = personDynamoDbTable.updateItem(retrievedPerson);

        // Verify for this example.
        Address updatedMainAddress = updatedPerson.getMainAddress();
        assert updatedMainAddress.getCity().equals("YourCity");
        assert updatedMainAddress.getState().equals("MyState"); // Unchanged.
        // The list of phone numbers remains; it was not set to null;
        assert updatedPerson.getPhoneNumbers().size() == 1;
    }
```

### Aktualisierungsansatz 2: Verwenden Sie eine `IgnoreNullsMode` Aufzählung, ohne das Element zuerst abzurufen
<a name="ddb-en-client-adv-features-nested-updates-nullmode"></a>

Um ein Element in DynamoDB zu aktualisieren, können Sie ein neues Objekt angeben, das nur die Eigenschaften hat, die Sie aktualisieren möchten, und die anderen Werte auf Null belassen. Bei diesem Ansatz müssen Sie wissen, wie Nullwerte im Objekt vom SDK behandelt werden und wie Sie das Verhalten steuern können.

Um anzugeben, welche Eigenschaften mit Nullwerten das SDK ignorieren soll, geben Sie beim Erstellen des eine `IgnoreNullsMode` Aufzählung an. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/UpdateItemEnhancedRequest.Builder.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/model/UpdateItemEnhancedRequest.Builder.html) Als Beispiel für die Verwendung eines der Aufzählungswerte verwendet der folgende Codeausschnitt den Modus. `IgnoreNullsMode.SCALAR_ONLY`

```
// Create a new Person object to update the existing item in DynamoDB.
Person personForUpdate = new Person();
personForUpdate.setId(1);
personForUpdate.setFirstName("updatedFirstName");  // 'firstName' is a top scalar property.

Address addressForUpdate = new Address();
addressForUpdate.setCity("updatedCity");
personForUpdate.setMainAddress(addressForUpdate);

personDynamoDbTable.updateItem(r -> r
                .item(personForUpdate)
                .ignoreNullsMode(IgnoreNullsMode.SCALAR_ONLY));

/* With IgnoreNullsMode.SCALAR_ONLY provided, The SDK ignores all null properties. The SDK adds or replaces
the 'firstName' property with the provided value, "updatedFirstName". The SDK updates the 'city' value of
'mainAddress', as long as the 'mainAddress' attribute already exists in DynamoDB.

In the background, the SDK generates an update expression that it sends in the request to DynamoDB.
The following JSON object is a simplified version of what it sends. Notice that the SDK includes the paths
to 'mainAddress.city' and 'firstName' in the SET clause of the update expression. No null values in
'personForUpdate' are included.

{
  "TableName": "PersonTable",
  "Key": {
    "id": {
      "N": "1"
    }
  },
  "ReturnValues": "ALL_NEW",
  "UpdateExpression": "SET #mainAddress.#city = :mainAddress_city, #firstName = :firstName",
  "ExpressionAttributeNames": {
    "#city": "city",
    "#firstName": "firstName",
    "#mainAddress": "mainAddress"
  },
  "ExpressionAttributeValues": {
    ":firstName": {
      "S": "updatedFirstName"
    },
    ":mainAddress_city": {
      "S": "updatedCity"
    }
  }
}

Had we chosen 'IgnoreNullsMode.DEFAULT' instead of 'IgnoreNullsMode.SCALAR_ONLY', the SDK would have included
null values in the "ExpressionAttributeValues" section of the request as shown in the following snippet.

  "ExpressionAttributeValues": {
    ":mainAddress": {
      "M": {
        "zipCode": {
          "NULL": true
        },
        "city": {
          "S": "updatedCity"
        },
        "street": {
          "NULL": true
        },
        "state": {
          "NULL": true
        }
      }
    },
    ":firstName": {
      "S": "updatedFirstName"
    }
  }
*/
```

Das Amazon DynamoDB DynamoDB-Entwicklerhandbuch enthält weitere Informationen zu [Aktualisierungsausdrücken](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html).

#### Beschreibungen der Optionen `IgnoreNullsMode`
<a name="ignore-nulls-mode-descriptions"></a>
+ `IgnoreNullsMode.SCALAR_ONLY`- Verwenden Sie diese Einstellung, um skalare Attribute auf jeder Ebene zu aktualisieren. Das SDK erstellt eine Aktualisierungsanweisung, die nur skalare Attribute ungleich Null an DynamoDB sendet. Das SDK ignoriert nullwertige, skalare Attribute einer Bean oder Map und behält den gespeicherten Wert in DynamoDB bei.

  Wenn Sie ein skalares Attribut von map oder bean aktualisieren, muss die Map bereits in DynamoDB vorhanden sein. Wenn Sie dem Objekt eine Map oder eine Bean hinzufügen, die noch nicht für das Objekt in DynamoDB vorhanden ist, erhalten Sie eine `DynamoDbException` mit der Meldung *Der im Aktualisierungsausdruck angegebene Dokumentpfad ist für die Aktualisierung ungültig*. Sie müssen `MAPS_ONLY` den Modus verwenden, um DynamoDB ein Bean oder eine Map hinzuzufügen, bevor Sie eines ihrer Attribute aktualisieren.
+ `IgnoreNullsMode.MAPS_ONLY`- Verwenden Sie diese Einstellung, um Eigenschaften hinzuzufügen oder zu ersetzen, bei denen es sich um eine Bean oder Map handelt. Das SDK ersetzt oder fügt alle im Objekt bereitgestellten Maps oder Beans hinzu. Alle Beans oder Maps, die im Objekt Null sind, werden ignoriert, wobei die in DynamoDB vorhandene Map beibehalten wird.
+ `IgnoreNullsMode.DEFAULT`— Mit dieser Einstellung ignoriert das SDK niemals Nullwerte. Skalare Attribute auf jeder Ebene, die Null sind, werden auf Null aktualisiert. Das SDK aktualisiert alle Bean-, Map-, List- oder Set-Eigenschaften mit Nullwert im Objekt in DynamoDB auf Null. Wenn Sie diesen Modus verwenden — oder keinen Modus angeben, da es der Standardmodus ist — sollten Sie das Element zuerst abrufen, damit Werte in DynamoDB nicht auf Null gesetzt werden, die im Objekt zur Aktualisierung bereitgestellt werden, es sei denn, Sie beabsichtigen, die Werte auf Null zu setzen.

Wenn Sie in allen Modi ein Objekt mit einer Liste oder einem Satz angeben`updateItem`, der nicht Null ist, wird die Liste oder der Satz in DynamoDB gespeichert. 

#### Warum die Modi?
<a name="ddb-en-client-adv-features-nested-updates-nullmodes-why"></a>

Wenn Sie ein Objekt mit einem Bean oder einer Map für die `updateItem` Methode bereitstellen, kann das SDK nicht sagen, ob es die Eigenschaftswerte in der Bean (oder die Eintragswerte in der Map) verwenden soll, um das Element zu aktualisieren, oder ob das Ganze das ersetzen bean/map soll, was in DynamoDB gespeichert wurde.

Ausgehend von unserem vorherigen Beispiel, das zuerst den Abruf des Elements zeigt, versuchen wir, das `city` Attribut von `mainAddress` ohne den Abruf zu aktualisieren.

```
/* The retrieval example saved the Person object with a 'mainAddress' property whose 'city' property value is "MyCity".
/* Note that we create a new Person with only the necessary information to update the city value
of the mainAddress. */
Person personForUpdate = new Person();
personForUpdate.setId(1);
// The update we want to make changes the city.
Address mainAddressForUpdate = new Address();
mainAddressForUpdate.setCity("YourCity");
personForUpdate.setMainAddress(mainAddressForUpdate);

// Lets' try the following:
Person updatedPerson = personDynamoDbTable.updateItem(personForUpdate);
/*
 Since we haven't retrieved the item, we don't know if the 'mainAddress' property
 already exists, so what update expression should the SDK generate?

A) Should it replace or add the 'mainAddress' with the provided object (setting all attributes to null other than city)
   as shown in the following simplified JSON?

      {
        "TableName": "PersonTable",
        "Key": {
          "id": {
            "N": "1"
          }
        },
        "ReturnValues": "ALL_NEW",
        "UpdateExpression": "SET #mainAddress = :mainAddress",
        "ExpressionAttributeNames": {
          "#mainAddress": "mainAddress"
        },
        "ExpressionAttributeValues": {
          ":mainAddress": {
            "M": {
              "zipCode": {
                "NULL": true
              },
              "city": {
                "S": "YourCity"
              },
              "street": {
                "NULL": true
              },
              "state": {
                "NULL": true
              }
            }
          }
        }
      }
 
B) Or should it update only the 'city' attribute of an existing 'mainAddress' as shown in the following simplified JSON?

      {
        "TableName": "PersonTable",
        "Key": {
          "id": {
            "N": "1"
          }
        },
        "ReturnValues": "ALL_NEW",
        "UpdateExpression": "SET #mainAddress.#city = :mainAddress_city",
        "ExpressionAttributeNames": {
          "#city": "city",
          "#mainAddress": "mainAddress"
        },
        "ExpressionAttributeValues": {
          ":mainAddress_city": {
            "S": "YourCity"
          }
        }
      }

However, assume that we don't know if the 'mainAddress' already exists. If it doesn't exist, the SDK would try to update 
an attribute of a non-existent map, which results in an exception.

In this particular case, we would likely select option B (SCALAR_ONLY) to retain the other values of the 'mainAddress'.
*/
```

Die folgenden beiden Beispiele zeigen die Verwendung der Werte `MAPS_ONLY` und der `SCALAR_ONLY` Aufzählungswerte. `MAPS_ONLY`fügt eine Map hinzu und `SCALAR_ONLY` aktualisiert eine Map.

##### `IgnoreNullsMode.MAPS_ONLY`Beispiel für
<a name="scalar-only-example"></a>

```
    public void mapsOnlyModeExample() {
        // Assume that we ran this code yesterday.
        Person person = new Person();
        person.setId(1);
        person.setFirstName("FirstName");

        personDynamoDbTable.putItem(person);

        // Assume that we are running this code now.

        /* Note that we create a new Person with only the necessary information to update the city value
        of the mainAddress. */
        Person personForUpdate = new Person();
        personForUpdate.setId(1);
        // The update we want to make changes the city.
        Address mainAddressForUpdate = new Address();
        mainAddressForUpdate.setCity("YourCity");
        personForUpdate.setMainAddress(mainAddressForUpdate);


        Person updatedPerson = personDynamoDbTable.updateItem(r -> r
                .item(personForUpdate)
                .ignoreNullsMode(IgnoreNullsMode.MAPS_ONLY)); // Since the mainAddress property does not exist, use MAPS_ONLY mode.
        assert updatedPerson.getMainAddress().getCity().equals("YourCity");
        assert updatedPerson.getMainAddress().getState() == null;
    }
```

##### `IgnoreNullsMode.SCALAR_ONLY example`
<a name="maps-only-example"></a>

```
    public void scalarOnlyExample() {
        // Assume that we ran this code yesterday.
        Person person = new Person();
        person.setId(1);
        Address mainAddress = new Address();
        mainAddress.setCity("MyCity");
        mainAddress.setState("MyState");
        person.setMainAddress(mainAddress);

        personDynamoDbTable.putItem(person);

        // Assume that we are running this code now.

        /* Note that we create a new Person with only the necessary information to update the city value
        of the mainAddress. */
        Person personForUpdate = new Person();
        personForUpdate.setId(1);
        // The update we want to make changes the city.
        Address mainAddressForUpdate = new Address();
        mainAddressForUpdate.setCity("YourCity");
        personForUpdate.setMainAddress(mainAddressForUpdate);

        Person updatedPerson = personDynamoDbTable.updateItem(r -> r
                .item(personForUpdate)
                .ignoreNullsMode(IgnoreNullsMode.SCALAR_ONLY)); // SCALAR_ONLY mode ignores null properties in the in mainAddress.
        assert updatedPerson.getMainAddress().getCity().equals("YourCity");
        assert updatedPerson.getMainAddress().getState().equals("MyState"); // The state property remains the same.
    }
```

In der folgenden Tabelle können Sie nachlesen, welche Nullwerte für jeden Modus ignoriert werden. Sie können oft mit beiden `SCALAR_ONLY` arbeiten, `MAPS_ONLY` außer wenn Sie mit Beans oder Maps arbeiten.


**Welche Eigenschaften mit Nullwert in dem Objekt, an das gesendet wurde, ignoriert `updateItem` das SDK für jeden Modus?**  

| Art der Eigenschaft | im Modus SCALAR\$1ONLY | im MAPS\$1ONLY-Modus | im DEFAULT-Modus | 
| --- | --- | --- | --- | 
| Oberster Skalar | Ja | Ja | Nein | 
| Bean oder Karte | Ja | Ja | Nein | 
| Skalarwert eines Bean- oder Map-Eintrags | Ja1 | Nr.2 | Nein | 
| Liste oder Satz | Ja | Ja | Nein | 

1 Dies setzt voraus, dass die Map bereits in DynamoDB vorhanden ist. Jeder Skalarwert — Null oder nicht Null — der Bean oder Map, die Sie im Objekt für die Aktualisierung angeben, erfordert, dass ein Pfad zu dem Wert in DynamoDB existiert. Das SDK erstellt mithilfe des Dereferenzierungsoperators einen Pfad zu dem Attribut, bevor es die Anforderung sendet. `. (dot)`

2 Da Sie den `MAPS_ONLY` Modus verwenden, um eine Bean oder Map vollständig zu ersetzen oder hinzuzufügen, werden alle Nullwerte in der Bean oder Map in der in DynamoDB gespeicherten Map beibehalten.

# Leere Objekte konservieren mit `@DynamoDbPreserveEmptyObject`
<a name="ddb-en-client-adv-features-empty"></a>

Wenn Sie eine Bean mit leeren Objekten in Amazon DynamoDB speichern und möchten, dass das SDK die leeren Objekte beim Abrufen neu erstellt, kommentieren Sie den Getter der inneren Bean mit. `@DynamoDbPreserveEmptyObject`

Um zu veranschaulichen, wie die Anmerkung funktioniert, verwendet das Codebeispiel die folgenden beiden Beans.

## Beispiel Bohnen
<a name="ddb-en-client-adv-features-empty-ex1"></a>

Die folgende Datenklasse enthält zwei `InnerBean` Felder. Die Getter-Methode,`getInnerBeanWithoutAnno()`, ist nicht mit annotiert. `@DynamoDbPreserveEmptyObject` Die `getInnerBeanWithAnno()` Methode ist mit Anmerkungen versehen.

```
@DynamoDbBean
public class MyBean {

    private String id;
    private String name;
    private InnerBean innerBeanWithoutAnno;
    private InnerBean innerBeanWithAnno;

    @DynamoDbPartitionKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

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

    public InnerBean getInnerBeanWithoutAnno() { return innerBeanWithoutAnno; }
    public void setInnerBeanWithoutAnno(InnerBean innerBeanWithoutAnno) { this.innerBeanWithoutAnno = innerBeanWithoutAnno; }

    @DynamoDbPreserveEmptyObject
    public InnerBean getInnerBeanWithAnno() { return innerBeanWithAnno; }
    public void setInnerBeanWithAnno(InnerBean innerBeanWithAnno) { this.innerBeanWithAnno = innerBeanWithAnno; }

    @Override
    public String toString() {
        return new StringJoiner(", ", MyBean.class.getSimpleName() + "[", "]")
                .add("innerBeanWithoutAnno=" + innerBeanWithoutAnno)
                .add("innerBeanWithAnno=" + innerBeanWithAnno)
                .add("id='" + id + "'")
                .add("name='" + name + "'")
                .toString();
    }
}
```

Instanzen der folgenden `InnerBean` Klasse sind Felder von `MyBean` und werden im Beispielcode als leere Objekte initialisiert.

```
@DynamoDbBean
public class InnerBean {

    private String innerBeanField;

    public String getInnerBeanField() {
        return innerBeanField;
    }

    public void setInnerBeanField(String innerBeanField) {
        this.innerBeanField = innerBeanField;
    }

    @Override
    public String toString() {
        return "InnerBean{" +
                "innerBeanField='" + innerBeanField + '\'' +
                '}';
    }
}
```

Das folgende Codebeispiel speichert ein `MyBean` Objekt mit initialisierten inneren Beans in DynamoDB und ruft dann das Element ab. Die protokollierte Ausgabe zeigt, dass das `innerBeanWithoutAnno` nicht initialisiert wurde, sondern erstellt wurde. `innerBeanWithAnno`

```
    public MyBean preserveEmptyObjectAnnoUsingGetItemExample(DynamoDbTable<MyBean> myBeanTable) {
        // Save an item to DynamoDB.
        MyBean bean = new MyBean();
        bean.setId("1");
        bean.setInnerBeanWithoutAnno(new InnerBean());   // Instantiate the inner bean.
        bean.setInnerBeanWithAnno(new InnerBean());      // Instantiate the inner bean.
        myBeanTable.putItem(bean);

        GetItemEnhancedRequest request = GetItemEnhancedRequest.builder()
                .key(Key.builder().partitionValue("1").build())
                .build();
        MyBean myBean = myBeanTable.getItem(request);

        logger.info(myBean.toString());
        // Output 'MyBean[innerBeanWithoutAnno=null, innerBeanWithAnno=InnerBean{innerBeanField='null'}, id='1', name='null']'.

        return myBean;
    }
```

## Alternatives statisches Schema
<a name="ddb-en-client-adv-features-empty-ex1-static"></a>

Sie können die folgende `StaticTableSchema` Version der Tabellenschemas anstelle der Anmerkungen auf den Beans verwenden.

```
    public static TableSchema<MyBean> buildStaticSchemas() {

        StaticTableSchema<InnerBean> innerBeanStaticTableSchema =
                StaticTableSchema.builder(InnerBean.class)
                        .newItemSupplier(InnerBean::new)
                        .addAttribute(String.class, a -> a.name("innerBeanField")
                                .getter(InnerBean::getInnerBeanField)
                                .setter(InnerBean::setInnerBeanField))
                        .build();

        return StaticTableSchema.builder(MyBean.class)
                .newItemSupplier(MyBean::new)
                .addAttribute(String.class, a -> a.name("id")
                        .getter(MyBean::getId)
                        .setter(MyBean::setId)
                        .addTag(primaryPartitionKey()))
                .addAttribute(String.class, a -> a.name("name")
                        .getter(MyBean::getName)
                        .setter(MyBean::setName))
                .addAttribute(EnhancedType.documentOf(InnerBean.class,
                                innerBeanStaticTableSchema),
                        a -> a.name("innerBean1")
                                .getter(MyBean::getInnerBeanWithoutAnno)
                                .setter(MyBean::setInnerBeanWithoutAnno))
                .addAttribute(EnhancedType.documentOf(InnerBean.class,
                                innerBeanStaticTableSchema,
                                b -> b.preserveEmptyObject(true)),
                        a -> a.name("innerBean2")
                                .getter(MyBean::getInnerBeanWithAnno)
                                .setter(MyBean::setInnerBeanWithAnno))
                .build();
    }
```

# Vermeiden Sie das Speichern von Null-Attributen verschachtelter Objekte
<a name="ddb-en-client-adv-features-ignore-null"></a>

Sie können Null-Attribute verschachtelter Objekte überspringen, wenn Sie ein Datenklassenobjekt in DynamoDB speichern, indem Sie die Anmerkung anwenden. `@DynamoDbIgnoreNulls` Im Gegensatz dazu werden Attribute der obersten Ebene mit Nullwerten niemals in der Datenbank gespeichert.

Um zu veranschaulichen, wie die Anmerkung funktioniert, verwendet das Codebeispiel die folgenden beiden Beans.

## Beispiel Bohnen
<a name="ddb-en-client-adv-features-ignore-null-ex1"></a>

Die folgende Datenklasse enthält zwei `InnerBean` Felder. Die Getter-Methode,`getInnerBeanWithoutAnno()`, ist nicht annotiert. Die `getInnerBeanWithIgnoreNullsAnno()` Methode ist mit annotiert. `@DynamoDbIgnoreNulls`

```
@DynamoDbBean
public class MyBean {

    private String id;
    private String name;
    private InnerBean innerBeanWithoutAnno;
    private InnerBean innerBeanWithIgnoreNullsAnno;

    @DynamoDbPartitionKey
    public String getId() { return id; }
    public void setId(String id) { this.id = id; }

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

    public InnerBean getInnerBeanWithoutAnno() { return innerBeanWithoutAnno; }
    public void setInnerBeanWithoutAnno(InnerBean innerBeanWithoutAnno) { this.innerBeanWithoutAnno = innerBeanWithoutAnno; }

    @DynamoDbIgnoreNulls
    public InnerBean getInnerBeanWithIgnoreNullsAnno() { return innerBeanWithIgnoreNullsAnno; }
    public void setInnerBeanWithIgnoreNullsAnno(InnerBean innerBeanWithAnno) { this.innerBeanWithIgnoreNullsAnno = innerBeanWithAnno; }

    @Override
    public String toString() {
        return new StringJoiner(", ", MyBean.class.getSimpleName() + "[", "]")
                .add("innerBeanWithoutAnno=" + innerBeanWithoutAnno)
                .add("innerBeanWithIgnoreNullsAnno=" + innerBeanWithIgnoreNullsAnno)
                .add("id='" + id + "'")
                .add("name='" + name + "'")
                .toString();
    }
}
```

Instanzen der folgenden `InnerBean` Klasse sind Felder von `MyBean` und werden im folgenden Beispielcode verwendet.

```
@DynamoDbBean
public class InnerBean {

    private String innerBeanFieldString;
    private Integer innerBeanFieldInteger;

    public String getInnerBeanFieldString() { return innerBeanFieldString; }
    public void setInnerBeanFieldString(String innerBeanFieldString) { this.innerBeanFieldString = innerBeanFieldString; }

    public Integer getInnerBeanFieldInteger() { return innerBeanFieldInteger; }
    public void setInnerBeanFieldInteger(Integer innerBeanFieldInteger) { this.innerBeanFieldInteger = innerBeanFieldInteger; }

    @Override
    public String toString() {
        return new StringJoiner(", ", InnerBean.class.getSimpleName() + "[", "]")
                .add("innerBeanFieldString='" + innerBeanFieldString + "'")
                .add("innerBeanFieldInteger=" + innerBeanFieldInteger)
                .toString();
    }
}
```

Im folgenden Codebeispiel wird ein `InnerBean` Objekt erstellt und nur einem seiner beiden Attribute ein Wert zugewiesen. 

```
    public void ignoreNullsAnnoUsingPutItemExample(DynamoDbTable<MyBean> myBeanTable) {
        // Create an InnerBean object and give only one attribute a value.
        InnerBean innerBeanOneAttributeSet = new InnerBean();
        innerBeanOneAttributeSet.setInnerBeanFieldInteger(200);

        // Create a MyBean instance and use the same InnerBean instance both for attributes.
        MyBean bean = new MyBean();
        bean.setId("1");
        bean.setInnerBeanWithoutAnno(innerBeanOneAttributeSet);
        bean.setInnerBeanWithIgnoreNullsAnno(innerBeanOneAttributeSet);

        Map<String, AttributeValue> itemMap = myBeanTable.tableSchema().itemToMap(bean, true);
        logger.info(itemMap.toString());
        // Log the map that is sent to the database.
        // {innerBeanWithIgnoreNullsAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200)}), id=AttributeValue(S=1), innerBeanWithoutAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200), innerBeanFieldString=AttributeValue(NUL=true)})}
        
        // Save the MyBean object to the table.
        myBeanTable.putItem(bean);
    }
```

Um die Low-Level-Daten zu visualisieren, die an DynamoDB gesendet werden, protokolliert der Code die Attributzuordnung, bevor das Objekt gespeichert wird. `MyBean`

Die protokollierte Ausgabe zeigt, dass ein Attribut `innerBeanWithIgnoreNullsAnno` ausgegeben wird,

```
innerBeanWithIgnoreNullsAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200)})
```

Die `innerBeanWithoutAnno` Instanz gibt zwei Attribute aus. Ein Attribut hat einen Wert von 200 und das andere ist ein Nullwertattribut.

```
innerBeanWithoutAnno=AttributeValue(M={innerBeanFieldInteger=AttributeValue(N=200), innerBeanFieldString=AttributeValue(NUL=true)})
```

## JSON-Darstellung der Attributzuordnung
<a name="ddb-en-client-adv-features-ignore-null-ex2"></a>

Die folgende JSON-Darstellung macht es einfacher, die in DynamoDB gespeicherten Daten zu sehen.

```
{
  "id": {
    "S": "1"
  },
  "innerBeanWithIgnoreNullsAnno": {
    "M": {
      "innerBeanFieldInteger": {
        "N": "200"
      }
    }
  },
  "innerBeanWithoutAnno": {
    "M": {
      "innerBeanFieldInteger": {
        "N": "200"
      },
      "innerBeanFieldString": {
        "NULL": true
      }
    }
  }
}
```

## Alternatives statisches Schema
<a name="ddb-en-client-adv-features-empty-ex1-static"></a>

Sie können die folgende `StaticTableSchema` Version der Tabellenschemas anstelle von Datenklassenanmerkungen verwenden.

```
public static TableSchema<MyBean> buildStaticSchemas() {

    StaticTableSchema<InnerBean> innerBeanStaticTableSchema =
        StaticTableSchema.builder(InnerBean.class)
            .newItemSupplier(InnerBean::new)
            .addAttribute(String.class, a -> a.name("innerBeanFieldString")
                .getter(InnerBean::getInnerBeanFieldString)
                .setter(InnerBean::setInnerBeanFieldString))
            .addAttribute(Integer.class, a -> a.name("innerBeanFieldInteger")
                .getter(InnerBean::getInnerBeanFieldInteger)
                .setter(InnerBean::setInnerBeanFieldInteger))
            .build();

    return StaticTableSchema.builder(MyBean.class)
        .newItemSupplier(MyBean::new)
        .addAttribute(String.class, a -> a.name("id")
            .getter(MyBean::getId)
            .setter(MyBean::setId)
            .addTag(primaryPartitionKey()))
        .addAttribute(String.class, a -> a.name("name")
            .getter(MyBean::getName)
            .setter(MyBean::setName))
        .addAttribute(EnhancedType.documentOf(InnerBean.class,
                innerBeanStaticTableSchema),
            a -> a.name("innerBeanWithoutAnno")
                .getter(MyBean::getInnerBeanWithoutAnno)
                .setter(MyBean::setInnerBeanWithoutAnno))
        .addAttribute(EnhancedType.documentOf(InnerBean.class,
                innerBeanStaticTableSchema,
                b -> b.ignoreNulls(true)),
            a -> a.name("innerBeanWithIgnoreNullsAnno")
                .getter(MyBean::getInnerBeanWithIgnoreNullsAnno)
                .setter(MyBean::setInnerBeanWithIgnoreNullsAnno))
        .build();
}
```

# Arbeiten Sie mit JSON-Dokumenten mit der Enhanced Document API für DynamoDB
<a name="ddb-en-client-doc-api"></a>

Die [Enhanced Document API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/package-summary.html) für AWS SDK for Java 2.x ist für die Arbeit mit dokumentenorientierten Daten konzipiert, die kein festes Schema haben. Sie können damit jedoch auch benutzerdefinierte Klassen verwenden, um einzelne Attribute zuzuordnen.

 Die Enhanced Document API ist der Nachfolger der [Document API](https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/dynamodbv2/document/DynamoDB.html) der AWS SDK für Java Version v1.x.

**Contents**
+ [Beginnen Sie mit der Verwendung der Enhanced Document API](ddb-en-client-doc-api-steps.md)
  + [Erstellen Sie ein und ein `DocumentTableSchema` `DynamoDbTable`](ddb-en-client-doc-api-steps.md#ddb-en-client-doc-api-steps-createschema)
+ [Erstellen Sie erweiterte Dokumente](ddb-en-client-doc-api-steps-create-ed.md)
  + [Aus einer JSON-Zeichenfolge erstellen](ddb-en-client-doc-api-steps-create-ed.md#ddb-en-client-doc-api-steps-create-ed-fromJson)
  + [Aus einzelnen Elementen zusammensetzen](ddb-en-client-doc-api-steps-create-ed.md#ddb-en-client-doc-api-steps-create-ed-fromparts)
+ [Führen Sie CRUD-Operationen durch](ddb-en-client-doc-api-steps-use.md)
+ [Greifen Sie als benutzerdefinierte Objekte auf erweiterte Dokumentattribute zu](ddb-en-client-doc-api-convert.md)
+ [Verwenden Sie eine `EnhancedDocument` ohne DynamoDB](ddb-en-client-doc-api-standalone.md)

# Beginnen Sie mit der Verwendung der Enhanced Document API
<a name="ddb-en-client-doc-api-steps"></a>

Die Enhanced Document API erfordert dieselben [Abhängigkeiten](ddb-en-client-getting-started.md#ddb-en-client-gs-dep) wie die DynamoDB Enhanced Client API. Außerdem ist eine [`DynamoDbEnhancedClient`Instanz](ddb-en-client-getting-started-dynamodbTable.md#ddb-en-client-getting-started-dynamodbTable-eclient) erforderlich, wie am Anfang dieses Themas beschrieben.

Da die Enhanced Document API mit Version 2.20.3 von veröffentlicht wurde AWS SDK for Java 2.x, benötigen Sie diese Version oder eine höhere Version.

## Erstellen Sie ein und ein `DocumentTableSchema` `DynamoDbTable`
<a name="ddb-en-client-doc-api-steps-createschema"></a>

[Um mithilfe der Enhanced Document API Befehle für eine DynamoDB-Tabelle aufzurufen, verknüpfen Sie die Tabelle mit einem clientseitigen DynamoDbTable < > -Ressourcenobjekt. EnhancedDocument](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html) 

Die `table()` Methode des erweiterten Clients erstellt eine `DynamoDbTable<EnhancedDocument>` Instanz und benötigt Parameter für den DynamoDB-Tabellennamen und a. `DocumentTableSchema` 

Der Builder für a [DocumentTableSchema](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/DocumentTableSchema.html)erfordert einen primären Indexschlüssel und einen oder mehrere Attributkonverter-Anbieter. Die `AttributeConverterProvider.defaultProvider()` Methode stellt Konverter für [Standardtypen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/internal/converter/attribute/package-summary.html) bereit. Sie sollte auch dann angegeben werden, wenn Sie einen benutzerdefinierten Attributkonverter-Anbieter angeben. Sie können dem Builder einen optionalen sekundären Indexschlüssel hinzufügen.

Der folgende Codeausschnitt zeigt den Code, der die clientseitige Darstellung einer DynamoDB-Tabelle generiert, in der schemalose Objekte gespeichert `person` werden. `EnhancedDocument`

```
DynamoDbTable<EnhancedDocument> documentDynamoDbTable = 
                enhancedClient.table("person",
                        TableSchema.documentSchemaBuilder()
                            // Specify the primary key attributes.
                            .addIndexPartitionKey(TableMetadata.primaryIndexName(),"id", AttributeValueType.S)
                            .addIndexSortKey(TableMetadata.primaryIndexName(), "lastName", AttributeValueType.S)
                            // Specify attribute converter providers. Minimally add the default one.
                            .attributeConverterProviders(AttributeConverterProvider.defaultProvider())
                            .build());
                                                         
// Call documentTable.createTable() if "person" does not exist in DynamoDB.
// createTable() should be called only one time.
```

Im Folgenden wird die JSON-Darstellung eines Objekts gezeigt, die in diesem Abschnitt verwendet wird`person`.

### `person`JSON-Objekt
<a name="ddb-en-client-doc-api-steps-createschema-obj"></a>

```
{
  "id": 1,
  "firstName": "Richard",
  "lastName": "Roe",
  "age": 25,
  "addresses":
    {
      "home": {
        "zipCode": "00000",
        "city": "Any Town",
        "state": "FL",
        "street": "123 Any Street"
      },
      "work": {
        "zipCode": "00001",
        "city": "Anywhere",
        "state": "FL",
        "street": "100 Main Street"
      }
    },
  "hobbies": [
    "Hobby 1",
    "Hobby 2"
  ],
  "phoneNumbers": [
    {
      "type": "Home",
      "number": "555-0100"
    },
    {
      "type": "Work",
      "number": "555-0119"
    }
  ]
}
```

# Erstellen Sie erweiterte Dokumente
<a name="ddb-en-client-doc-api-steps-create-ed"></a>

An `[EnhancedDocument](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/document/EnhancedDocument.html)` steht für ein Objekt vom Typ Dokument mit einer komplexen Struktur mit verschachtelten Attributen. An `EnhancedDocument` erfordert Attribute der obersten Ebene, die den für den angegebenen Primärschlüsselattributen entsprechen. `DocumentTableSchema` Der restliche Inhalt ist willkürlich und kann aus Attributen der obersten Ebene und auch tief verschachtelten Attributen bestehen.

Sie erstellen eine `EnhancedDocument` Instanz mithilfe eines Builders, der mehrere Möglichkeiten zum Hinzufügen von Elementen bietet.

## Aus einer JSON-Zeichenfolge erstellen
<a name="ddb-en-client-doc-api-steps-create-ed-fromJson"></a>

Mit einer JSON-Zeichenfolge können Sie einen Methodenaufruf `EnhancedDocument` in einem Schritt erstellen. Das folgende Snippet erstellt `EnhancedDocument` aus einer JSON-Zeichenfolge, die von der `jsonPerson()` Hilfsmethode zurückgegeben wird. Die `jsonPerson()` Methode gibt die JSON-String-Version des zuvor gezeigten [Personenobjekts](ddb-en-client-doc-api-steps.md#ddb-en-client-doc-api-steps-createschema-obj) zurück.

```
EnhancedDocument document = 
        EnhancedDocument.builder()
                        .json( jsonPerson() )
                        .build());
```

## Aus einzelnen Elementen zusammensetzen
<a name="ddb-en-client-doc-api-steps-create-ed-fromparts"></a>

Alternativ können Sie mit den typsicheren Methoden des Builders eine `EnhancedDocument` Instanz aus einzelnen Komponenten erstellen.

Im folgenden Beispiel wird ein `person` erweitertes Dokument erstellt, das dem erweiterten Dokument ähnelt, das aus der JSON-Zeichenfolge im vorherigen Beispiel erstellt wurde.

```
        /* Define the shape of an address map whose JSON representation looks like the following.
           Use 'addressMapEnhancedType' in the following EnhancedDocument.builder() to simplify the code.
           "home": {
             "zipCode": "00000",
             "city": "Any Town",
             "state": "FL",
             "street": "123 Any Street"
           }*/
        EnhancedType<Map<String, String>> addressMapEnhancedType =
                EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(String.class));


        //  Use the builder's typesafe methods to add elements to the enhanced document.
        EnhancedDocument personDocument = EnhancedDocument.builder()
                .putNumber("id", 50)
                .putString("firstName", "Shirley")
                .putString("lastName", "Rodriguez")
                .putNumber("age", 53)
                .putNull("nullAttribute")
                .putJson("phoneNumbers", phoneNumbersJSONString())
                /* Add the map of addresses whose JSON representation looks like the following.
                        {
                          "home": {
                            "zipCode": "00000",
                            "city": "Any Town",
                            "state": "FL",
                            "street": "123 Any Street"
                          }
                        } */
                .putMap("addresses", getAddresses(), EnhancedType.of(String.class), addressMapEnhancedType)
                .putList("hobbies", List.of("Theater", "Golf"), EnhancedType.of(String.class))
                .build();
```

### Hilfsmethoden
<a name="ddb-en-client-doc-api-steps-use-fromparts-helpers"></a>

```
    private static String phoneNumbersJSONString() {
        return "  [" +
                "    {" +
                "      \"type\": \"Home\"," +
                "      \"number\": \"555-0140\"" +
                "    }," +
                "    {" +
                "      \"type\": \"Work\"," +
                "      \"number\": \"555-0155\"" +
                "    }" +
                "  ]";
    }

    private static Map<String, Map<String, String>> getAddresses() {
        return Map.of(
                "home", Map.of(
                        "zipCode", "00002",
                        "city", "Any Town",
                        "state", "ME",
                        "street", "123 Any Street"));

    }
```

# Führen Sie CRUD-Operationen durch
<a name="ddb-en-client-doc-api-steps-use"></a>

Nachdem Sie eine `EnhancedDocument` Instanz definiert haben, können Sie sie in einer DynamoDB-Tabelle speichern. Der folgende Codeausschnitt verwendet das [PersonDocument, das aus einzelnen Elementen](ddb-en-client-doc-api-steps-create-ed.md#ddb-en-client-doc-api-steps-create-ed-fromparts) erstellt wurde.

```
documentDynamoDbTable.putItem(personDocument);
```

Nachdem Sie eine erweiterte Dokumentinstanz aus DynamoDB gelesen haben, können Sie die einzelnen Attributwerte mithilfe von Getter extrahieren, wie im folgenden Codeausschnitt gezeigt, die auf die Daten zugreifen, die aus dem gespeichert wurden. `personDocument` Alternativ können Sie den gesamten Inhalt in eine JSON-Zeichenfolge extrahieren, wie im letzten Teil des Beispielcodes gezeigt.

```
        // Read the item.
        EnhancedDocument personDocFromDb = documentDynamoDbTable.getItem(Key.builder().partitionValue(50).build());

        // Access top-level attributes.
        logger.info("Name: {} {}", personDocFromDb.getString("firstName"), personDocFromDb.getString("lastName"));
        // Name: Shirley Rodriguez

        // Typesafe access of a deeply nested attribute. The addressMapEnhancedType shown previously defines the shape of an addresses map.
        Map<String, Map<String, String>> addresses = personDocFromDb.getMap("addresses", EnhancedType.of(String.class), addressMapEnhancedType);
        addresses.keySet().forEach(k -> logger.info(addresses.get(k).toString()));
        // {zipCode=00002, city=Any Town, street=123 Any Street, state=ME}

        // Alternatively, work with AttributeValue types checking along the way for deeply nested attributes.
        Map<String, AttributeValue> addressesMap = personDocFromDb.getMapOfUnknownType("addresses");
        addressesMap.keySet().forEach((String k) -> {
            logger.info("Looking at data for [{}] address", k);
            // Looking at data for [home] address
            AttributeValue value = addressesMap.get(k);
            AttributeValue cityValue = value.m().get("city");
            if (cityValue != null) {
                logger.info(cityValue.s());
                // Any Town
            }
        });

        List<AttributeValue> phoneNumbers = personDocFromDb.getListOfUnknownType("phoneNumbers");
        phoneNumbers.forEach((AttributeValue av) -> {
            if (av.hasM()) {
                AttributeValue type = av.m().get("type");
                if (type.s() != null) {
                    logger.info("Type of phone: {}", type.s());
                    // Type of phone: Home
                    // Type of phone: Work
                }
            }
        });

        String jsonPerson = personDocFromDb.toJson();
        logger.info(jsonPerson);
        // {"firstName":"Shirley","lastName":"Rodriguez","addresses":{"home":{"zipCode":"00002","city":"Any Town","street":"123 Any Street","state":"ME"}},"hobbies":["Theater","Golf"],
        //     "id":50,"nullAttribute":null,"age":53,"phoneNumbers":[{"number":"555-0140","type":"Home"},{"number":"555-0155","type":"Work"}]}
```

`EnhancedDocument`Instanzen können mit jeder Methode von `[DynamoDbTable](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbTable.html)` oder [DynamoDbEnhancedClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedClient.html)anstelle von zugewiesenen Datenklassen verwendet werden.

# Greifen Sie als benutzerdefinierte Objekte auf erweiterte Dokumentattribute zu
<a name="ddb-en-client-doc-api-convert"></a>

Die Enhanced Document API bietet nicht nur eine API zum Lesen und Schreiben von Attributen mit schemalosen Strukturen, sondern ermöglicht auch die Konvertierung von Attributen in und aus Instanzen benutzerdefinierter Klassen.

Die Enhanced Document API verwendet `AttributeConverterProvider` s und `AttributeConverter` s, die im Abschnitt zur [Konvertierung von Steuerattributen](ddb-en-client-adv-features-conversion.md) als Teil der DynamoDB Enhanced Client API angezeigt wurden.

Im folgenden Beispiel verwenden wir a `CustomAttributeConverterProvider` mit seiner verschachtelten `AddressConverter` Klasse, um Objekte zu konvertieren. `Address` 

Dieses Beispiel zeigt, dass Sie Daten aus Klassen und auch Daten aus Strukturen kombinieren können, die nach Bedarf erstellt werden. Dieses Beispiel zeigt auch, dass benutzerdefinierte Klassen auf jeder Ebene einer verschachtelten Struktur verwendet werden können. Die `Address` Objekte in diesem Beispiel sind Werte, die in einer Map verwendet werden.

```
    public static void attributeToAddressClassMappingExample(DynamoDbEnhancedClient enhancedClient, DynamoDbClient standardClient) {
        String tableName = "customer";

        // Define the DynamoDbTable for an enhanced document.
        // The schema builder provides methods for attribute converter providers and keys.
        DynamoDbTable<EnhancedDocument> documentDynamoDbTable = enhancedClient.table(tableName,
                DocumentTableSchema.builder()
                        // Add the CustomAttributeConverterProvider along with the default when you build the table schema.
                        .attributeConverterProviders(
                                List.of(
                                        new CustomAttributeConverterProvider(),
                                        AttributeConverterProvider.defaultProvider()))
                        .addIndexPartitionKey(TableMetadata.primaryIndexName(), "id", AttributeValueType.N)
                        .addIndexSortKey(TableMetadata.primaryIndexName(), "lastName", AttributeValueType.S)
                        .build());
        // Create the DynamoDB table if needed.
        documentDynamoDbTable.createTable();
        waitForTableCreation(tableName, standardClient);


        // The getAddressesForCustomMappingExample() helper method that provides 'addresses' shows the use of a custom Address class
        // rather than using a Map<String, Map<String, String> to hold the address data.
        Map<String, Address> addresses = getAddressesForCustomMappingExample();

        // Build an EnhancedDocument instance to save an item with a mix of structures defined as needed and static classes.
        EnhancedDocument personDocument = EnhancedDocument.builder()
                .putNumber("id", 50)
                .putString("firstName", "Shirley")
                .putString("lastName", "Rodriguez")
                .putNumber("age", 53)
                .putNull("nullAttribute")
                .putJson("phoneNumbers", phoneNumbersJSONString())
                // Note the use of 'EnhancedType.of(Address.class)' instead of the more generic
                // 'EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(String.class))' that was used in a previous example.
                .putMap("addresses", addresses, EnhancedType.of(String.class), EnhancedType.of(Address.class))
                .putList("hobbies", List.of("Hobby 1", "Hobby 2"), EnhancedType.of(String.class))
                .build();
        // Save the item to DynamoDB.
        documentDynamoDbTable.putItem(personDocument);

        // Retrieve the item just saved.
        EnhancedDocument srPerson = documentDynamoDbTable.getItem(Key.builder().partitionValue(50).sortValue("Rodriguez").build());

        // Access the addresses attribute.
        Map<String, Address> srAddresses = srPerson.get("addresses",
                EnhancedType.mapOf(EnhancedType.of(String.class), EnhancedType.of(Address.class)));

        srAddresses.keySet().forEach(k -> logger.info(addresses.get(k).toString()));

        documentDynamoDbTable.deleteTable();

// The content logged to the console shows that the saved maps were converted to Address instances.
Address{street='123 Main Street', city='Any Town', state='NC', zipCode='00000'}
Address{street='100 Any Street', city='Any Town', state='NC', zipCode='00000'}
```

## `CustomAttributeConverterProvider`-Code
<a name="ddb-en-client-doc-api-convert-provider"></a>

```
public class CustomAttributeConverterProvider implements AttributeConverterProvider {

    private final Map<EnhancedType<?>, AttributeConverter<?>> converterCache = ImmutableMap.of(
            // 1. Add AddressConverter to the internal cache.
            EnhancedType.of(Address.class), new AddressConverter());

    public static CustomAttributeConverterProvider create() {
        return new CustomAttributeConverterProvider();
    }

    // 2. The enhanced client queries the provider for attribute converters if it
    //    encounters a type that it does not know how to convert.
    @SuppressWarnings("unchecked")
    @Override
    public <T> AttributeConverter<T> converterFor(EnhancedType<T> enhancedType) {
        return (AttributeConverter<T>) converterCache.get(enhancedType);
    }

    // 3. Custom attribute converter
    private class AddressConverter implements AttributeConverter<Address> {
        // 4. Transform an Address object into a DynamoDB map.
        @Override
        public AttributeValue transformFrom(Address address) {

            Map<String, AttributeValue> attributeValueMap = Map.of(
                    "street", AttributeValue.fromS(address.getStreet()),
                    "city", AttributeValue.fromS(address.getCity()),
                    "state", AttributeValue.fromS(address.getState()),
                    "zipCode", AttributeValue.fromS(address.getZipCode()));

            return AttributeValue.fromM(attributeValueMap);
        }

        // 5. Transform the DynamoDB map attribute to an Address oject.
        @Override
        public Address transformTo(AttributeValue attributeValue) {
            Map<String, AttributeValue> m = attributeValue.m();
            Address address = new Address();
            address.setStreet(m.get("street").s());
            address.setCity(m.get("city").s());
            address.setState(m.get("state").s());
            address.setZipCode(m.get("zipCode").s());

            return address;
        }

        @Override
        public EnhancedType<Address> type() {
            return EnhancedType.of(Address.class);
        }

        @Override
        public AttributeValueType attributeValueType() {
            return AttributeValueType.M;
        }
    }
}
```

## `Address`-Klasse
<a name="ddb-en-client-doc-api-convert-address"></a>

```
public class Address {
                  private String street;
                  private String city;
                  private String state;
                  private String zipCode;

                  public Address() {
                  }

                  public String getStreet() {
                  return this.street;
                  }

                  public String getCity() {
                  return this.city;
                  }

                  public String getState() {
                  return this.state;
                  }

                  public String getZipCode() {
                  return this.zipCode;
                  }

                  public void setStreet(String street) {
                  this.street = street;
                  }

                  public void setCity(String city) {
                  this.city = city;
                  }

                  public void setState(String state) {
                  this.state = state;
                  }

                  public void setZipCode(String zipCode) {
                  this.zipCode = zipCode;
                  }
                  }
```

## Hilfsmethode, die Adressen bereitstellt
<a name="ddb-en-client-doc-api-convert-helper"></a>

Die folgende Hilfsmethode stellt die Map bereit, die benutzerdefinierte `Address` Instanzen für Werte anstelle von generischen `Map<String, String>` Instanzen für Werte verwendet.

```
    private static Map<String, Address> getAddressesForCustomMappingExample() {
        Address homeAddress = new Address();
        homeAddress.setStreet("100 Any Street");
        homeAddress.setCity("Any Town");
        homeAddress.setState("NC");
        homeAddress.setZipCode("00000");

        Address workAddress = new Address();
        workAddress.setStreet("123 Main Street");
        workAddress.setCity("Any Town");
        workAddress.setState("NC");
        workAddress.setZipCode("00000");

        return Map.of("home", homeAddress,
                "work", workAddress);
    }
```

# Verwenden Sie eine `EnhancedDocument` ohne DynamoDB
<a name="ddb-en-client-doc-api-standalone"></a>

Normalerweise verwenden Sie eine Instanz von an, `EnhancedDocument` um DynamoDB-Elemente vom Typ Dokument zu lesen und zu schreiben, sie kann jedoch auch unabhängig von DynamoDB verwendet werden. 

Sie können ihre Fähigkeit verwenden`EnhancedDocuments`, zwischen JSON-Zeichenfolgen oder benutzerdefinierten Objekten in Low-Level-Maps von `AttributeValues` zu konvertieren, wie im folgenden Beispiel gezeigt.

```
    public static void conversionWithoutDynamoDbExample() {
        Address address = new Address();
        address.setCity("my city");
        address.setState("my state");
        address.setStreet("my street");
        address.setZipCode("00000");

        // Build an EnhancedDocument instance for its conversion functionality alone.
        EnhancedDocument addressEnhancedDoc = EnhancedDocument.builder()
                // Important: You must specify attribute converter providers when you build an EnhancedDocument instance not used with a DynamoDB table.
                .attributeConverterProviders(new CustomAttributeConverterProvider(), DefaultAttributeConverterProvider.create())
                .put("addressDoc", address, Address.class)
                .build();

        // Convert address to a low-level item representation.
        final Map<String, AttributeValue> addressAsAttributeMap = addressEnhancedDoc.getMapOfUnknownType("addressDoc");
        logger.info("addressAsAttributeMap: {}", addressAsAttributeMap.toString());

        // Convert address to a JSON string.
        String addressAsJsonString = addressEnhancedDoc.getJson("addressDoc");
        logger.info("addressAsJsonString: {}", addressAsJsonString);
        // Convert addressEnhancedDoc back to an Address instance.
        Address addressConverted =  addressEnhancedDoc.get("addressDoc", Address.class);
        logger.info("addressConverted: {}", addressConverted.toString());
    }

   /* Console output:
          addressAsAttributeMap: {zipCode=AttributeValue(S=00000), state=AttributeValue(S=my state), street=AttributeValue(S=my street), city=AttributeValue(S=my city)}
          addressAsJsonString: {"zipCode":"00000","state":"my state","street":"my street","city":"my city"}
          addressConverted: Address{street='my street', city='my city', state='my state', zipCode='00000'}
   */
```

**Anmerkung**  
Wenn Sie ein erweitertes Dokument verwenden, das unabhängig von einer DynamoDB-Tabelle ist, stellen Sie sicher, dass Sie im Builder explizit Attributkonverter-Anbieter festlegen.  
Im Gegensatz dazu stellt das Dokumenttabellenschema die Konverteranbieter bereit, wenn ein erweitertes Dokument mit einer DynamoDB-Tabelle verwendet wird.

# Verwenden Sie Erweiterungen, um DynamoDB Enhanced Client-Operationen anzupassen
<a name="ddb-en-client-extensions"></a>

Die DynamoDB Enhanced Client API unterstützt Plugin-Erweiterungen, die Funktionen bieten, die über Mapping-Operationen hinausgehen. Erweiterungen verwenden zwei Hook-Methoden, um Daten während Lese- und Schreibvorgängen zu ändern:
+ `beforeWrite()`- Ändert einen Schreibvorgang, bevor er stattfindet
+ `afterRead()`- Ändert die Ergebnisse eines Lesevorgangs, nachdem er ausgeführt wurde

Bei einigen Operationen (wie Artikelaktualisierungen) wird sowohl ein Schreib- als auch ein Lesevorgang ausgeführt, sodass beide Hook-Methoden aufgerufen werden.

## Wie werden Erweiterungen geladen
<a name="ddb-en-client-extensions-loading"></a>

Erweiterungen werden in der Reihenfolge geladen, die Sie im erweiterten Client Builder angegeben haben. Die Ladereihenfolge kann wichtig sein, da eine Erweiterung auf Werte reagieren kann, die durch eine vorherige Erweiterung transformiert wurden.

Standardmäßig lädt der erweiterte Client zwei Erweiterungen:
+ `[VersionedRecordExtension](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/extensions/VersionedRecordExtension.html)`- Sorgt für optimistisches Sperren
+ `[AtomicCounterExtension](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/extensions/AtomicCounterExtension.html)`- Inkrementiert automatisch die Zählerattribute

Sie können das Standardverhalten mit dem erweiterten Client Builder überschreiben und jede Erweiterung laden. Sie können auch keine angeben, wenn Sie die Standarderweiterungen nicht verwenden möchten.

**Wichtig**  
Wenn Sie Ihre eigenen Erweiterungen laden, lädt der erweiterte Client keine Standarderweiterungen. Wenn Sie das Verhalten einer der Standarderweiterungen verwenden möchten, müssen Sie sie explizit zur Liste der Erweiterungen hinzufügen.

Das folgende Beispiel zeigt, wie eine benutzerdefinierte Erweiterung geladen wird, die `verifyChecksumExtension` nach dem benannt ist`VersionedRecordExtension`. Die `AtomicCounterExtension` ist in diesem Beispiel nicht geladen.

```
DynamoDbEnhancedClientExtension versionedRecordExtension = VersionedRecordExtension.builder().build();

DynamoDbEnhancedClient enhancedClient = 
    DynamoDbEnhancedClient.builder()
                          .dynamoDbClient(dynamoDbClient)
                          .extensions(versionedRecordExtension, verifyChecksumExtension)
                          .build();
```

## Verfügbare Erweiterungsdetails und Konfiguration
<a name="ddb-en-client-extensions-details"></a>

Die folgenden Abschnitte enthalten detaillierte Informationen zu jeder verfügbaren Erweiterung im SDK.

### Implementieren Sie optimistisches Sperren mit dem `VersionedRecordExtension`
<a name="ddb-en-client-extensions-VRE"></a>

Die `VersionedRecordExtension` Erweiterung ermöglicht optimistisches Sperren, indem die Versionsnummer eines Elements beim Schreiben von Elementen in die Datenbank erhöht und nachverfolgt wird. Jedem Schreibvorgang wird eine Bedingung hinzugefügt, die dazu führt, dass der Schreibvorgang fehlschlägt, wenn die Versionsnummer des tatsächlich persistenten Elements nicht dem Wert entspricht, den die Anwendung zuletzt gelesen hat.

#### Konfiguration
<a name="ddb-en-client-extensions-VRE-conf"></a>

Um anzugeben, welches Attribut verwendet werden soll, um die Versionsnummer des Elements nachzuverfolgen, kennzeichnen Sie ein numerisches Attribut im Tabellenschema.

Der folgende Codeausschnitt gibt an, dass das `version` Attribut die Versionsnummer des Artikels enthalten soll.

```
    @DynamoDbVersionAttribute
    public Integer getVersion() {...};
    public void setVersion(Integer version) {...};
```

Der entsprechende Ansatz für ein statisches Tabellenschema wird im folgenden Codeausschnitt dargestellt.

```
    .addAttribute(Integer.class, a -> a.name("version")
                                       .getter(Customer::getVersion)
                                       .setter(Customer::setVersion)
                                        // Apply the 'version' tag to the attribute.
                                       .tags(VersionedRecordExtension.AttributeTags.versionAttribute())
```

#### Funktionsweise
<a name="ddb-en-client-extensions-VRE-how-it-works"></a>

Das optimistische Sperren mit dem `VersionedRecordExtension` hat folgende Auswirkungen auf diese `DynamoDbEnhancedClient` und `DynamoDbTable` Methoden:

**`putItem`**  
Neuen Elementen wird der ursprüngliche Versionswert 0 zugewiesen. Dies kann mit konfiguriert werden`@DynamoDbVersionAttribute(startAt = X)`.

**`updateItem`**  
Wenn Sie ein Element abrufen, eine oder mehrere seiner Eigenschaften aktualisieren und versuchen, die Änderungen zu speichern, ist der Vorgang nur erfolgreich, wenn die Versionsnummer auf der Client- und der Serverseite übereinstimmen.  
Bei Erfolg wird die Versionsnummer automatisch um 1 erhöht. Dies kann mit `@DynamoDbVersionAttribute(incrementBy = X)` konfiguriert werden.

**`deleteItem`**  
Die `DynamoDbVersionAttribute` Anmerkung hat keine Auswirkung. Sie müssen beim Löschen eines Elements manuell Bedingungsausdrücke hinzufügen.  
Im folgenden Beispiel wird ein bedingter Ausdruck hinzugefügt, um sicherzustellen, dass es sich bei dem gelöschten Element auch um das gelesene Element handelt. Im folgenden Beispiel `recordVersion` ist das Attribut der Bean mit `@DynamoDbVersionAttribute` annotiert.  

```
// 1. Read the item and get its current version.
Customer item = customerTable.getItem(Key.builder().partitionValue("someId").build());
// `recordVersion` is the bean's attribute that is annotated with `@DynamoDbVersionAttribute`.
AttributeValue currentVersion = item.getRecordVersion();

// 2. Create conditional delete with the `currentVersion` value.
DeleteItemEnhancedRequest deleteItemRequest =
    DeleteItemEnhancedRequest.builder()
       .key(KEY)
       .conditionExpression(Expression.builder()
           .expression("recordVersion = :current_version_value")
           .putExpressionValue(":current_version_value", currentVersion)
           .build()).build();

customerTable.deleteItem(deleteItemRequest);
```

**`transactWriteItems`**  
+ `addPutItem`: Diese Methode hat das gleiche Verhalten wie`putItem`.
+ `addUpdateItem`: Diese Methode hat das gleiche Verhalten wie`updateItem`.
+ `addDeleteItem`: Diese Methode hat das gleiche Verhalten wie`deleteItem`.

**`batchWriteItem`**  
+ `addPutItem`: Diese Methode hat das gleiche Verhalten wie`putItem`.
+ `addDeleteItem`: Diese Methode hat das gleiche Verhalten wie`deleteItem`.

**Anmerkung**  
Globale DynamoDB-Tabellen verwenden einen [Abgleich zwischen gleichzeitigen Aktualisierungen, bei dem DynamoDB sich nach besten Kräften bemüht, den letzten Writer](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables_HowItWorks.html#V2globaltables_HowItWorks.consistency-modes) zu ermitteln. Wenn Sie globale Tabellen verwenden, bedeutet diese „Last Writer gewinnt“ -Richtlinie, dass Sperrstrategien möglicherweise nicht wie erwartet funktionieren, da alle Replikate letztendlich auf der Grundlage des von DynamoDB bestimmten letzten Schreibvorgangs konvergieren. 

#### Wie deaktiviere ich
<a name="ddb-en-client-extensions-VRE-how-to-disable"></a>

Verwenden Sie die `@DynamoDbVersionAttribute` Anmerkung nicht, um das optimistische Sperren zu deaktivieren.

### Implementieren Sie Zähler mit dem `AtomicCounterExtension`
<a name="ddb-en-client-extensions-ACE"></a>

Die `AtomicCounterExtension` Erweiterung erhöht jedes Mal, wenn ein Datensatz in die Datenbank geschrieben wird, ein mit Tags versehenes numerisches Attribut. Sie können Start- und Inkrementwerte angeben. Wenn keine Werte angegeben sind, wird der Startwert auf 0 gesetzt und der Wert des Attributs wird um 1 erhöht.

#### Konfiguration
<a name="ddb-en-client-extensions-ACE-conf"></a>

Um anzugeben, welches Attribut ein Zähler ist, kennzeichnen Sie ein Attribut vom Typ `Long` im Tabellenschema.

Der folgende Ausschnitt zeigt die Verwendung der standardmäßigen Start- und Inkrementwerte für das Attribut. `counter`

```
    @DynamoDbAtomicCounter
    public Long getCounter() {...};
    public void setCounter(Long counter) {...};
```

Der Ansatz eines statischen Tabellenschemas wird im folgenden Codeausschnitt dargestellt. Die Atomic Counter Extension verwendet einen Startwert von 10 und erhöht den Wert jedes Mal, wenn der Datensatz geschrieben wird, um 5.

```
    .addAttribute(Integer.class, a -> a.name("counter")
                                       .getter(Customer::getCounter)
                                       .setter(Customer::setCounter)
                                        // Apply the 'atomicCounter' tag to the attribute with start and increment values.
                                       .tags(StaticAttributeTags.atomicCounter(10L, 5L))
```

### Fügen Sie Zeitstempel hinzu mit `AutoGeneratedTimestampRecordExtension`
<a name="ddb-en-client-extensions-AGTE"></a>

Die `AutoGeneratedTimestampRecordExtension` Erweiterung aktualisiert jedes Mal, wenn das Element erfolgreich in die Datenbank geschrieben wurde, automatisch markierte Attribute des Typs `[Instant](https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html)` mit einem aktuellen Zeitstempel. Diese Erweiterung ist standardmäßig nicht geladen.

#### Konfiguration
<a name="ddb-en-client-extensions-AGTE-conf"></a>

Um anzugeben, welches Attribut mit dem aktuellen Zeitstempel aktualisiert werden soll, kennzeichnen Sie das `Instant` Attribut im Tabellenschema.

Das `lastUpdate` Attribut ist das Ziel des Verhaltens der Erweiterung im folgenden Codeausschnitt. Beachten Sie die Anforderung, dass das Attribut ein `Instant` Typ sein muss.

```
    @DynamoDbAutoGeneratedTimestampAttribute
    public Instant getLastUpdate() {...}
    public void setLastUpdate(Instant lastUpdate) {...}
```

Der entsprechende Ansatz für ein statisches Tabellenschema wird im folgenden Codeausschnitt dargestellt.

```
     .addAttribute(Instant.class, a -> a.name("lastUpdate")
                                        .getter(Customer::getLastUpdate)
                                        .setter(Customer::setLastUpdate)
                                        // Applying the 'autoGeneratedTimestamp' tag to the attribute.
                                        .tags(AutoGeneratedTimestampRecordExtension.AttributeTags.autoGeneratedTimestampAttribute())
```

### Generieren Sie eine UUID mit dem AutoGeneratedUuidExtension
<a name="ddb-en-client-extensions-AGUE"></a>

Die `AutoGeneratedUuidExtension` Erweiterung generiert eine eindeutige UUID (Universally Unique Identifier) für ein Attribut, wenn ein neuer Datensatz in die Datenbank geschrieben wird. Verwendet die Java-JDK-Methode [UUID.randomUUID () und gilt für Typattribute](https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html#randomUUID--). `java.lang.String` Diese Erweiterung wird standardmäßig nicht geladen.

#### Konfiguration
<a name="ddb-en-client-extensions-AGUE-conf"></a>

Das `uniqueId` Attribut ist das Ziel des Verhaltens der Erweiterung im folgenden Codeausschnitt.

```
    @AutoGeneratedUuidExtension
    public String getUniqueId() {...}
    public void setUniqueId(String uniqueId) {...}
```

Der entsprechende Ansatz für ein statisches Tabellenschema wird im folgenden Codeausschnitt dargestellt.

```
     .addAttribute(String.class, a -> a.name("uniqueId")
                                        .getter(Customer::getUniqueId)
                                        .setter(Customer::setUniqueId)
                                        // Applying the 'autoGeneratedUuid' tag to the attribute.
                                        .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute())
```

Wenn Sie möchten, dass die Erweiterung die UUID nur für `putItem` Methoden und nicht für Methoden auffüllt, fügen Sie die Anmerkung zum `updateItem` [Aktualisierungsverhalten](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/mapper/UpdateBehavior.html) hinzu, wie im folgenden Codeausschnitt gezeigt.

```
    @AutoGeneratedUuidExtension
    @DynamoDbUpdateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS)
    public String getUniqueId() {...}
    public void setUniqueId(String uniqueId) {...}
```

Wenn Sie den Ansatz eines statischen Tabellenschemas verwenden, verwenden Sie den folgenden äquivalenten Code.

```
     .addAttribute(String.class, a -> a.name("uniqueId")
                                        .getter(Customer::getUniqueId)
                                        .setter(Customer::setUniqueId)
                                        // Applying the 'autoGeneratedUuid' tag to the attribute.
                                        .tags(AutoGeneratedUuidExtension.AttributeTags.autoGeneratedUuidAttribute(),
                                              StaticAttributeTags.updateBehavior(UpdateBehavior.WRITE_IF_NOT_EXISTS))
```

# Beispiel für eine benutzerdefinierte Erweiterung
<a name="ddb-en-client-extensions-custom"></a>

Sie können benutzerdefinierte Erweiterungen erstellen, indem Sie die `DynamoDbEnhancedClientExtension` Schnittstelle implementieren. Die folgende benutzerdefinierte Erweiterungsklasse zeigt eine `beforeWrite()` Methode, die einen Aktualisierungsausdruck verwendet, um ein `registrationDate` Attribut festzulegen, falls das Element in der Datenbank noch keines hat.

```
public final class CustomExtension implements DynamoDbEnhancedClientExtension {

    // 1. In a custom extension, use an UpdateExpression to define what action to take before
    //    an item is updated.
    @Override
    public WriteModification beforeWrite(DynamoDbExtensionContext.BeforeWrite context) {
        if ( context.operationContext().tableName().equals("Customer")
                && context.operationName().equals(OperationName.UPDATE_ITEM)) {
            return WriteModification.builder()
                    .updateExpression(createUpdateExpression())
                    .build();
        }
        return WriteModification.builder().build();  // Return an "empty" WriteModification instance if the extension should not be applied.
                                                     // In this case, if the code is not updating an item on the Customer table.
    }

    private static UpdateExpression createUpdateExpression() {

        // 2. Use a SetAction, a subclass of UpdateAction, to provide the values in the update.
        SetAction setAction =
                SetAction.builder()
                        .path("registrationDate")
                        .value("if_not_exists(registrationDate, :regValue)")
                        .putExpressionValue(":regValue", AttributeValue.fromS(Instant.now().toString()))
                        .build();
        // 3. Build the UpdateExpression with one or more UpdateAction.
        return UpdateExpression.builder()
                .addAction(setAction)
                .build();
    }
}
```

# Verwenden Sie die DynamoDB Enhanced Client API asynchron
<a name="ddb-en-client-async"></a>

Wenn Ihre Anwendung nicht blockierende, asynchrone Aufrufe von DynamoDB erfordert, können Sie den verwenden. [DynamoDbEnhancedAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/enhanced/dynamodb/DynamoDbEnhancedAsyncClient.html) Sie ähnelt der synchronen Implementierung, weist jedoch die folgenden wesentlichen Unterschiede auf:

1. Wenn Sie den erstellen`DynamoDbEnhancedAsyncClient`, müssen Sie die asynchrone Version des Standardclients bereitstellen`DynamoDbAsyncClient`, wie im folgenden Codeausschnitt dargestellt.

   ```
    DynamoDbEnhancedAsyncClient enhancedClient = 
        DynamoDbEnhancedAsyncClient.builder()
                                   .dynamoDbClient(dynamoDbAsyncClient)
                                   .build();
   ```

1. Methoden, die ein einzelnes Datenobjekt zurückgeben, geben nicht nur das Ergebnis zurück. `CompletableFuture` Ihre Anwendung kann dann andere Aufgaben ausführen, ohne das Ergebnis blockieren zu müssen. Der folgende Ausschnitt zeigt die asynchrone `getItem()` Methode. 

   ```
   CompletableFuture<Customer> result = customerDynamoDbTable.getItem(customer);
   // Perform other work here.
   return result.join();   // Now block and wait for the result.
   ```

1. Methoden, die paginierte Ergebnislisten zurückgeben, geben [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)statt eines 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), das die synchrone Methode für dieselben Methoden `DynamoDbEnhanceClient` zurückgibt. Ihre Anwendung kann dann einen Handler für diesen Herausgeber abonnieren, um die Ergebnisse asynchron zu verarbeiten, ohne sie blockieren zu müssen.

   ```
   PagePublisher<Customer> results = customerDynamoDbTable.query(r -> r.queryConditional(keyEqualTo(k -> k.partitionValue("Smith"))));
   results.subscribe(myCustomerResultsProcessor);
   // Perform other work and let the processor handle the results asynchronously.
   ```

   Ein vollständigeres Beispiel für die Arbeit mit dem `SdkPublisher API` finden Sie in [dem Beispiel](ddb-en-client-use-multirecord.md#ddb-en-client-use-multirecord-scan-async) in dem Abschnitt, in dem die asynchrone `scan()` Methode beschrieben wird.

# Anmerkungen zu Datenklassen
<a name="ddb-en-client-anno-index"></a>

In der folgenden Tabelle sind die Anmerkungen aufgeführt, die für Datenklassen verwendet werden können, und sie enthält Links zu Informationen und Beispielen in diesem Handbuch. Die Tabelle ist in aufsteigender alphabetischer Reihenfolge nach dem Namen der Anmerkung sortiert.


**Anmerkungen zur Datenklasse, die in diesem Handbuch verwendet werden**  

| Name der Anmerkung | Anmerkung bezieht sich auf 1 | Was macht es | Wo es in diesem Handbuch gezeigt wird | 
| --- | --- | --- | --- | 
| DynamoDbAtomicCounter | Attribut 2 | Inkrementiert ein mit Tags versehenes numerisches Attribut jedes Mal, wenn ein Datensatz in die Datenbank geschrieben wird. | [Einführung und Diskussion.](ddb-en-client-extensions.md#ddb-en-client-extensions-ACE) | 
| DynamoDbAttribute | Attribut | Definiert oder benennt eine Bean-Eigenschaft um, die einem DynamoDB-Tabellenattribut zugeordnet ist. |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbAutoGeneratedTimestampAttribute | Attribut | Aktualisiert jedes Mal, wenn das Element erfolgreich in die Datenbank geschrieben wurde, ein mit einem Tag versehenes Attribut mit einem aktuellen Zeitstempel | [Einführung und Diskussion](ddb-en-client-extensions.md#ddb-en-client-extensions-AGTE). | 
| DynamoDbAutoGeneratedUuid | Attribut | Generieren Sie eine eindeutige UUID (Universally Unique Identifier) für ein Attribut, wenn ein neuer Datensatz in die Datenbank geschrieben wird. | [Einführung und Diskussion.](ddb-en-client-extensions.md#ddb-en-client-extensions-AGUE) | 
| DynamoDbBean | class | Markiert eine Datenklasse als einem Tabellenschema zuordbar. | Erste Anwendung in der [Kundenklasse](ddb-en-client-gs-tableschema.md#ddb-en-client-gs-tableschema-anno-bean-cust) im Abschnitt Erste Schritte. Im gesamten Handbuch werden verschiedene Verwendungen verwendet. | 
| DynamoDbConvertedBy | Attribut | Ordnet dem annotierten AttributeConverter Attribut einen benutzerdefinierten Wert zu. | [Erste Diskussion und Beispiel.](ddb-en-client-adv-features-conversion.md#ddb-en-client-adv-features-conversion-single) | 
| DynamoDbFlatten | Attribut | Reduziert alle Attribute einer separaten DynamoDB-Datenklasse und fügt sie dem Datensatz, der in die Datenbank gelesen und geschrieben wird, als Attribute der obersten Ebene hinzu.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbIgnore | Attribut |  Führt dazu, dass das Attribut nicht zugeordnet wird.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbIgnoreNulls | Attribut | Verhindert das Speichern von Null-Attributen verschachtelter DynamoDb Objekte. | [Diskussion und Beispiele.](ddb-en-client-adv-features-ignore-null.md) | 
| DynamoDbImmutable | class |  Markiert eine unveränderliche Datenklasse als einem Tabellenschema zuordbar.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbPartitionKey | Attribut |  Markiert ein Attribut als primären Partitionsschlüssel (Hash-Schlüssel) der DynamoDb Tabelle.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbPreserveEmptyObject | Attribut |  Gibt an, dass das Objekt mit allen Nullfeldern initialisiert werden soll, wenn keine Daten für das Objekt vorhanden sind, das dem annotierten Attribut zugeordnet ist.  | [Diskussion und Beispiele.](ddb-en-client-adv-features-empty.md) | 
| DynamoDbSecondaryPartitionKey | Attribut |  Markiert ein Attribut als Partitionsschlüssel für einen globalen sekundären Index.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbSecondarySortKey | Attribut |  Markiert ein Attribut als optionalen Sortierschlüssel für einen globalen oder lokalen Sekundärindex.  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbSortKey | Attribut |  Markiert ein Attribut als optionalen primären Sortierschlüssel (Bereichsschlüssel).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/ddb-en-client-anno-index.html)  | 
| DynamoDbUpdateBehavior | Attribut |  Gibt das Verhalten an, wenn dieses Attribut im Rahmen eines Aktualisierungsvorgangs aktualisiert wird, UpdateItem z.  | [Einführung und Beispiel.](ddb-en-client-adv-features-upd-behavior.md) | 
| DynamoDbVersionAttribute | Attribut | Erhöht die Versionsnummer eines Artikels. | [Einführung und Diskussion.](ddb-en-client-extensions.md#ddb-en-client-extensions-VRE) | 

1 Sie können Anmerkungen auf Attributebene auf Getter oder Setter anwenden, aber nicht auf beide. Diese Anleitung zeigt Anmerkungen zu Getter.

2 Der Begriff `property` wird normalerweise für einen Wert verwendet, der in einer Datenklasse gekapselt ist. JavaBean In diesem Handbuch wird der Begriff jedoch `attribute` stattdessen verwendet, um mit der von DynamoDB verwendeten Terminologie konsistent zu sein.

# Arbeite mit Amazon EC2
<a name="examples-ec2"></a>

Dieser Abschnitt enthält Beispiele für Programmierungen [Amazon EC2](https://docs.aws.amazon.com/ec2/), die AWS SDK für Java 2.x verwenden.

**Topics**
+ [Amazon EC2 Instanzen verwalten](examples-ec2-instances.md)
+ [Nutzungs AWS-Regionen - und Verfügbarkeitszonen](examples-ec2-regions-zones.md)
+ [Arbeiten Sie mit Sicherheitsgruppen in Amazon EC2](examples-ec2-security-groups.md)
+ [Arbeiten Sie mit Amazon EC2 EC2-Instance-Metadaten](examples-ec2-IMDS.md)

# Amazon EC2 Instanzen verwalten
<a name="examples-ec2-instances"></a>

## Erstellen einer -Instance
<a name="create-an-instance"></a>

Erstellen Sie eine neue Amazon EC2 Instance, indem Sie die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#runInstances(software.amazon.awssdk.services.ec2.model.RunInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#runInstances(software.amazon.awssdk.services.ec2.model.RunInstancesRequest))Methode des [Ec2Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html) aufrufen und ihr ein zu [RunInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RunInstancesRequest.html)verwendendes [Amazon Machine Image (AMI)](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/AMIs.html) und einen [Instance-Typ](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/instance-types.html) zur Verfügung stellen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.InstanceType;
import software.amazon.awssdk.services.ec2.model.RunInstancesRequest;
import software.amazon.awssdk.services.ec2.model.RunInstancesResponse;
import software.amazon.awssdk.services.ec2.model.Tag;
import software.amazon.awssdk.services.ec2.model.CreateTagsRequest;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
```

 **Code** 

```
   public static String createEC2Instance(Ec2Client ec2,String name, String amiId ) {

        RunInstancesRequest runRequest = RunInstancesRequest.builder()
                .imageId(amiId)
                .instanceType(InstanceType.T1_MICRO)
                .maxCount(1)
                .minCount(1)
                .build();

        RunInstancesResponse response = ec2.runInstances(runRequest);
        String instanceId = response.instances().get(0).instanceId();

        Tag tag = Tag.builder()
                .key("Name")
                .value(name)
                .build();

        CreateTagsRequest tagRequest = CreateTagsRequest.builder()
                .resources(instanceId)
                .tags(tag)
                .build();

        try {
            ec2.createTags(tagRequest);
            System.out.printf(
                    "Successfully started EC2 Instance %s based on AMI %s",
                    instanceId, amiId);

          return instanceId;

        } catch (Ec2Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }

        return "";
    }
```

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

## Starten einer Instance
<a name="start-an-instance"></a>

Um eine Amazon EC2 Instanz zu starten, rufen Sie die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#startInstances(software.amazon.awssdk.services.ec2.model.StartInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#startInstances(software.amazon.awssdk.services.ec2.model.StartInstancesRequest))Methode des Ec2Client auf und geben ihr eine, die die ID der zu startenden Instanz [StartInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/StartInstancesRequest.html)enthält.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.StartInstancesRequest;
import software.amazon.awssdk.services.ec2.model.StopInstancesRequest;
```

 **Code** 

```
    public static void startInstance(Ec2Client ec2, String instanceId) {

        StartInstancesRequest request = StartInstancesRequest.builder()
                .instanceIds(instanceId)
                .build();

        ec2.startInstances(request);
        System.out.printf("Successfully started instance %s", instanceId);
    }
```

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

## Anhalten einer Instance
<a name="stop-an-instance"></a>

Um eine Amazon EC2 Instanz zu stoppen, rufen Sie die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#stopInstances(software.amazon.awssdk.services.ec2.model.StopInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#stopInstances(software.amazon.awssdk.services.ec2.model.StopInstancesRequest))Methode des Ec2Client auf und geben ihr eine, die die ID der Instanz [StopInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/StopInstancesRequest.html)enthält, die gestoppt werden soll.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.StartInstancesRequest;
import software.amazon.awssdk.services.ec2.model.StopInstancesRequest;
```

 **Code** 

```
    public static void stopInstance(Ec2Client ec2, String instanceId) {

        StopInstancesRequest request = StopInstancesRequest.builder()
                .instanceIds(instanceId)
                .build();

        ec2.stopInstances(request);
        System.out.printf("Successfully stopped instance %s", instanceId);
    }
```

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

## Neustarten einer Instance
<a name="reboot-an-instance"></a>

Um eine Amazon EC2 Instanz neu zu starten, rufen Sie die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#rebootInstances(software.amazon.awssdk.services.ec2.model.RebootInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#rebootInstances(software.amazon.awssdk.services.ec2.model.RebootInstancesRequest))Methode des Ec2Client auf und geben Sie ihr eine, die die ID der Instanz [RebootInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/RebootInstancesRequest.html)enthält, die neu gestartet werden soll.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
import software.amazon.awssdk.services.ec2.model.RebootInstancesRequest;
```

 **Code** 

```
    public static void rebootEC2Instance(Ec2Client ec2, String instanceId) {

      try {
            RebootInstancesRequest request = RebootInstancesRequest.builder()
                .instanceIds(instanceId)
                    .build();

            ec2.rebootInstances(request);
            System.out.printf(
                "Successfully rebooted instance %s", instanceId);
    } catch (Ec2Exception e) {
          System.err.println(e.awsErrorDetails().errorMessage());
          System.exit(1);
     }
  }
```

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

## Beschreiben von Instances
<a name="describe-instances"></a>

Um Ihre Instanzen aufzulisten, erstellen Sie eine Methode des Ec2Client [DescribeInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DescribeInstancesRequest.html)und rufen Sie sie auf. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#describeInstances(software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#describeInstances(software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest)) Es wird ein [DescribeInstancesResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DescribeInstancesResponse.html)Objekt zurückgegeben, mit dem Sie die Amazon EC2 Instanzen für Ihr Konto und Ihre Region auflisten können.

Instances werden nach *Reservierung* gruppiert. Jede Reservierung entspricht dem Aufruf von `startInstances`, durch den die Instance gestartet wurde. Um Ihre Instances aufzulisten, müssen Sie zuerst die Methode `reservations` der Klasse `DescribeInstancesResponse` aufrufen und dann `instances` für jedes zurückgegebene [Reservation](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/Reservation.html)-Objekt aufrufen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
import software.amazon.awssdk.services.ec2.model.Instance;
import software.amazon.awssdk.services.ec2.model.Reservation;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
```

 **Code** 

```
    public static void describeEC2Instances( Ec2Client ec2){

        String nextToken = null;

        try {

            do {
                DescribeInstancesRequest request = DescribeInstancesRequest.builder().maxResults(6).nextToken(nextToken).build();
                DescribeInstancesResponse response = ec2.describeInstances(request);

                for (Reservation reservation : response.reservations()) {
                    for (Instance instance : reservation.instances()) {
                        System.out.println("Instance Id is " + instance.instanceId());
                        System.out.println("Image id is "+  instance.imageId());
                        System.out.println("Instance type is "+  instance.instanceType());
                        System.out.println("Instance state name is "+  instance.state().name());
                        System.out.println("monitoring information is "+  instance.monitoring().state());

                }
            }
                nextToken = response.nextToken();
            } while (nextToken != null);

        } catch (Ec2Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Die Ergebnisse werden seitenweise zurückgegeben. Sie können die weiteren Ergebnisse abrufen, indem Sie den von der `nextToken`-Methode des Rückgabeobjekts zurückgegebenen Wert an die `nextToken`-Methode eines neuen Anforderungsobjekts übergeben. Verwenden Sie dann das neue Anforderungsobjekt für den nächsten Aufruf von `describeInstances`.

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

## Überwachen einer Instance
<a name="monitor-an-instance"></a>

Sie können verschiedene Aspekte Ihrer Amazon EC2 Instances überwachen, z. B. die CPU- und Netzwerkauslastung, den verfügbaren Arbeitsspeicher und den verbleibenden Festplattenspeicher. Weitere Informationen zur Instanzüberwachung finden Sie unter [Überwachung Amazon EC2](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/monitoring_ec2.html) im Amazon EC2 Benutzerhandbuch für Linux-Instances.

Um mit der Überwachung einer Instanz zu beginnen, müssen Sie eine [MonitorInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/MonitorInstancesRequest.html)mit der ID der zu überwachenden Instanz erstellen und sie an die Methode des Ec2Client übergeben. [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#monitorInstances(software.amazon.awssdk.services.ec2.model.MonitorInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#monitorInstances(software.amazon.awssdk.services.ec2.model.MonitorInstancesRequest))

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.MonitorInstancesRequest;
import software.amazon.awssdk.services.ec2.model.UnmonitorInstancesRequest;
```

 **Code** 

```
    public static void monitorInstance( Ec2Client ec2, String instanceId) {

        MonitorInstancesRequest request = MonitorInstancesRequest.builder()
                .instanceIds(instanceId).build();

        ec2.monitorInstances(request);
        System.out.printf(
                "Successfully enabled monitoring for instance %s",
                instanceId);
    }
```

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

## Anhalten der Instance-Überwachung
<a name="stop-instance-monitoring"></a>

Um die Überwachung einer Instanz zu beenden, erstellen Sie eine [UnmonitorInstancesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/UnmonitorInstancesRequest.html)mit der ID der Instanz, deren Überwachung beendet werden soll, und übergeben Sie sie an die Methode des [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#unmonitorInstances(software.amazon.awssdk.services.ec2.model.UnmonitorInstancesRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/Ec2Client.html#unmonitorInstances(software.amazon.awssdk.services.ec2.model.UnmonitorInstancesRequest))Ec2Client.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.MonitorInstancesRequest;
import software.amazon.awssdk.services.ec2.model.UnmonitorInstancesRequest;
```

 **Code** 

```
    public static void unmonitorInstance(Ec2Client ec2, String instanceId) {
        UnmonitorInstancesRequest request = UnmonitorInstancesRequest.builder()
                .instanceIds(instanceId).build();

        ec2.unmonitorInstances(request);

        System.out.printf(
                "Successfully disabled monitoring for instance %s",
                instanceId);
    }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html)in der Amazon EC2 API-Referenz
+  [DescribeInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeInstances.html)in der Amazon EC2 API-Referenz
+  [StartInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StartInstances.html)in der Amazon EC2 API-Referenz
+  [StopInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_StopInstances.html)in der Amazon EC2 API-Referenz
+  [RebootInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RebootInstances.html)in der Amazon EC2 API-Referenz
+  [MonitorInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_MonitorInstances.html)in der Amazon EC2 API-Referenz
+  [UnmonitorInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_UnmonitorInstances.html)in der Amazon EC2 API-Referenz

# Nutzungs AWS-Regionen - und Verfügbarkeitszonen
<a name="examples-ec2-regions-zones"></a>

## Beschreiben von Regionen
<a name="describe-regions"></a>

Rufen Sie die Methode von Ec2Client auf, um die für Ihr Konto verfügbaren Regionen aufzulisten. `describeRegions` Sie gibt [DescribeRegionsResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DescribeRegionsResponse.html) zurück. Rufen Sie die `regions`-Methode des zurückgegebenen Objekts auf und Sie erhalten eine Liste mit [Region](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/Region.html)-Objekten, von denen jedes für eine Region steht.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2AsyncClient;
import software.amazon.awssdk.services.ec2.model.DescribeRegionsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesResponse;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2AsyncClient;
import software.amazon.awssdk.services.ec2.model.DescribeRegionsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesResponse;
import java.util.concurrent.CompletableFuture;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class DescribeRegionsAndZones {
    public static void main(String[] args) {
        Ec2AsyncClient ec2AsyncClient = Ec2AsyncClient.builder()
            .region(Region.US_EAST_1)
            .build();

        try {
            CompletableFuture<Void> future = describeEC2RegionsAndZonesAsync(ec2AsyncClient);
            future.join(); // Wait for both async operations to complete.
        } catch (RuntimeException rte) {
            System.err.println("An exception occurred: " + (rte.getCause() != null ? rte.getCause().getMessage() : rte.getMessage()));
        }
    }

    /**
     * Asynchronously describes the EC2 regions and availability zones.
     *
     * @param ec2AsyncClient the EC2 async client used to make the API calls
     * @return a {@link CompletableFuture} that completes when both the region and availability zone descriptions are complete
     */
    public static CompletableFuture<Void> describeEC2RegionsAndZonesAsync(Ec2AsyncClient ec2AsyncClient) {
        // Initiate the asynchronous request to describe regions
        CompletableFuture<DescribeRegionsResponse> regionsResponse = ec2AsyncClient.describeRegions();

        // Handle the response or exception for regions
        CompletableFuture<DescribeRegionsResponse> regionsFuture = regionsResponse.whenComplete((regionsResp, ex) -> {
            if (ex != null) {
                // Handle the exception by throwing a RuntimeException
                throw new RuntimeException("Failed to describe EC2 regions.", ex);
            } else if (regionsResp == null || regionsResp.regions().isEmpty()) {
                // Throw an exception if the response is null or the result is empty
                throw new RuntimeException("No EC2 regions found.");
            } else {
                // Process the response if no exception occurred and the result is not empty
                regionsResp.regions().forEach(region -> {
                    System.out.printf(
                        "Found Region %s with endpoint %s%n",
                        region.regionName(),
                        region.endpoint());
                });
            }
        });

        CompletableFuture<DescribeAvailabilityZonesResponse> zonesResponse = ec2AsyncClient.describeAvailabilityZones();
        CompletableFuture<DescribeAvailabilityZonesResponse> zonesFuture = zonesResponse.whenComplete((zonesResp, ex) -> {
            if (ex != null) {
                throw new RuntimeException("Failed to describe EC2 availability zones.", ex);
            } else if (zonesResp == null || zonesResp.availabilityZones().isEmpty()) {
                throw new RuntimeException("No EC2 availability zones found.");
            } else {
                zonesResp.availabilityZones().forEach(zone -> {
                    System.out.printf(
                        "Found Availability Zone %s with status %s in region %s%n",
                        zone.zoneName(),
                        zone.state(),
                        zone.regionName()
                    );
                });
            }
        });

        return CompletableFuture.allOf(regionsFuture, zonesFuture);
    }
}
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/7486a1a092aa8e16a21698ef26f9d524fef62e55/javav2/example_code/ec2/src/main/java/com/example/ec2/DescribeRegionsAndZones.java) finden Sie unter. GitHub

## Beschreiben von Availability Zones
<a name="describe-availability-zones"></a>

Rufen Sie die Methode von Ec2Client auf, um jede Availability Zone aufzulisten, die für Ihr Konto verfügbar sind`describeAvailabilityZones`. Sie gibt [DescribeAvailabilityZonesResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DescribeAvailabilityZonesResponse.html) zurück. Rufen Sie die `availabilityZones` Methode auf, um eine Liste von [AvailabilityZone](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/AvailabilityZone.html)Objekten zu erhalten, die jede Availability Zone repräsentieren.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2AsyncClient;
import software.amazon.awssdk.services.ec2.model.DescribeRegionsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesResponse;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

Erstellen Sie den Ec2Client.

```
        Ec2AsyncClient ec2AsyncClient = Ec2AsyncClient.builder()
            .region(Region.US_EAST_1)
            .build();
```

Rufen Sie dann describeAvailabilityZones () auf und rufen Sie die Ergebnisse ab.

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2AsyncClient;
import software.amazon.awssdk.services.ec2.model.DescribeRegionsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeAvailabilityZonesResponse;
import java.util.concurrent.CompletableFuture;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class DescribeRegionsAndZones {
    public static void main(String[] args) {
        Ec2AsyncClient ec2AsyncClient = Ec2AsyncClient.builder()
            .region(Region.US_EAST_1)
            .build();

        try {
            CompletableFuture<Void> future = describeEC2RegionsAndZonesAsync(ec2AsyncClient);
            future.join(); // Wait for both async operations to complete.
        } catch (RuntimeException rte) {
            System.err.println("An exception occurred: " + (rte.getCause() != null ? rte.getCause().getMessage() : rte.getMessage()));
        }
    }

    /**
     * Asynchronously describes the EC2 regions and availability zones.
     *
     * @param ec2AsyncClient the EC2 async client used to make the API calls
     * @return a {@link CompletableFuture} that completes when both the region and availability zone descriptions are complete
     */
    public static CompletableFuture<Void> describeEC2RegionsAndZonesAsync(Ec2AsyncClient ec2AsyncClient) {
        // Initiate the asynchronous request to describe regions
        CompletableFuture<DescribeRegionsResponse> regionsResponse = ec2AsyncClient.describeRegions();

        // Handle the response or exception for regions
        CompletableFuture<DescribeRegionsResponse> regionsFuture = regionsResponse.whenComplete((regionsResp, ex) -> {
            if (ex != null) {
                // Handle the exception by throwing a RuntimeException
                throw new RuntimeException("Failed to describe EC2 regions.", ex);
            } else if (regionsResp == null || regionsResp.regions().isEmpty()) {
                // Throw an exception if the response is null or the result is empty
                throw new RuntimeException("No EC2 regions found.");
            } else {
                // Process the response if no exception occurred and the result is not empty
                regionsResp.regions().forEach(region -> {
                    System.out.printf(
                        "Found Region %s with endpoint %s%n",
                        region.regionName(),
                        region.endpoint());
                });
            }
        });

        CompletableFuture<DescribeAvailabilityZonesResponse> zonesResponse = ec2AsyncClient.describeAvailabilityZones();
        CompletableFuture<DescribeAvailabilityZonesResponse> zonesFuture = zonesResponse.whenComplete((zonesResp, ex) -> {
            if (ex != null) {
                throw new RuntimeException("Failed to describe EC2 availability zones.", ex);
            } else if (zonesResp == null || zonesResp.availabilityZones().isEmpty()) {
                throw new RuntimeException("No EC2 availability zones found.");
            } else {
                zonesResp.availabilityZones().forEach(zone -> {
                    System.out.printf(
                        "Found Availability Zone %s with status %s in region %s%n",
                        zone.zoneName(),
                        zone.state(),
                        zone.regionName()
                    );
                });
            }
        });

        return CompletableFuture.allOf(regionsFuture, zonesFuture);
    }
}
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/7486a1a092aa8e16a21698ef26f9d524fef62e55/javav2/example_code/ec2/src/main/java/com/example/ec2/DescribeRegionsAndZones.java) finden Sie unter GitHub.

## Beschreiben von Konten
<a name="describe-accounts"></a>

Rufen Sie die EC2 Methode von Ec2Client auf, um verwandte Informationen zu Ihrem Konto aufzulisten. `describeAccountAttributes` Diese Methode gibt ein [DescribeAccountAttributesResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DescribeAccountAttributesResponse.html)Objekt zurück. Rufen Sie die `accountAttributes` Methode dieses Objekts auf, um eine Liste von [AccountAttribute](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/AccountAttribute.html)Objekten zu erhalten. Sie können die Liste durchgehen, um ein `AccountAttribute` Objekt abzurufen.

Sie können die Attributwerte Ihres Kontos abrufen, indem Sie die Methode des `AccountAttribute` `attributeValues` Objekts aufrufen. Diese Methode gibt eine Liste von [AccountAttributeValue](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/AccountAttributeValue.html)Objekten zurück. Sie können diese zweite Liste durchlaufen, um den Wert von Attributen anzuzeigen (siehe das folgende Codebeispiel).

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2AsyncClient;
import software.amazon.awssdk.services.ec2.model.DescribeAccountAttributesResponse;
import java.util.concurrent.CompletableFuture;
```

 **Code** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2AsyncClient;
import software.amazon.awssdk.services.ec2.model.DescribeAccountAttributesResponse;
import java.util.concurrent.CompletableFuture;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class DescribeAccount {
    public static void main(String[] args) {
        Ec2AsyncClient ec2AsyncClient = Ec2AsyncClient.builder()
            .region(Region.US_EAST_1)
            .build();

        try {
            CompletableFuture<DescribeAccountAttributesResponse> future = describeEC2AccountAsync(ec2AsyncClient);
            future.join();
            System.out.println("EC2 Account attributes described successfully.");
        } catch (RuntimeException rte) {
            System.err.println("An exception occurred: " + (rte.getCause() != null ? rte.getCause().getMessage() : rte.getMessage()));
        }
    }

    /**
     * Describes the EC2 account attributes asynchronously.
     *
     * @param ec2AsyncClient the EC2 asynchronous client to use for the operation
     * @return a {@link CompletableFuture} containing the {@link DescribeAccountAttributesResponse} with the account attributes
     */
    public static CompletableFuture<DescribeAccountAttributesResponse> describeEC2AccountAsync(Ec2AsyncClient ec2AsyncClient) {
        CompletableFuture<DescribeAccountAttributesResponse> response = ec2AsyncClient.describeAccountAttributes();
        return response.whenComplete((accountResults, ex) -> {
            if (ex != null) {
                // Handle the exception by throwing a RuntimeException.
                throw new RuntimeException("Failed to describe EC2 account attributes.", ex);
            } else if (accountResults == null || accountResults.accountAttributes().isEmpty()) {
                // Throw an exception if the response is null or no account attributes are found.
                throw new RuntimeException("No account attributes found.");
            } else {
                // Process the response if no exception occurred.
                accountResults.accountAttributes().forEach(attribute -> {
                    System.out.println("\nThe name of the attribute is " + attribute.attributeName());
                    attribute.attributeValues().forEach(
                        myValue -> System.out.println("The value of the attribute is " + myValue.attributeValue()));
                });
            }
        });
    }
}
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/7486a1a092aa8e16a21698ef26f9d524fef62e55/javav2/example_code/ec2/src/main/java/com/example/ec2/DescribeAccount.java) finden Sie unter GitHub.

## Weitere Informationen
<a name="more-information"></a>
+  [Regionen und Availability Zones](https://docs.aws.amazon.com//AWSEC2/latest/UserGuide/using-regions-availability-zones.html) im Amazon EC2 Benutzerhandbuch für Linux-Instances
+  [DescribeRegions](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeRegions.html)in der Amazon EC2 API-Referenz
+  [DescribeAvailabilityZones](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeAvailabilityZones.html)in der Amazon EC2 API-Referenz

# Arbeiten Sie mit Sicherheitsgruppen in Amazon EC2
<a name="examples-ec2-security-groups"></a>

## Eine Sicherheitsgruppe erstellen
<a name="create-a-security-group"></a>

Um eine Sicherheitsgruppe zu erstellen, rufen Sie die `createSecurityGroup` Methode des Ec2Client mit einer auf [CreateSecurityGroupRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/CreateSecurityGroupRequest.html), die den Namen des Schlüssels enthält.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.CreateSecurityGroupRequest;
import software.amazon.awssdk.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
import software.amazon.awssdk.services.ec2.model.AuthorizeSecurityGroupIngressResponse;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
import software.amazon.awssdk.services.ec2.model.IpPermission;
import software.amazon.awssdk.services.ec2.model.CreateSecurityGroupResponse;
import software.amazon.awssdk.services.ec2.model.IpRange;
```

 **Code** 

```
            CreateSecurityGroupRequest createRequest = CreateSecurityGroupRequest.builder()
                .groupName(groupName)
                .description(groupDesc)
                .vpcId(vpcId)
                .build();

            CreateSecurityGroupResponse resp= ec2.createSecurityGroup(createRequest);
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/ec2/src/main/java/com/example/ec2/CreateSecurityGroup.java) finden Sie unter. GitHub

## Konfigurieren einer Sicherheitsgruppe
<a name="configure-a-security-group"></a>

Eine Sicherheitsgruppe kann sowohl den eingehenden (eingehenden) als auch den ausgehenden (ausgehenden) Datenverkehr zu Ihren Instances kontrollieren. Amazon EC2 

Um Ihrer Sicherheitsgruppe Eingangsregeln hinzuzufügen, verwenden Sie die `authorizeSecurityGroupIngress` Methode des Ec2Client und geben Sie den Namen der Sicherheitsgruppe und die Zugriffsregeln ([IpPermission](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/IpPermission.html)) an, die Sie ihr innerhalb eines Objekts zuweisen möchten. [AuthorizeSecurityGroupIngressRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/AuthorizeSecurityGroupIngressRequest.html) Im folgenden Beispiel wird gezeigt, wie Sie einer Sicherheitsgruppe IP-Berechtigungen hinzufügen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.CreateSecurityGroupRequest;
import software.amazon.awssdk.services.ec2.model.AuthorizeSecurityGroupIngressRequest;
import software.amazon.awssdk.services.ec2.model.AuthorizeSecurityGroupIngressResponse;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
import software.amazon.awssdk.services.ec2.model.IpPermission;
import software.amazon.awssdk.services.ec2.model.CreateSecurityGroupResponse;
import software.amazon.awssdk.services.ec2.model.IpRange;
```

 **Code** 

Erstellen Sie zunächst einen Ec2Client

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

Verwenden Sie dann die Methode des Ec2Client `authorizeSecurityGroupIngress`

```
            IpRange ipRange = IpRange.builder()
                .cidrIp("0.0.0.0/0").build();

            IpPermission ipPerm = IpPermission.builder()
                .ipProtocol("tcp")
                .toPort(80)
                .fromPort(80)
                .ipRanges(ipRange)
                .build();

            IpPermission ipPerm2 = IpPermission.builder()
                .ipProtocol("tcp")
                .toPort(22)
                .fromPort(22)
                .ipRanges(ipRange)
                .build();

            AuthorizeSecurityGroupIngressRequest authRequest =
                AuthorizeSecurityGroupIngressRequest.builder()
                        .groupName(groupName)
                        .ipPermissions(ipPerm, ipPerm2)
                        .build();

            AuthorizeSecurityGroupIngressResponse authResponse =
            ec2.authorizeSecurityGroupIngress(authRequest);

            System.out.printf(
                "Successfully added ingress policy to Security Group %s",
                groupName);

            return resp.groupId();

        } catch (Ec2Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return "";
    }
```

Um der Sicherheitsgruppe eine Ausgangsregel hinzuzufügen, geben Sie ähnliche Daten in einer der [AuthorizeSecurityGroupEgressRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/AuthorizeSecurityGroupEgressRequest.html)Ec2Client-Methode an. `authorizeSecurityGroupEgress`

Das [vollständige](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/ec2/src/main/java/com/example/ec2/CreateSecurityGroup.java) Beispiel finden Sie unter. GitHub

## Beschreiben von Sicherheitsgruppen
<a name="describe-security-groups"></a>

Rufen Sie die Methode des Ec2Client auf, um Ihre Sicherheitsgruppen zu beschreiben oder Informationen über sie zu erhalten. `describeSecurityGroups` Sie gibt eine zurück [DescribeSecurityGroupsResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DescribeSecurityGroupsResponse.html), mit der Sie auf die Liste der Sicherheitsgruppen zugreifen können, indem Sie ihre `securityGroups` Methode aufrufen, die eine Liste von [SecurityGroup](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/SecurityGroup.html)Objekten zurückgibt.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsResponse;
import software.amazon.awssdk.services.ec2.model.SecurityGroup;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
```

 **Code** 

```
     public static void describeEC2SecurityGroups(Ec2Client ec2, String groupId) {

        try {
            DescribeSecurityGroupsRequest request =
                DescribeSecurityGroupsRequest.builder()
                        .groupIds(groupId).build();

            DescribeSecurityGroupsResponse response =
                ec2.describeSecurityGroups(request);

             for(SecurityGroup group : response.securityGroups()) {
                System.out.printf(
                    "Found Security Group with id %s, " +
                            "vpc id %s " +
                            "and description %s",
                    group.groupId(),
                    group.vpcId(),
                    group.description());
            }
        } catch (Ec2Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/ec2/src/main/java/com/example/ec2/DescribeSecurityGroups.java) finden Sie unter GitHub.

## Löschen einer Sicherheitsgruppe
<a name="delete-a-security-group"></a>

Um eine Sicherheitsgruppe zu löschen, rufen Sie die `deleteSecurityGroup` Methode des Ec2Client auf und übergeben ihr eine, [DeleteSecurityGroupRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/ec2/model/DeleteSecurityGroupRequest.html)die die ID der zu löschenden Sicherheitsgruppe enthält.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DeleteSecurityGroupRequest;
import software.amazon.awssdk.services.ec2.model.Ec2Exception;
```

 **Code** 

```
    public static void deleteEC2SecGroup(Ec2Client ec2,String groupId) {

        try {
            DeleteSecurityGroupRequest request = DeleteSecurityGroupRequest.builder()
                .groupId(groupId)
                .build();

            ec2.deleteSecurityGroup(request);
            System.out.printf(
                "Successfully deleted Security Group with id %s", groupId);

        } catch (Ec2Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
     }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/ec2/src/main/java/com/example/ec2/DeleteSecurityGroup.java) finden Sie unter. GitHub

## Weitere Informationen
<a name="more-information"></a>
+  [Amazon EC2 Sicherheitsgruppen](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html) im Amazon EC2 Benutzerhandbuch für Linux-Instances
+  [Autorisieren Sie eingehenden Datenverkehr für Ihre Linux-Instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/authorizing-access-to-an-instance.html) im Amazon EC2 Benutzerhandbuch für Linux-Instances
+  [CreateSecurityGroup](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateSecurityGroup.html)in der API-Referenz Amazon EC2 
+  [DescribeSecurityGroups](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DescribeSecurityGroups.html)in der Amazon EC2 API-Referenz
+  [DeleteSecurityGroup](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteSecurityGroup.html)in der Amazon EC2 API-Referenz
+  [AuthorizeSecurityGroupIngress](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_AuthorizeSecurityGroupIngress.html)in der Amazon EC2 API-Referenz

# Arbeiten Sie mit Amazon EC2 EC2-Instance-Metadaten
<a name="examples-ec2-IMDS"></a>

Ein Java-SDK-Client für den Amazon EC2 Instance Metadata Service (Metadaten-Client) ermöglicht Ihren Anwendungen den Zugriff auf Metadaten auf ihrer lokalen EC2-Instance. Der Metadaten-Client arbeitet mit der lokalen Instanz von [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html)(Instance Metadata Service v2) und verwendet sitzungsorientierte Anfragen. 

Zwei Clientklassen sind im SDK verfügbar. Die synchrone Variante `[Ec2MetadataClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/imds/Ec2MetadataClient.html)` dient zum Blockieren von Vorgängen und die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/imds/Ec2MetadataAsyncClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/imds/Ec2MetadataAsyncClient.html)für asynchrone, nicht blockierende Anwendungsfälle. 

## Erste Schritte
<a name="examples-ec2-IMDS-getstarted"></a>

Um den Metadaten-Client zu verwenden, fügen Sie das `imds` Maven-Artefakt zu Ihrem Projekt hinzu. Sie benötigen auch Klassen für eine `[SdkHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/SdkHttpClient.html)` (oder eine `[SdkAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/async/SdkAsyncHttpClient.html)` für die asynchrone Variante) im Klassenpfad. 

Das folgende Maven-XML zeigt Abhängigkeits-Snippets für die Verwendung der synchronen [UrlConnectionHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/urlconnection/UrlConnectionHttpClient.html)Version zusammen mit der Abhängigkeit für Metadaten-Clients.

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

<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>imds</artifactId>
    </dependency>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>url-connection-client</artifactId>
    </dependency>
    <!-- other dependencies --> 
</dependencies>
```

Suchen Sie im [zentralen Maven-Repository](https://central.sonatype.com/artifact/software.amazon.awssdk/bom) nach der neuesten Version des Artefakts. `bom`

Um einen asynchronen HTTP-Client zu verwenden, ersetzen Sie das Abhängigkeits-Snippet für das Artefakt. `url-connection-client` Das folgende Snippet bringt beispielsweise die Implementierung mit ein. [NettyNioAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/nio/netty/NettyNioAsyncHttpClient.html)

```
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>netty-nio-client</artifactId>
    </dependency>
```

## Verwenden Sie den Metadaten-Client
<a name="examples-ec2-IMDS-use"></a>

### Instanziieren Sie einen Metadaten-Client
<a name="examples-ec2-IMDS-use-create"></a>

Sie können eine Instanz eines synchronen Systems instanziieren, `Ec2MetadataClient` wenn nur eine Implementierung der `SdkHttpClient` Schnittstelle im Klassenpfad vorhanden ist. Rufen Sie dazu die statische `Ec2MetadataClient#create()` Methode auf, wie im folgenden Codeausschnitt gezeigt. 

```
Ec2MetadataClient client = Ec2MetadataClient.create(); // 'Ec2MetadataAsyncClient#create' is the asynchronous version.
```

Wenn Ihre Anwendung über mehrere Implementierungen der `SdkHttpClient` `SdkHttpAsyncClient` OR-Schnittstelle verfügt, müssen Sie eine Implementierung angeben, die der Metadaten-Client verwenden soll, wie im Abschnitt gezeigt. [Konfigurierbarer HTTP-Client](#examples-ec2-IMDS-features-http) 

**Anmerkung**  
Für die meisten Service-Clients, wie Amazon S3, fügt das SDK for Java automatisch Implementierungen der `SdkHttpClient` `SdkHttpAsyncClient` OR-Schnittstelle hinzu. Wenn Ihr Metadaten-Client dieselbe Implementierung verwendet, `Ec2MetadataClient#create()` funktioniert das. Wenn Sie eine andere Implementierung benötigen, müssen Sie diese angeben, wenn Sie den Metadaten-Client erstellen.

### Anfragen senden
<a name="examples-ec2-IMDS-use-req"></a>

Um Instanzmetadaten abzurufen, instanziieren Sie die `EC2MetadataClient` Klasse und rufen Sie die `get` Methode mit einem Pfadparameter auf, der die [Metadatenkategorie der Instanz](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html) angibt.

Im folgenden Beispiel wird der mit dem `ami-id` Schlüssel verknüpfte Wert in die Konsole gedruckt.

```
Ec2MetadataClient client = Ec2MetadataClient.create();
Ec2MetadataResponse response = client.get("/latest/meta-data/ami-id");
System.out.println(response.asString());
client.close(); // Closes the internal resources used by the Ec2MetadataClient class.
```

Wenn der Pfad nicht gültig ist, löst die `get` Methode eine Ausnahme aus. 

Verwenden Sie dieselbe Client-Instanz für mehrere Anfragen, rufen Sie jedoch den Client `close` auf, wenn er nicht mehr benötigt wird, um Ressourcen freizugeben. Nach dem Aufruf der Methode close kann die Client-Instanz nicht mehr verwendet werden.

### Antworten analysieren
<a name="examples-ec2-IMDS-use-pares"></a>

EC2-Instanz-Metadaten können in verschiedenen Formaten ausgegeben werden. Klartext und JSON sind die am häufigsten verwendeten Formate. Die Metadaten-Clients bieten Möglichkeiten, mit diesen Formaten zu arbeiten. 

Wie das folgende Beispiel zeigt, verwenden Sie die `asString` Methode, um die Daten als Java-String abzurufen. Sie können die `asList` Methode auch verwenden, um eine Klartext-Antwort zu trennen, die mehrere Zeilen zurückgibt. 

```
Ec2MetadataClient client = Ec2MetadataClient.create();
Ec2MetadataResponse response = client.get("/latest/meta-data/");
String fullResponse = response.asString();
List<String> splits = response.asList();
```

Wenn die Antwort in JSON ist, verwenden Sie die `Ec2MetadataResponse#asDocument` Methode, um die JSON-Antwort in eine [Dokumentinstanz](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/document/Document.html) zu parsen, wie im folgenden Codeausschnitt gezeigt.

```
Document fullResponse = response.asDocument();
```

Eine Ausnahme wird ausgelöst, wenn das Format der Metadaten nicht in JSON ist. Wenn die Antwort erfolgreich analysiert wurde, können Sie die [Dokument-API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/document/package-summary.html) verwenden, um die Antwort genauer zu untersuchen. In der [Tabelle mit den Kategorien der Instanz-Metadaten](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-categories.html) erfahren Sie, welche Metadatenkategorien Antworten im JSON-Format liefern.

## Konfigurieren Sie einen Metadaten-Client
<a name="examples-ec2-IMDS-config"></a>

### Erneute Versuche
<a name="examples-ec2-IMDS-config-retries"></a>

Sie können einen Metadaten-Client mit einem Wiederholungsmechanismus konfigurieren. Wenn Sie dies tun, kann der Client Anfragen, die aus unerwarteten Gründen fehlschlagen, automatisch wiederholen. Standardmäßig versucht der Client bei einer fehlgeschlagenen Anfrage dreimal, wobei zwischen den Versuchen eine exponentielle Backoff-Zeit liegt.

Wenn Ihr Anwendungsfall einen anderen Wiederholungsmechanismus erfordert, können Sie den Client mithilfe der `retryPolicy` Methode in seinem Builder anpassen. Das folgende Beispiel zeigt beispielsweise einen synchronen Client, der mit einer festen Verzögerung von zwei Sekunden zwischen Versuchen und fünf Wiederholungsversuchen konfiguriert ist.

```
BackoffStrategy fixedBackoffStrategy = FixedDelayBackoffStrategy.create(Duration.ofSeconds(2));
Ec2MetadataClient client =
    Ec2MetadataClient.builder()
                     .retryPolicy(retryPolicyBuilder -> retryPolicyBuilder.numRetries(5)
                                                                           .backoffStrategy(fixedBackoffStrategy))
                     .build();
```

Es gibt mehrere [BackoffStrategies](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/retry/backoff/package-summary.html), die Sie mit einem Metadaten-Client verwenden können.

Sie können den Wiederholungsmechanismus auch vollständig deaktivieren, wie der folgende Ausschnitt zeigt.

```
Ec2MetadataClient client =
    Ec2MetadataClient.builder()
                    .retryPolicy(Ec2MetadataRetryPolicy.none())
                    .build();
```

Durch die Verwendung `Ec2MetadataRetryPolicy#none()` wird die standardmäßige Wiederholungsrichtlinie deaktiviert, sodass der Metadaten-Client keine Wiederholungen versucht.

### IP-Version
<a name="examples-ec2-IMDS-config-ipversion"></a>

Standardmäßig verwendet ein Metadaten-Client den IPV4 Endpunkt unter. `http://169.254.169.254` Um den Client so zu ändern, dass er die IPV6 Version verwendet, verwenden Sie entweder die `endpointMode` oder die `endpoint` Methode des Builders. Eine Ausnahme ergibt sich, wenn beide Methoden im Builder aufgerufen werden.

Die folgenden Beispiele zeigen beide IPV6 Optionen.

```
Ec2MetadataClient client =
    Ec2MetadataClient.builder()
                     .endpointMode(EndpointMode.IPV6)
                     .build();
```

```
Ec2MetadataClient client =
    Ec2MetadataClient.builder()
                     .endpoint(URI.create("http://[fd00:ec2::254]"))
                     .build();
```

## Schlüssel-Features
<a name="examples-ec2-IMDS-features"></a>

### Asynchroner Client
<a name="examples-ec2-IMDS-features-async"></a>

Um die nicht blockierende Version des Clients zu verwenden, instanziieren Sie eine Instanz der Klasse. `Ec2MetadataAsyncClient` Der Code im folgenden Beispiel erstellt einen asynchronen Client mit Standardeinstellungen und verwendet die `get` Methode, um den Wert für den Schlüssel abzurufen. `ami-id`

```
Ec2MetadataAsyncClient asyncClient = Ec2MetadataAsyncClient.create();
CompletableFuture<Ec2MetadataResponse> response = asyncClient.get("/latest/meta-data/ami-id");
```

Der von der `get` Methode `java.util.concurrent.CompletableFuture` zurückgegebene Vorgang wird abgeschlossen, wenn die Antwort zurückgegeben wird. Im folgenden Beispiel werden die `ami-id` Metadaten auf die Konsole gedruckt.

```
response.thenAccept(metadata -> System.out.println(metadata.asString()));
```

### Konfigurierbarer HTTP-Client
<a name="examples-ec2-IMDS-features-http"></a>

Der Builder für jeden Metadaten-Client verfügt über eine `httpClient` Methode, mit der Sie einen benutzerdefinierten HTTP-Client bereitstellen können. 

Das folgende Beispiel zeigt Code für eine benutzerdefinierte `UrlConnectionHttpClient` Instanz.

```
SdkHttpClient httpClient =
    UrlConnectionHttpClient.builder()
                           .socketTimeout(Duration.ofMinutes(5))
                           .proxyConfiguration(proxy -> proxy.endpoint(URI.create("http://proxy.example.net:8888"))))
                           .build();
Ec2MetadataClient metaDataClient =
    Ec2MetadataClient.builder()
                     .httpClient(httpClient)
                     .build();
// Use the metaDataClient instance.
metaDataClient.close();   // Close the instance when no longer needed.
```

Das folgende Beispiel zeigt Code für eine benutzerdefinierte `NettyNioAsyncHttpClient` Instanz mit einem asynchronen Metadaten-Client.

```
SdkAsyncHttpClient httpAsyncClient = 
    NettyNioAsyncHttpClient.builder()
                           .connectionTimeout(Duration.ofMinutes(5))
                           .maxConcurrency(100)
                           .build();
Ec2MetadataAsyncClient asyncMetaDataClient =
    Ec2MetadataAsyncClient.builder()
                          .httpClient(httpAsyncClient)
                          .build();
// Use the asyncMetaDataClient instance.
asyncMetaDataClient.close();   // Close the instance when no longer needed.
```

Das [Konfigurieren Sie HTTP-Clients in der AWS SDK for Java 2.x](http-configuration.md) Thema in diesem Handbuch enthält Einzelheiten zur Konfiguration der HTTP-Clients, die im SDK for Java verfügbar sind.

### Zwischenspeichern von Token
<a name="examples-ec2-IMDS-features-token"></a>

Da die Clients die Metadaten verwenden IMDSv2, sind alle Anfragen mit einer Sitzung verknüpft. Eine Sitzung wird durch ein Token mit Ablauf definiert, das der Metadaten-Client für Sie verwaltet. Bei jeder Metadatenanforderung wird das Token automatisch wiederverwendet, bis es abläuft. 

Standardmäßig ist ein Token sechs Stunden (21.600 Sekunden) gültig. Wir empfehlen, den time-to-live Standardwert beizubehalten, es sei denn, Ihr spezieller Anwendungsfall erfordert eine erweiterte Konfiguration. 

Falls erforderlich, konfigurieren Sie die Dauer mithilfe der `tokenTtl` Builder-Methode. Mit dem Code im folgenden Codeausschnitt wird beispielsweise ein Client mit einer Sitzungsdauer von fünf Minuten erstellt. 

```
Ec2MetadataClient client =
    Ec2MetadataClient.builder()
                     .tokenTtl(Duration.ofMinutes(5))
                     .build();
```

Wenn Sie den Aufruf der `tokenTtl` Methode im Builder weglassen, wird stattdessen die Standarddauer von 21.600 verwendet. 

# Arbeite mit IAM
<a name="examples-iam"></a>

Dieser Abschnitt enthält Beispiele für die Programmierung AWS Identity and Access Management (IAM) mit AWS SDK für Java 2.x.

 AWS Identity and Access Management (IAM) ermöglicht es Ihnen, den Zugriff Ihrer Benutzer auf AWS Dienste und Ressourcen sicher zu kontrollieren. Mithilfe von IAM Cookies können Sie AWS Benutzer und Gruppen erstellen und verwalten und ihnen mithilfe von Berechtigungen den Zugriff auf AWS Ressourcen gewähren oder verweigern. Eine vollständige Anleitung dazu IAM finden Sie im [IAM Benutzerhandbuch](https://docs.aws.amazon.com//IAM/latest/UserGuide/introduction.html).

Die folgenden Beispiele enthalten nur den Code, der zur Demonstration jeder Technik nötig ist. Der [vollständige Beispielcode ist verfügbar unter GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2). Von dort aus können Sie eine einzelne Quelldatei herunterladen oder das Repository klonen, um alle Beispiele lokal zu erstellen und auszuführen.

**Topics**
+ [IAM Zugangsschlüssel verwalten](examples-iam-access-keys.md)
+ [IAM Nutzer verwalten](examples-iam-users.md)
+ [IAM-Richtlinien erstellen](feature-iam-policy-builder.md)
+ [Mit IAM Richtlinien arbeiten](examples-iam-policies.md)
+ [Arbeiten Sie mit IAM Serverzertifikaten](examples-iam-server-certificates.md)

# IAM Zugangsschlüssel verwalten
<a name="examples-iam-access-keys"></a>

## Erstellen eines Zugriffsschlüssels
<a name="create-an-access-key"></a>

Um einen IAM Zugriffsschlüssel zu erstellen, rufen Sie die `IamClient’s` `createAccessKey` Methode mit einem [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/CreateAccessKeyRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/CreateAccessKeyRequest.html)Objekt auf.

**Anmerkung**  
Sie müssen die Region auf einstellen, **AWS\$1GLOBAL**damit `IamClient` Anrufe funktionieren, da IAM es sich um einen globalen Dienst handelt.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.CreateAccessKeyRequest;
import software.amazon.awssdk.services.iam.model.CreateAccessKeyResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static String createIAMAccessKey(IamClient iam,String user) {

        try {
            CreateAccessKeyRequest request = CreateAccessKeyRequest.builder()
                .userName(user).build();

            CreateAccessKeyResponse response = iam.createAccessKey(request);
           String keyId = response.accessKey().accessKeyId();
           return keyId;

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return "";
    }
```

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

## Auflisten von Zugriffsschlüsseln
<a name="list-access-keys"></a>

Um die Zugriffsschlüssel für einen bestimmten Benutzer aufzulisten, erstellen Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListAccessKeysRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListAccessKeysRequest.html)Objekt, das den Benutzernamen enthält, für den die Schlüssel aufgelistet werden sollen, und übergeben Sie ihn an die `IamClient’s` `listAccessKeys` Methode.

**Anmerkung**  
Wenn Sie keinen Benutzernamen angeben, wird versucht`listAccessKeys`, die Zugriffsschlüssel aufzulisten, die dem Benutzer zugeordnet sind AWS-Konto , der die Anfrage signiert hat.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.AccessKeyMetadata;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.ListAccessKeysRequest;
import software.amazon.awssdk.services.iam.model.ListAccessKeysResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
```

 **Code** 

```
    public static void listKeys( IamClient iam,String userName ){

        try {
            boolean done = false;
            String newMarker = null;

            while (!done) {
                ListAccessKeysResponse response;

            if(newMarker == null) {
                ListAccessKeysRequest request = ListAccessKeysRequest.builder()
                        .userName(userName).build();
                response = iam.listAccessKeys(request);
            } else {
                ListAccessKeysRequest request = ListAccessKeysRequest.builder()
                        .userName(userName)
                        .marker(newMarker).build();
                response = iam.listAccessKeys(request);
            }

            for (AccessKeyMetadata metadata :
                    response.accessKeyMetadata()) {
                System.out.format("Retrieved access key %s",
                        metadata.accessKeyId());
            }

            if (!response.isTruncated()) {
                done = true;
            } else {
                newMarker = response.marker();
            }
        }

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Die Ergebnisse von `listAccessKeys` sind seitenweise angeordnet (mit einem Standardhöchstwert von 100 Datensätzen pro Aufruf). Sie können das zurückgegebene [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListAccessKeysResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListAccessKeysResponse.html)Objekt aufrufen`isTruncated`, um zu überprüfen, ob die Abfrage weniger Ergebnisse geliefert hat, als verfügbar sind. Falls ja, rufen Sie `marker` für `ListAccessKeysResponse` auf und verwenden es beim Erstellen einer neuen Anforderung. Verwenden Sie diese neue Anforderung im nächsten Aufruf von `listAccessKeys`.

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

## Abrufen der letzten Nutzungszeit eines Zugriffsschlüssels
<a name="retrieve-an-access-key-s-last-used-time"></a>

Um die Uhrzeit zu ermitteln, zu der ein Zugriffsschlüssel zuletzt verwendet wurde, rufen Sie die `IamClient’s` `getAccessKeyLastUsed` Methode mit der ID des Zugriffsschlüssels auf (die mithilfe eines [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/GetAccessKeyLastUsedRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/GetAccessKeyLastUsedRequest.html)Objekts übergeben werden kann).

Sie können dann das zurückgegebene [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/GetAccessKeyLastUsedResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/GetAccessKeyLastUsedResponse.html)Objekt verwenden, um die Uhrzeit der letzten Verwendung des Schlüssels abzurufen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.GetAccessKeyLastUsedRequest;
import software.amazon.awssdk.services.iam.model.GetAccessKeyLastUsedResponse;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void getAccessKeyLastUsed(IamClient iam, String accessId ){

        try {
            GetAccessKeyLastUsedRequest request = GetAccessKeyLastUsedRequest.builder()
                    .accessKeyId(accessId).build();

            GetAccessKeyLastUsedResponse response = iam.getAccessKeyLastUsed(request);

            System.out.println("Access key was last used at: " +
                    response.accessKeyLastUsed().lastUsedDate());

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        System.out.println("Done");
    }
```

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

## Aktivieren oder Deaktivieren von Zugriffsschlüsseln
<a name="iam-access-keys-update"></a>

Sie können einen Zugriffsschlüssel aktivieren oder deaktivieren, indem Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/UpdateAccessKeyRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/UpdateAccessKeyRequest.html)Objekt erstellen, die Zugriffsschlüssel-ID, optional den Benutzernamen und das gewünschte [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/StatusType.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/StatusType.html)Objekt angeben und dann das Anforderungsobjekt an die `IamClient’s` `updateAccessKey` Methode übergeben.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.StatusType;
import software.amazon.awssdk.services.iam.model.UpdateAccessKeyRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
```

 **Code** 

```
       public static void updateKey(IamClient iam, String username, String accessId, String status ) {

          try {
              if (status.toLowerCase().equalsIgnoreCase("active")) {
                  statusType = StatusType.ACTIVE;
              } else if (status.toLowerCase().equalsIgnoreCase("inactive")) {
                  statusType = StatusType.INACTIVE;
              } else {
                  statusType = StatusType.UNKNOWN_TO_SDK_VERSION;
              }
              UpdateAccessKeyRequest request = UpdateAccessKeyRequest.builder()
                .accessKeyId(accessId)
                .userName(username)
                .status(statusType)
                .build();

              iam.updateAccessKey(request);

              System.out.printf(
                "Successfully updated the status of access key %s to" +
                        "status %s for user %s", accessId, status, username);

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Löschen eines Zugriffsschlüssels
<a name="delete-an-access-key"></a>

Um einen Zugriffsschlüssel dauerhaft zu löschen, rufen Sie die `IamClient’s` `deleteKey` Methode auf und geben Sie ihr eine, die die ID und den Benutzernamen des Zugriffsschlüssels [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/DeleteAccessKeyRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/DeleteAccessKeyRequest.html)enthält.

**Anmerkung**  
Nach dem Löschen können Schlüssel nicht mehr abgerufen oder verwendet werden. Um einen Schlüssel vorübergehend zu deaktivieren, sodass er später wieder aktiviert werden kann, verwenden Sie stattdessen [`updateAccessKey`](#iam-access-keys-update)Methode.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.DeleteAccessKeyRequest;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void deleteKey(IamClient iam ,String username, String accessKey ) {

        try {
            DeleteAccessKeyRequest request = DeleteAccessKeyRequest.builder()
                    .accessKeyId(accessKey)
                    .userName(username)
                    .build();

            iam.deleteAccessKey(request);
            System.out.println("Successfully deleted access key " + accessKey +
                " from user " + username);

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [CreateAccessKey](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateAccessKey.html)in der IAM API-Referenz
+  [ListAccessKeys](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAccessKeys.html)in der IAM API-Referenz
+  [GetAccessKeyLastUsed](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetAccessKeyLastUsed.html)in der IAM API-Referenz
+  [UpdateAccessKey](https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateAccessKey.html)in der IAM API-Referenz
+  [DeleteAccessKey](https://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteAccessKey.html)in der IAM API-Referenz

# IAM Nutzer verwalten
<a name="examples-iam-users"></a>

## Erstellen eines Benutzers
<a name="creating-a-user"></a>

Erstellen Sie einen neuen IAM Benutzer, indem Sie mithilfe eines [CreateUserRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/CreateUserRequest.html)Objekts, IamClient das den Benutzernamen enthält, den Benutzernamen für die `createUser` Methode angeben.

 **Importe** 

```
import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.services.iam.model.CreateUserRequest;
import software.amazon.awssdk.services.iam.model.CreateUserResponse;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.waiters.IamWaiter;
import software.amazon.awssdk.services.iam.model.GetUserRequest;
import software.amazon.awssdk.services.iam.model.GetUserResponse;
```

 **Code** 

```
    public static String createIAMUser(IamClient iam, String username ) {

        try {
            // Create an IamWaiter object
            IamWaiter iamWaiter = iam.waiter();

            CreateUserRequest request = CreateUserRequest.builder()
                    .userName(username)
                    .build();

            CreateUserResponse response = iam.createUser(request);

            // Wait until the user is created
            GetUserRequest userRequest = GetUserRequest.builder()
                    .userName(response.user().userName())
                    .build();

            WaiterResponse<GetUserResponse> waitUntilUserExists = iamWaiter.waitUntilUserExists(userRequest);
            waitUntilUserExists.matched().response().ifPresent(System.out::println);
            return response.user().userName();

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
       return "";
    }
```

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

## -Benutzer auflisten
<a name="listing-users"></a>

Um die IAM Benutzer für Ihr Konto aufzulisten, erstellen Sie ein neues [ListUsersRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListUsersRequest.html)und übergeben Sie es an die IamClient `listUsers` Methode. Sie können die Benutzerliste abrufen, indem Sie das zurückgegebene [ListUsersResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListUsersResponse.html)Objekt aufrufen`users`.

Die von `listUsers` zurückgegebene Benutzerliste ist segmentiert. Sie können prüfen, ob weitere Ergebnisse bereitliegen, indem Sie die `isTruncated`-Methode des Antwortobjekts aufrufen. Wenn sie `true` zurückgibt, rufen Sie die `marker()`-Methode des Antwortobjekts auf. Verwenden Sie den Marker-Wert, um ein neues Objekt zu erstellen. Anschließend rufen Sie die `listUsers`-Methode erneut für die neue Anforderung auf.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.ListUsersRequest;
import software.amazon.awssdk.services.iam.model.ListUsersResponse;
import software.amazon.awssdk.services.iam.model.User;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
```

 **Code** 

```
    public static void listAllUsers(IamClient iam ) {

        try {

             boolean done = false;
             String newMarker = null;

             while(!done) {
                ListUsersResponse response;

                if (newMarker == null) {
                    ListUsersRequest request = ListUsersRequest.builder().build();
                    response = iam.listUsers(request);
                } else {
                    ListUsersRequest request = ListUsersRequest.builder()
                        .marker(newMarker).build();
                    response = iam.listUsers(request);
                }

                for(User user : response.users()) {
                 System.out.format("\n Retrieved user %s", user.userName());
                }

                if(!response.isTruncated()) {
                  done = true;
                } else {
                    newMarker = response.marker();
                }
            }
        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Aktualisiere einen Benutzer
<a name="updating-a-user"></a>

Um einen Benutzer zu aktualisieren, rufen Sie die `updateUser` Methode des IamClient Objekts auf, die ein [UpdateUserRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/UpdateUserRequest.html)Objekt verwendet, mit dem Sie den *Namen* oder *Pfad* des Benutzers ändern können.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.UpdateUserRequest;
```

 **Code** 

```
    public static void updateIAMUser(IamClient iam, String curName,String newName ) {

        try {
            UpdateUserRequest request = UpdateUserRequest.builder()
                    .userName(curName)
                    .newUserName(newName)
                    .build();

            iam.updateUser(request);
            System.out.printf("Successfully updated user to username %s",
                newName);
        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
      }
```

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

## Einen Benutzer löschen
<a name="deleting-a-user"></a>

Um einen Benutzer zu löschen, rufen Sie die IamClient `deleteUser` Anfrage mit einem [UpdateUserRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/UpdateUserRequest.html)Objektsatz mit dem zu löschenden Benutzernamen auf.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.DeleteUserRequest;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void deleteIAMUser(IamClient iam, String userName) {

        try {
            DeleteUserRequest request = DeleteUserRequest.builder()
                    .userName(userName)
                    .build();

            iam.deleteUser(request);
            System.out.println("Successfully deleted IAM user " + userName);
        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [IAM Benutzer](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users.html) im IAM Benutzerhandbuch
+  [IAM Benutzer im IAM Benutzerhandbuch verwalten](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_manage.html)
+  [CreateUser](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreateUser.html)in der IAM API-Referenz
+  [ListUsers](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListUsers.html)in der IAM API-Referenz
+  [UpdateUser](https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateUser.html)in der IAM API-Referenz
+  [DeleteUser](https://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteUser.html)in der IAM API-Referenz

# Erstellen Sie IAM-Richtlinien mit dem AWS SDK for Java 2.x
<a name="feature-iam-policy-builder"></a>

Die [IAM Policy Builder API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/package-summary.html) ist eine Bibliothek, mit der Sie [IAM-Richtlinien in Java erstellen und in (IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html)) hochladen können. AWS Identity and Access Management 

Anstatt eine IAM-Richtlinie durch manuelles Zusammenstellen einer JSON-Zeichenfolge oder durch Lesen einer Datei zu erstellen, bietet die API einen clientseitigen, objektorientierten Ansatz zur Generierung der JSON-Zeichenfolge. Wenn Sie eine bestehende IAM-Richtlinie im JSON-Format lesen, konvertiert die API sie zur Bearbeitung in eine Instanz. [IamPolicy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamPolicy.html)

Die IAM Policy Builder-API wurde mit Version 2.20.105 des SDK verfügbar. Verwenden Sie also diese oder eine spätere Version in Ihrer Maven-Build-Datei. Die neueste Versionsnummer des SDK ist in Maven Central [aufgeführt.](https://central.sonatype.com/artifact/software.amazon.awssdk/iam-policy-builder)

Das folgende Snippet zeigt ein Beispiel für einen Abhängigkeitsblock für eine Maven-Datei. `pom.xml` Auf diese Weise können Sie die IAM Policy Builder-API in Ihrem Projekt verwenden. 

```
<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>iam-policy-builder</artifactId>
    <version>2.27.21</version>
</dependency>
```

## Erstellen eines `IamPolicy`
<a name="iam-policy-builder-create"></a>

In diesem Abschnitt finden Sie mehrere Beispiele für die Erstellung von Richtlinien mithilfe der IAM Policy Builder-API.

Beginnen Sie in jedem der folgenden Beispiele mit der `[IamPolicy.Builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamPolicy.Builder.html)` und fügen Sie mithilfe der `addStatement` Methode eine oder mehrere Anweisungen hinzu. Diesem Muster folgend verfügt der [IamStatement.Builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/policybuilder/iam/IamStatement.Builder.html) über Methoden, um der Anweisung den Effekt, die Aktionen, Ressourcen und Bedingungen hinzuzufügen.

### Beispiel: Erstellen Sie eine zeitbasierte Richtlinie
<a name="iam-policy-builder-create-ex-time-based"></a>

Das folgende Beispiel erstellt eine identitätsbasierte Richtlinie, die die Amazon DynamoDB `GetItem` DynamoDB-Aktion zwischen zwei Zeitpunkten ermöglicht.

```
    public String timeBasedPolicyExample() {
        IamPolicy policy = IamPolicy.builder()
                .addStatement(b -> b
                        .effect(IamEffect.ALLOW)
                        .addAction("dynamodb:GetItem")
                        .addResource(IamResource.ALL)
                        .addCondition(b1 -> b1
                                .operator(IamConditionOperator.DATE_GREATER_THAN)
                                .key("aws:CurrentTime")
                                .value("2020-04-01T00:00:00Z"))
                        .addCondition(b1 -> b1
                                .operator(IamConditionOperator.DATE_LESS_THAN)
                                .key("aws:CurrentTime")
                                .value("2020-06-30T23:59:59Z")))
                .build();

        // Use an IamPolicyWriter to write out the JSON string to a more readable format.
        return policy.toJson(IamPolicyWriter.builder()
                        .prettyPrint(true)
                        .build());
    }
```

#### JSON-Ausgabe
<a name="iam-builder-ex-json-date"></a>

Die letzte Anweisung im vorherigen Beispiel gibt die folgende JSON-Zeichenfolge zurück. 

Weitere Informationen zu diesem [Beispiel](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws-dates.html) finden Sie im *AWS Identity and Access Management Benutzerhandbuch*.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Effect": "Allow",
        "Action": "dynamodb:GetItem",
        "Resource": "*",
        "Condition": {
            "DateGreaterThan": {
                "aws:CurrentTime": "2020-04-01T00:00:00Z"
            },
            "DateLessThan": {
                "aws:CurrentTime": "2020-06-30T23:59:59Z"
            }
        }
    }
}
```

------

### Beispiel: Geben Sie mehrere Bedingungen an
<a name="iam-policy-builder-create-ex-multi-conditions"></a>

Das folgende Beispiel zeigt, wie Sie eine identitätsbasierte Richtlinie erstellen können, die den Zugriff auf bestimmte DynamoDB-Attribute ermöglicht. Die Richtlinie enthält zwei Bedingungen.

```
    public String multipleConditionsExample() {
        IamPolicy policy = IamPolicy.builder()
                .addStatement(b -> b
                        .effect(IamEffect.ALLOW)
                        .addAction("dynamodb:GetItem")
                        .addAction("dynamodb:BatchGetItem")
                        .addAction("dynamodb:Query")
                        .addAction("dynamodb:PutItem")
                        .addAction("dynamodb:UpdateItem")
                        .addAction("dynamodb:DeleteItem")
                        .addAction("dynamodb:BatchWriteItem")
                        .addResource("arn:aws:dynamodb:*:*:table/table-name")
                        .addConditions(IamConditionOperator.STRING_EQUALS.addPrefix("ForAllValues:"),
                                "dynamodb:Attributes",
                                List.of("column-name1", "column-name2", "column-name3"))
                        .addCondition(b1 -> b1.operator(IamConditionOperator.STRING_EQUALS.addSuffix("IfExists"))
                                .key("dynamodb:Select")
                                .value("SPECIFIC_ATTRIBUTES")))
                .build();

        return policy.toJson(IamPolicyWriter.builder()
                .prettyPrint(true).build());
    }
```

#### JSON-Ausgabe
<a name="iam-builder-ex-json-multi-cond"></a>

Die letzte Anweisung im vorherigen Beispiel gibt die folgende JSON-Zeichenfolge zurück. 

Weitere Informationen zu diesem [Beispiel](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_dynamodb_attributes.html) finden Sie im *AWS Identity and Access Management Benutzerhandbuch*.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "dynamodb:GetItem",
            "dynamodb:BatchGetItem",
            "dynamodb:Query",
            "dynamodb:PutItem",
            "dynamodb:UpdateItem",
            "dynamodb:DeleteItem",
            "dynamodb:BatchWriteItem"
        ],
        "Resource": "arn:aws:dynamodb:*:*:table/table-name",
        "Condition": {
            "ForAllValues:StringEquals": {
                "dynamodb:Attributes": [
                    "column-name1",
                    "column-name2",
                    "column-name3"
                ]
            },
            "StringEqualsIfExists": {
                "dynamodb:Select": "SPECIFIC_ATTRIBUTES"
            }
        }
    }
}
```

------

### Beispiel: Geben Sie Principals an
<a name="iam-policy-builder-create-ex-principals"></a>

Das folgende Beispiel zeigt, wie eine ressourcenbasierte Richtlinie erstellt wird, die allen Prinzipalen mit Ausnahme der in der Bedingung angegebenen den Zugriff auf einen Bucket verweigert.

```
    public String specifyPrincipalsExample() {
        IamPolicy policy = IamPolicy.builder()
                .addStatement(b -> b
                        .effect(IamEffect.DENY)
                        .addAction("s3:*")
                        .addPrincipal(IamPrincipal.ALL)
                        .addResource("arn:aws:s3:::BUCKETNAME/*")
                        .addResource("arn:aws:s3:::BUCKETNAME")
                        .addCondition(b1 -> b1
                                .operator(IamConditionOperator.ARN_NOT_EQUALS)
                                .key("aws:PrincipalArn")
                                .value("arn:aws:iam::444455556666:user/user-name")))
                .build();
        return policy.toJson(IamPolicyWriter.builder()
                .prettyPrint(true).build());
    }
```

#### JSON-Ausgabe
<a name="iam-policy-builder-create-json-ex-principals"></a>

Die letzte Anweisung im vorherigen Beispiel gibt die folgende JSON-Zeichenfolge zurück. 

Weitere Informationen zu diesem [Beispiel](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-anonymous) finden Sie im *AWS Identity and Access Management Benutzerhandbuch*.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement" : {
    "Effect" : "Deny",
    "Principal" : "*",
    "Action" : "s3:*",
    "Resource" : [ "arn:aws:s3:::BUCKETNAME/*", "arn:aws:s3:::BUCKETNAME" ],
    "Condition" : {
      "ArnNotEquals" : {
        "aws:PrincipalArn" : "arn:aws:iam::444455556666:user/user-name"
      }
    }
  }
}
```

------

### Beispiel: Kontenübergreifenden Zugriff zulassen
<a name="iam-policy-builder-create-ex-cross-account"></a>

Das folgende Beispiel zeigt, wie Sie es einer anderen Person ermöglichen AWS-Konto , Objekte in Ihren Bucket hochzuladen, während Sie gleichzeitig die volle Eigentümerkontrolle über die hochgeladenen Objekte behalten. 

```
    public String allowCrossAccountAccessExample() {
        IamPolicy policy = IamPolicy.builder()
                .addStatement(b -> b
                        .effect(IamEffect.ALLOW)
                        .addPrincipal(IamPrincipalType.AWS, "111122223333")
                        .addAction("s3:PutObject")
                        .addResource("arn:aws:s3:::amzn-s3-demo-bucket/*")
                        .addCondition(b1 -> b1
                                .operator(IamConditionOperator.STRING_EQUALS)
                                .key("s3:x-amz-acl")
                                .value("bucket-owner-full-control")))
                .build();
        return policy.toJson(IamPolicyWriter.builder()
                .prettyPrint(true).build());
    }
```

#### JSON-Ausgabe
<a name="iam-policy-builder-create-ex-json-cross-account"></a>

Die letzte Anweisung im vorherigen Beispiel gibt die folgende JSON-Zeichenfolge zurück. 

Weitere Informationen zu diesem [Beispiel](https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html#example-bucket-policies-acl-2) finden Sie im *Amazon Simple Storage Service-Benutzerhandbuch*.

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement" : {
    "Effect" : "Allow",
    "Principal" : {
      "AWS" : "111122223333"
    },
    "Action" : "s3:PutObject",
    "Resource" : "arn:aws:s3:::amzn-s3-demo-bucket/*",
    "Condition" : {
      "StringEquals" : {
        "s3:x-amz-acl" : "bucket-owner-full-control"
      }
    }
  }
}
```

------

## Verwenden Sie eine `IamPolicy` mit IAM
<a name="iam-policy-builder-work-with-service"></a>

Nachdem Sie eine `IamPolicy` Instanz erstellt haben, verwenden Sie eine, [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/IamClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/IamClient.html)um mit dem IAM-Dienst zu arbeiten. 

Im folgenden Beispiel wird eine Richtlinie erstellt, die es einer [IAM-Identität](https://docs.aws.amazon.com/IAM/latest/UserGuide/id.html) ermöglicht, Elemente in eine DynamoDB-Tabelle in dem Konto zu schreiben, das mit dem Parameter angegeben ist. `accountID` Die Richtlinie wird dann als JSON-Zeichenfolge in IAM hochgeladen.

```
    public String createAndUploadPolicyExample(IamClient iam, String accountID, String policyName) {
        // Build the policy.
        IamPolicy policy =
                IamPolicy.builder() // 'version' defaults to "2012-10-17".
                        .addStatement(IamStatement.builder()
                                .effect(IamEffect.ALLOW)
                                .addAction("dynamodb:PutItem")
                                .addResource("arn:aws:dynamodb:us-east-1:" + accountID + ":table/exampleTableName")
                                .build())
                        .build();
        // Upload the policy.
        iam.createPolicy(r -> r.policyName(policyName).policyDocument(policy.toJson()));
        return policy.toJson(IamPolicyWriter.builder().prettyPrint(true).build());
    }
```

Das nächste Beispiel baut auf dem vorherigen Beispiel auf. Der Code lädt die Richtlinie herunter und verwendet sie als Grundlage für eine neue Richtlinie, indem die Anweisung kopiert und geändert wird. Die neue Richtlinie wird dann hochgeladen.

```
    public String createNewBasedOnExistingPolicyExample(IamClient iam, String accountID, String policyName, String newPolicyName) {

        String policyArn = "arn:aws:iam::" + accountID + ":policy/" + policyName;
        GetPolicyResponse getPolicyResponse = iam.getPolicy(r -> r.policyArn(policyArn));

        String policyVersion = getPolicyResponse.policy().defaultVersionId();
        GetPolicyVersionResponse getPolicyVersionResponse =
                iam.getPolicyVersion(r -> r.policyArn(policyArn).versionId(policyVersion));

        // Create an IamPolicy instance from the JSON string returned from IAM.
        String decodedPolicy = URLDecoder.decode(getPolicyVersionResponse.policyVersion().document(), StandardCharsets.UTF_8);
        IamPolicy policy = IamPolicy.fromJson(decodedPolicy);

            /*
             All IamPolicy components are immutable, so use the copy method that creates a new instance that
             can be altered in the same method call.

             Add the ability to get an item from DynamoDB as an additional action.
            */
        IamStatement newStatement = policy.statements().get(0).copy(s -> s.addAction("dynamodb:GetItem"));

        // Create a new statement that replaces the original statement.
        IamPolicy newPolicy = policy.copy(p -> p.statements(Arrays.asList(newStatement)));

        // Upload the new policy. IAM now has both policies.
        iam.createPolicy(r -> r.policyName(newPolicyName)
                .policyDocument(newPolicy.toJson()));

        return newPolicy.toJson(IamPolicyWriter.builder().prettyPrint(true).build());
    }
```

### IamClient
<a name="iam-policy-builder-work-with-serivce-create-client"></a>

In den vorherigen Beispielen wird ein `IamClient` Argument verwendet, das wie im folgenden Codeausschnitt dargestellt erstellt wurde.

```
IamClient iam = IamClient.builder().region(Region.AWS_GLOBAL).build();
```

### Richtlinien in JSON
<a name="iam-policy-builder-work-with-serivce-json"></a>

Die Beispiele geben die folgenden JSON-Zeichenketten zurück.

```
First example
{
  "Version": "2012-10-17",		 	 	 
  "Statement" : {
    "Effect" : "Allow",
    "Action" : "dynamodb:PutItem",
    "Resource" : "arn:aws:dynamodb:us-east-1:111122223333:table/exampleTableName"
  }
}

Second example
{
  "Version": "2012-10-17",		 	 	 
  "Statement" : {
    "Effect" : "Allow",
    "Action" : [ "dynamodb:PutItem", "dynamodb:GetItem" ],
    "Resource" : "arn:aws:dynamodb:us-east-1:111122223333:table/exampleTableName"
  }
}
```

# Mit IAM Richtlinien arbeiten
<a name="examples-iam-policies"></a>

## Erstellen einer Richtlinie
<a name="create-a-policy"></a>

Um eine neue Richtlinie zu erstellen, geben Sie den Namen der Richtlinie und ein Richtliniendokument im JSON-Format in einer Methode [CreatePolicyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/CreatePolicyRequest.html)an. IamClient `createPolicy`

 **Importe** 

```
import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.services.iam.model.CreatePolicyRequest;
import software.amazon.awssdk.services.iam.model.CreatePolicyResponse;
import software.amazon.awssdk.services.iam.model.GetPolicyRequest;
import software.amazon.awssdk.services.iam.model.GetPolicyResponse;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.waiters.IamWaiter;
```

 **Code** 

```
    public static String createIAMPolicy(IamClient iam, String policyName ) {

        try {
            // Create an IamWaiter object
            IamWaiter iamWaiter = iam.waiter();

            CreatePolicyRequest request = CreatePolicyRequest.builder()
                .policyName(policyName)
                .policyDocument(PolicyDocument).build();

            CreatePolicyResponse response = iam.createPolicy(request);

            // Wait until the policy is created
            GetPolicyRequest polRequest = GetPolicyRequest.builder()
                    .policyArn(response.policy().arn())
                    .build();

            WaiterResponse<GetPolicyResponse> waitUntilPolicyExists = iamWaiter.waitUntilPolicyExists(polRequest);
            waitUntilPolicyExists.matched().response().ifPresent(System.out::println);
            return response.policy().arn();

         } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return "" ;
    }
```

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

## Abrufen einer Richtlinie
<a name="get-a-policy"></a>

Um eine bestehende Richtlinie abzurufen, rufen Sie die IamClient `getPolicy` Methode auf und geben den ARN der Richtlinie in einem [GetPolicyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/GetPolicyRequest.html)Objekt an.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.GetPolicyRequest;
import software.amazon.awssdk.services.iam.model.GetPolicyResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void getIAMPolicy(IamClient iam, String policyArn) {

        try {
            GetPolicyRequest request = GetPolicyRequest.builder()
                .policyArn(policyArn).build();

            GetPolicyResponse response = iam.getPolicy(request);
            System.out.format("Successfully retrieved policy %s",
                response.policy().policyName());

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Anfügen einer Rollenrichtlinie
<a name="attach-a-role-policy"></a>

Sie können eine Richtlinie an eine IAM [Rolle](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html) anhängen, indem Sie die `attachRolePolicy` Methode IamClient s aufrufen und ihr den Rollennamen und den Richtlinien-ARN in einer angeben [AttachRolePolicyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/AttachRolePolicyRequest.html).

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.AttachRolePolicyRequest;
import software.amazon.awssdk.services.iam.model.AttachedPolicy;
import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesRequest;
import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesResponse;
import java.util.List;
```

 **Code** 

```
    public static void attachIAMRolePolicy(IamClient iam, String roleName, String policyArn ) {

        try {

             ListAttachedRolePoliciesRequest request = ListAttachedRolePoliciesRequest.builder()
                    .roleName(roleName)
                    .build();

            ListAttachedRolePoliciesResponse  response = iam.listAttachedRolePolicies(request);
            List<AttachedPolicy> attachedPolicies = response.attachedPolicies();

            // Ensure that the policy is not attached to this role
            String polArn = "";
            for (AttachedPolicy policy: attachedPolicies) {
                polArn = policy.policyArn();
                if (polArn.compareTo(policyArn)==0) {
                   System.out.println(roleName +
                            " policy is already attached to this role.");
                    return;
                }
          }

            AttachRolePolicyRequest attachRequest =
                AttachRolePolicyRequest.builder()
                        .roleName(roleName)
                        .policyArn(policyArn)
                        .build();

            iam.attachRolePolicy(attachRequest);

            System.out.println("Successfully attached policy " + policyArn +
                " to role " + roleName);

         } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
          }

     System.out.println("Done");
    }
```

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

## Auflisten angefügter Rollenrichtlinien
<a name="list-attached-role-policies"></a>

Listet die angehängten Richtlinien für eine Rolle auf, indem Sie die `listAttachedRolePolicies` Methode IamClient's aufrufen. Es wird ein [ListAttachedRolePoliciesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListAttachedRolePoliciesRequest.html)Objekt benötigt, das den Rollennamen enthält, um die Richtlinien aufzulisten.

Rufen Sie das zurückgegebene [ListAttachedRolePoliciesResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListAttachedRolePoliciesResponse.html)Objekt `getAttachedPolicies` auf, um die Liste der angehängten Richtlinien abzurufen. Die Ergebnisse sind evtl. gekürzt. Wenn die `isTruncated`-Methode des `ListAttachedRolePoliciesResponse`-Objekts `true` zurückgibt, rufen Sie die `marker`-Methode des `ListAttachedRolePoliciesResponse`-Objekts auf. Verwenden Sie den zurückgegebenen Marker, um eine neue Anforderung zu erstellen, und verwenden Sie sie, um `listAttachedRolePolicies` erneut aufzurufen, um die nächste Ergebnisteilmenge zu erhalten.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.AttachRolePolicyRequest;
import software.amazon.awssdk.services.iam.model.AttachedPolicy;
import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesRequest;
import software.amazon.awssdk.services.iam.model.ListAttachedRolePoliciesResponse;
import java.util.List;
```

 **Code** 

```
    public static void attachIAMRolePolicy(IamClient iam, String roleName, String policyArn ) {

        try {

             ListAttachedRolePoliciesRequest request = ListAttachedRolePoliciesRequest.builder()
                    .roleName(roleName)
                    .build();

            ListAttachedRolePoliciesResponse  response = iam.listAttachedRolePolicies(request);
            List<AttachedPolicy> attachedPolicies = response.attachedPolicies();

            // Ensure that the policy is not attached to this role
            String polArn = "";
            for (AttachedPolicy policy: attachedPolicies) {
                polArn = policy.policyArn();
                if (polArn.compareTo(policyArn)==0) {
                   System.out.println(roleName +
                            " policy is already attached to this role.");
                    return;
                }
          }

            AttachRolePolicyRequest attachRequest =
                AttachRolePolicyRequest.builder()
                        .roleName(roleName)
                        .policyArn(policyArn)
                        .build();

            iam.attachRolePolicy(attachRequest);

            System.out.println("Successfully attached policy " + policyArn +
                " to role " + roleName);

         } catch (IamException e) {
                System.err.println(e.awsErrorDetails().errorMessage());
                System.exit(1);
          }

     System.out.println("Done");
    }
```

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

## Trennen einer Rollenrichtlinie
<a name="detach-a-role-policy"></a>

Um eine Richtlinie von einer Rolle zu trennen, rufen Sie die `detachRolePolicy` Methode IamClient's auf und geben Sie ihr den Rollennamen und den Richtlinien-ARN in a. [DetachRolePolicyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/DetachRolePolicyRequest.html)

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.DetachRolePolicyRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void detachPolicy(IamClient iam, String roleName, String policyArn ) {

        try {
            DetachRolePolicyRequest request = DetachRolePolicyRequest.builder()
                    .roleName(roleName)
                    .policyArn(policyArn)
                    .build();

            iam.detachRolePolicy(request);
            System.out.println("Successfully detached policy " + policyArn +
                " from role " + roleName);

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [Überblick über die IAM Richtlinien](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies.html) im IAM Benutzerhandbuch.
+ [AWS Referenz zu den IAM-Richtlinien](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html) im IAM Benutzerhandbuch.
+  [CreatePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html)in der IAM API-Referenz
+  [GetPolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetPolicy.html)in der IAM API-Referenz
+  [AttachRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_AttachRolePolicy.html)in der IAM API-Referenz
+  [ListAttachedRolePolicies](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListAttachedRolePolicies.html)in der IAM API-Referenz
+  [DetachRolePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_DetachRolePolicy.html)in der IAM API-Referenz

# Arbeiten Sie mit IAM Serverzertifikaten
<a name="examples-iam-server-certificates"></a>

Um HTTPS-Verbindungen zu Ihrer Website oder Anwendung zu aktivieren AWS, benötigen Sie ein SSL/TLS *Serverzertifikat*. Sie können ein Serverzertifikat verwenden, das von einem externen Anbieter bereitgestellt wurde AWS Certificate Manager oder das Sie von einem externen Anbieter bezogen haben.

Wir empfehlen, dass Sie ACM es für die Bereitstellung, Verwaltung und Bereitstellung Ihrer Serverzertifikate verwenden. Damit können ACM Sie ein Zertifikat anfordern, es für Ihre AWS Ressourcen bereitstellen und die Zertifikatserneuerung für Sie ACM übernehmen lassen. Die von bereitgestellten Zertifikate ACM sind kostenlos. Weitere Informationen zu ACM finden Sie im [AWS Certificate Manager Benutzerhandbuch](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html).

## Abrufen eines Serverzertifikats
<a name="get-a-server-certificate"></a>

Sie können ein Serverzertifikat abrufen, indem Sie die `getServerCertificate` Methode IamClient 'aufrufen und ihr a [GetServerCertificateRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/GetServerCertificateRequest.html)zusammen mit dem Namen des Zertifikats übergeben.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.GetServerCertificateRequest;
import software.amazon.awssdk.services.iam.model.GetServerCertificateResponse;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void getCertificate(IamClient iam,String certName ) {

        try {
            GetServerCertificateRequest request = GetServerCertificateRequest.builder()
                    .serverCertificateName(certName)
                    .build();

            GetServerCertificateResponse response = iam.getServerCertificate(request);
            System.out.format("Successfully retrieved certificate with body %s",
                response.serverCertificate().certificateBody());

         } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/iam/src/main/java/com/example/iam/GetServerCertificate.java) finden Sie unter GitHub.

## Auflisten von Serverzertifikaten
<a name="list-server-certificates"></a>

Um Ihre Serverzertifikate aufzulisten, rufen Sie die `listServerCertificates` Methode IamClient's mit einem auf [ListServerCertificatesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListServerCertificatesRequest.html). Sie gibt [ListServerCertificatesResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ListServerCertificatesResponse.html) zurück.

Rufen Sie die `serverCertificateMetadataList` Methode des zurückgegebenen `ListServerCertificateResponse` Objekts auf, um eine Liste von [ServerCertificateMetadata](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/ServerCertificateMetadata.html)Objekten abzurufen, mit denen Sie Informationen zu den einzelnen Zertifikaten abrufen können.

Die Ergebnisse sind evtl. gekürzt. Wenn die `isTruncated`-Methode des `ListServerCertificateResponse`-Objekts `true` zurückgibt, rufen Sie die `marker`-Methode des `ListServerCertificatesResponse`-Objekts auf und verwenden den Marker, um eine neue Anforderung zu erstellen. Verwenden Sie die neue Anforderung, um `listServerCertificates` erneut aufzurufen, um die nächsten Teilergebnisse zu erhalten.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.ListServerCertificatesRequest;
import software.amazon.awssdk.services.iam.model.ListServerCertificatesResponse;
import software.amazon.awssdk.services.iam.model.ServerCertificateMetadata;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
```

 **Code** 

```
    public static void listCertificates(IamClient iam) {

        try {
            boolean done = false;
            String newMarker = null;

            while(!done) {
              ListServerCertificatesResponse response;

            if (newMarker == null) {
                ListServerCertificatesRequest request =
                        ListServerCertificatesRequest.builder().build();
                response = iam.listServerCertificates(request);
            } else {
                ListServerCertificatesRequest request =
                        ListServerCertificatesRequest.builder()
                                .marker(newMarker).build();
                response = iam.listServerCertificates(request);
            }

            for(ServerCertificateMetadata metadata :
                    response.serverCertificateMetadataList()) {
                System.out.printf("Retrieved server certificate %s",
                        metadata.serverCertificateName());
            }

            if(!response.isTruncated()) {
                done = true;
            } else {
                newMarker = response.marker();
            }
        }

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/iam/src/main/java/com/example/iam/ListServerCertificates.java) finden Sie unter GitHub.

## Aktualisieren eines Serverzertifikats
<a name="update-a-server-certificate"></a>

Sie können den Namen oder Pfad eines Serverzertifikats aktualisieren, indem Sie die `updateServerCertificate` Methode IamClient's aufrufen. Sie benötigt eine [UpdateServerCertificateRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/UpdateServerCertificateRequest.html)Objektgruppe mit dem aktuellen Namen des Serverzertifikats und entweder einem neuen Namen oder einem neuen Pfad zur Verwendung.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
import software.amazon.awssdk.services.iam.model.UpdateServerCertificateRequest;
import software.amazon.awssdk.services.iam.model.UpdateServerCertificateResponse;
```

 **Code** 

```
    public static void updateCertificate(IamClient iam, String curName, String newName) {

        try {
            UpdateServerCertificateRequest request =
                UpdateServerCertificateRequest.builder()
                        .serverCertificateName(curName)
                        .newServerCertificateName(newName)
                        .build();

            UpdateServerCertificateResponse response =
                iam.updateServerCertificate(request);


            System.out.printf("Successfully updated server certificate to name %s",
                newName);

        } catch (IamException e) {
             System.err.println(e.awsErrorDetails().errorMessage());
             System.exit(1);
        }
     }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/iam/src/main/java/com/example/iam/UpdateServerCertificate.java) finden Sie unter GitHub.

## Löschen eines Serverzertifikats
<a name="delete-a-server-certificate"></a>

Um ein Serverzertifikat zu löschen, rufen Sie die `deleteServerCertificate` Methode IamClient 'mit einem auf, das den Namen des Zertifikats [DeleteServerCertificateRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/iam/model/DeleteServerCertificateRequest.html)enthält.

 **Importe** 

```
import software.amazon.awssdk.services.iam.model.DeleteServerCertificateRequest;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.iam.IamClient;
import software.amazon.awssdk.services.iam.model.IamException;
```

 **Code** 

```
    public static void deleteCert(IamClient iam,String certName ) {

        try {
            DeleteServerCertificateRequest request =
                DeleteServerCertificateRequest.builder()
                        .serverCertificateName(certName)
                        .build();

            iam.deleteServerCertificate(request);
            System.out.println("Successfully deleted server certificate " +
                    certName);

        } catch (IamException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/0b1785e42949ebf959eaa0f0da4dc2a48f92ea25/javav2/example_code/iam/src/main/java/com/example/iam/DeleteServerCertificate.java) finden Sie unter GitHub.

## Weitere Informationen
<a name="more-information"></a>
+  [Arbeiten mit Serverzertifikaten](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_server-certs.html) im IAM Benutzerhandbuch
+  [GetServerCertificate](https://docs.aws.amazon.com/IAM/latest/APIReference/API_GetServerCertificate.html)in der IAM API-Referenz
+  [ListServerCertificates](https://docs.aws.amazon.com/IAM/latest/APIReference/API_ListServerCertificates.html)in der IAM API-Referenz
+  [UpdateServerCertificate](https://docs.aws.amazon.com/IAM/latest/APIReference/API_UpdateServerCertificate.html)in der IAM API-Referenz
+  [DeleteServerCertificate](https://docs.aws.amazon.com/IAM/latest/APIReference/API_DeleteServerCertificate.html)in der IAM API-Referenz
+  [AWS Certificate Manager Benutzerhandbuch](https://docs.aws.amazon.com/acm/latest/userguide/) 

# Arbeite mit Kinesis
<a name="examples-kinesis"></a>

Dieser Abschnitt enthält Beispiele für die Programmierung [Amazon Kinesis](https://docs.aws.amazon.com/kinesis/)mit AWS SDK für Java 2.x.

Weitere Informationen zu Kinesis finden Sie im [Amazon Kinesis Entwicklerhandbuch](https://docs.aws.amazon.com/streams/latest/dev/introduction.html).

Die folgenden Beispiele enthalten nur den Code, der zur Demonstration jeder Technik nötig ist. Der [vollständige Beispielcode ist verfügbar unter GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2). Von dort aus können Sie eine einzelne Quelldatei herunterladen oder das Repository klonen, um alle Beispiele lokal zu erstellen und auszuführen.

**Topics**
+ [Abonnieren Amazon Kinesis Data Streams](examples-kinesis-stream.md)

# Abonnieren Amazon Kinesis Data Streams
<a name="examples-kinesis-stream"></a>

Die folgenden Beispiele zeigen Ihnen, wie Sie mit `subscribeToShard` dieser Methode Daten aus Amazon Kinesis Datenströmen abrufen und verarbeiten. Kinesis Data Streams verwendet jetzt die erweiterte Fanout-Funktion und eine HTTP/2-Datenabruf-API mit niedriger Latenz, was es Entwicklern erleichtert, mehrere Hochleistungsanwendungen mit niedriger Latenz auf demselben Datenstream auszuführen. Kinesis 

## Einrichten
<a name="set-up"></a>

Erstellen Sie zunächst einen asynchronen Client und ein Objekt Kinesis . [SubscribeToShardRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kinesis/model/SubscribeToShardRequest.html) Diese Objekte werden in jedem der folgenden Beispiele verwendet, um Kinesis Ereignisse zu abonnieren.

 **Importe** 

```
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import software.amazon.awssdk.core.async.SdkPublisher;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kinesis.KinesisAsyncClient;
import software.amazon.awssdk.services.kinesis.model.ShardIteratorType;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardEvent;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardEventStream;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardRequest;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardResponse;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardResponseHandler;
```

 **Code** 

```
        Region region = Region.US_EAST_1;
        KinesisAsyncClient client = KinesisAsyncClient.builder()
        .region(region)
        .build();

        SubscribeToShardRequest request = SubscribeToShardRequest.builder()
                .consumerARN(CONSUMER_ARN)
                .shardId("arn:aws:kinesis:us-east-1:111122223333:stream/StockTradeStream")
                .startingPosition(s -> s.type(ShardIteratorType.LATEST)).build();
```

## Verwenden Sie die Builder-Schnittstelle
<a name="use-the-builder-interface"></a>

Sie können die `builder` Methode verwenden, um die Erstellung von zu vereinfachen [SubscribeToShardResponseHandler](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kinesis/model/SubscribeToShardResponseHandler.html).

Mit dem Builder können Sie jeden Lebenszyklusrückruf mit einem Methodenaufruf versehen, anstatt die vollständige Schnittstelle zu implementieren.

 **Code** 

```
    private static CompletableFuture<Void> responseHandlerBuilder(KinesisAsyncClient client, SubscribeToShardRequest request) {
        SubscribeToShardResponseHandler responseHandler = SubscribeToShardResponseHandler
                .builder()
                .onError(t -> System.err.println("Error during stream - " + t.getMessage()))
                .onComplete(() -> System.out.println("All records stream successfully"))
                // Must supply some type of subscriber
                .subscriber(e -> System.out.println("Received event - " + e))
                .build();
        return client.subscribeToShard(request, responseHandler);
    }
```

Um mehr Kontrolle über den Herausgeber zu erhalten, können Sie ihn mit der Methode `publisherTransformer` anzupassen.

 **Code** 

```
    private static CompletableFuture<Void> responseHandlerBuilderPublisherTransformer(KinesisAsyncClient client, SubscribeToShardRequest request) {
        SubscribeToShardResponseHandler responseHandler = SubscribeToShardResponseHandler
                .builder()
                .onError(t -> System.err.println("Error during stream - " + t.getMessage()))
                .publisherTransformer(p -> p.filter(e -> e instanceof SubscribeToShardEvent).limit(100))
                .subscriber(e -> System.out.println("Received event - " + e))
                .build();
        return client.subscribeToShard(request, responseHandler);
    }
```

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

## Verwenden Sie einen benutzerdefinierten Antworthandler
<a name="use-a-custom-response-handler"></a>

Implementieren Sie die `SubscribeToShardResponseHandler` Schnittstelle, um die vollständige Kontrolle über den Abonnenten und den Herausgeber zu erhalten.

In diesem Beispiel implementieren Sie die Methode `onEventStream`, die Vollzugriff auf den Herausgeber ermöglicht. Hier wird veranschaulicht, wie der Herausgeber für durch den Abonnenten zu druckende Ereignisdatensätze transformiert wird.

 **Code** 

```
    private static CompletableFuture<Void> responseHandlerBuilderClassic(KinesisAsyncClient client, SubscribeToShardRequest request) {
        SubscribeToShardResponseHandler responseHandler = new SubscribeToShardResponseHandler() {

            @Override
            public void responseReceived(SubscribeToShardResponse response) {
                System.out.println("Receieved initial response");
            }

            @Override
            public void onEventStream(SdkPublisher<SubscribeToShardEventStream> publisher) {
                publisher
                        // Filter to only SubscribeToShardEvents
                        .filter(SubscribeToShardEvent.class)
                        // Flat map into a publisher of just records
                        .flatMapIterable(SubscribeToShardEvent::records)
                        // Limit to 1000 total records
                        .limit(1000)
                        // Batch records into lists of 25
                        .buffer(25)
                        // Print out each record batch
                        .subscribe(batch -> System.out.println("Record Batch - " + batch));
            }

            @Override
            public void complete() {
                System.out.println("All records stream successfully");
            }

            @Override
            public void exceptionOccurred(Throwable throwable) {
                System.err.println("Error during stream - " + throwable.getMessage());
            }
        };
        return client.subscribeToShard(request, responseHandler);
    }
```

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

## Verwenden Sie die Besucherschnittstelle
<a name="use-the-visitor-interface"></a>

Sie können mithilfe eines [Visitor](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kinesis/model/SubscribeToShardResponseHandler.Visitor.html)-Objekts bestimmte Ereignisse abonnieren, an denen Sie interessiert sind.

 **Code** 

```
    private static CompletableFuture<Void> responseHandlerBuilderVisitorBuilder(KinesisAsyncClient client, SubscribeToShardRequest request) {
        SubscribeToShardResponseHandler.Visitor visitor = SubscribeToShardResponseHandler.Visitor
                .builder()
                .onSubscribeToShardEvent(e -> System.out.println("Received subscribe to shard event " + e))
                .build();
        SubscribeToShardResponseHandler responseHandler = SubscribeToShardResponseHandler
                .builder()
                .onError(t -> System.err.println("Error during stream - " + t.getMessage()))
                .subscriber(visitor)
                .build();
        return client.subscribeToShard(request, responseHandler);
    }
```

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

## Verwenden Sie einen benutzerdefinierten Abonnenten
<a name="use-a-custom-subscriber"></a>

Sie können auch Ihren eigenen benutzerdefinierten Abonnenten implementieren, um den Stream zu abonnieren.

Dieser Codeausschnitt zeigt einen Beispiel für einen Abonnenten.

 **Code** 

```
    private static class MySubscriber implements Subscriber<SubscribeToShardEventStream> {

        private Subscription subscription;
        private AtomicInteger eventCount = new AtomicInteger(0);

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

        @Override
        public void onNext(SubscribeToShardEventStream shardSubscriptionEventStream) {
            System.out.println("Received event " + shardSubscriptionEventStream);
            if (eventCount.incrementAndGet() >= 100) {
                // You can cancel the subscription at any time if you wish to stop receiving events.
                subscription.cancel();
            }
            subscription.request(1);
        }

        @Override
        public void onError(Throwable throwable) {
            System.err.println("Error occurred while stream - " + throwable.getMessage());
        }

        @Override
        public void onComplete() {
            System.out.println("Finished streaming all events");
        }
    }
```

Sie können den benutzerdefinierten Abonnenten an die `subscribe` Methode übergeben, wie im folgenden Codeausschnitt gezeigt.

 **Code** 

```
    private static CompletableFuture<Void> responseHandlerBuilderSubscriber(KinesisAsyncClient client, SubscribeToShardRequest request) {
        SubscribeToShardResponseHandler responseHandler = SubscribeToShardResponseHandler
                .builder()
                .onError(t -> System.err.println("Error during stream - " + t.getMessage()))
                .subscriber(MySubscriber::new)
                .build();
        return client.subscribeToShard(request, responseHandler);
    }
```

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

## Schreiben Sie Datensätze in einen Kinesis Datenstrom
<a name="write-data-records-into-a-kinesis-data-stream"></a>

Sie können das [KinesisClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kinesis/KinesisClient.html)Objekt verwenden, um Datensätze in einen Kinesis Datenstrom zu schreiben, indem Sie die `putRecords` Methode verwenden. Um diese Methode erfolgreich aufzurufen, erstellen Sie ein [PutRecordsRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/kinesis/model/PutRecordsRequest.html)Objekt. Sie übergeben den Namen des Datenstroms an die `streamName` Methode. Darüber hinaus müssen Sie die Daten mit der Methode `putRecords` übergeben (wie im folgenden Codebeispiel gezeigt).

 **Importe** 

```
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kinesis.KinesisClient;
import software.amazon.awssdk.services.kinesis.model.PutRecordRequest;
import software.amazon.awssdk.services.kinesis.model.KinesisException;
import software.amazon.awssdk.services.kinesis.model.DescribeStreamRequest;
import software.amazon.awssdk.services.kinesis.model.DescribeStreamResponse;
```

Beachten Sie im folgenden Java-Codebeispiel, dass das **StockTrade**Objekt als Daten verwendet wird, um in den Kinesis Datenstrom zu schreiben. Bevor Sie dieses Beispiel ausführen, stellen Sie sicher, dass Sie den Datenstream erstellt haben.

 **Code** 

```
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kinesis.KinesisClient;
import software.amazon.awssdk.services.kinesis.model.PutRecordRequest;
import software.amazon.awssdk.services.kinesis.model.KinesisException;
import software.amazon.awssdk.services.kinesis.model.DescribeStreamRequest;
import software.amazon.awssdk.services.kinesis.model.DescribeStreamResponse;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class StockTradesWriter {
    public static void main(String[] args) {
        final String usage = """

                Usage:
                    <streamName>

                Where:
                    streamName - The Amazon Kinesis data stream to which records are written (for example, StockTradeStream)
                """;

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

        String streamName = args[0];
        Region region = Region.US_EAST_1;
        KinesisClient kinesisClient = KinesisClient.builder()
                .region(region)
                .build();

        // Ensure that the Kinesis Stream is valid.
        validateStream(kinesisClient, streamName);
        setStockData(kinesisClient, streamName);
        kinesisClient.close();
    }

    public static void setStockData(KinesisClient kinesisClient, String streamName) {
        try {
            // Repeatedly send stock trades with a 100 milliseconds wait in between.
            StockTradeGenerator stockTradeGenerator = new StockTradeGenerator();

            // Put in 50 Records for this example.
            int index = 50;
            for (int x = 0; x < index; x++) {
                StockTrade trade = stockTradeGenerator.getRandomTrade();
                sendStockTrade(trade, kinesisClient, streamName);
                Thread.sleep(100);
            }

        } catch (KinesisException | InterruptedException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        System.out.println("Done");
    }

    private static void sendStockTrade(StockTrade trade, KinesisClient kinesisClient,
            String streamName) {
        byte[] bytes = trade.toJsonAsBytes();

        // The bytes could be null if there is an issue with the JSON serialization by
        // the Jackson JSON library.
        if (bytes == null) {
            System.out.println("Could not get JSON bytes for stock trade");
            return;
        }

        System.out.println("Putting trade: " + trade);
        PutRecordRequest request = PutRecordRequest.builder()
                .partitionKey(trade.getTickerSymbol()) // We use the ticker symbol as the partition key, explained in
                                                       // the Supplemental Information section below.
                .streamName(streamName)
                .data(SdkBytes.fromByteArray(bytes))
                .build();

        try {
            kinesisClient.putRecord(request);
        } catch (KinesisException e) {
            System.err.println(e.getMessage());
        }
    }

    private static void validateStream(KinesisClient kinesisClient, String streamName) {
        try {
            DescribeStreamRequest describeStreamRequest = DescribeStreamRequest.builder()
                    .streamName(streamName)
                    .build();

            DescribeStreamResponse describeStreamResponse = kinesisClient.describeStream(describeStreamRequest);

            if (!describeStreamResponse.streamDescription().streamStatus().toString().equals("ACTIVE")) {
                System.err.println("Stream " + streamName + " is not active. Please wait a few moments and try again.");
                System.exit(1);
            }

        } catch (KinesisException e) {
            System.err.println("Error found while describing the stream " + streamName);
            System.err.println(e);
            System.exit(1);
        }
    }
}
```

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

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

Sie können andere Drittanbieter-Bibliotheken verwenden, anstatt eine benutzerdefinierten Abonnenten zu implementieren. In diesem Beispiel wird die Verwendung der RxJava Implementierung demonstriert. Sie können jedoch jede Bibliothek verwenden, die die Reactive Streams-Schnittstellen implementiert. Weitere Informationen zu dieser Bibliothek finden Sie [auf der RxJava Wiki-Seite auf Github](https://github.com/ReactiveX/RxJava/wiki).

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

 **POM-Eintrag** 

```
<dependency>
 <groupId>io.reactivex.rxjava2</groupId>
 <artifactId>rxjava</artifactId>
 <version>2.2.21</version>
</dependency>
```

 **Importe** 

```
import java.net.URI;
import java.util.concurrent.CompletableFuture;

import io.reactivex.Flowable;
import software.amazon.awssdk.auth.credentials.ProfileCredentialsProvider;
import software.amazon.awssdk.core.async.SdkPublisher;
import software.amazon.awssdk.http.Protocol;
import software.amazon.awssdk.http.SdkHttpConfigurationOption;
import software.amazon.awssdk.http.nio.netty.NettyNioAsyncHttpClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.kinesis.KinesisAsyncClient;
import software.amazon.awssdk.services.kinesis.model.ShardIteratorType;
import software.amazon.awssdk.services.kinesis.model.StartingPosition;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardEvent;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardRequest;
import software.amazon.awssdk.services.kinesis.model.SubscribeToShardResponseHandler;
import software.amazon.awssdk.utils.AttributeMap;
```

In diesem Beispiel wird die `onEventStream` Lifecycle-Methode verwendet RxJava . Dadurch haben Sie Vollzugriff auf den Herausgeber, der zum Erstellen einer Rx Flowable verwendet werden kann.

 **Code** 

```
        SubscribeToShardResponseHandler responseHandler = SubscribeToShardResponseHandler
            .builder()
            .onError(t -> System.err.println("Error during stream - " + t.getMessage()))
            .onEventStream(p -> Flowable.fromPublisher(p)
                                        .ofType(SubscribeToShardEvent.class)
                                        .flatMapIterable(SubscribeToShardEvent::records)
                                        .limit(1000)
                                        .buffer(25)
                                        .subscribe(e -> System.out.println("Record batch = " + e)))
            .build();
```

Sie können bei dem Herausgeber `Flowable` auch die Methode `publisherTransformer` verwenden. Sie müssen den `Flowable` Herausgeber an eine anpassen *SdkPublisher*, wie im folgenden Beispiel gezeigt.

 **Code** 

```
        SubscribeToShardResponseHandler responseHandler = SubscribeToShardResponseHandler
            .builder()
            .onError(t -> System.err.println("Error during stream - " + t.getMessage()))
            .publisherTransformer(p -> SdkPublisher.adapt(Flowable.fromPublisher(p).limit(100)))
            .build();
```

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

## Weitere Informationen
<a name="more-information"></a>
+  [SubscribeToShardEvent](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SubscribeToShardEvent.html)in der Amazon Kinesis API-Referenz
+  [SubscribeToShard](https://docs.aws.amazon.com/kinesis/latest/APIReference/API_SubscribeToShard.html)in der Amazon Kinesis API-Referenz

# Funktionen aufrufen, auflisten und löschen AWS Lambda
<a name="examples-lambda"></a>

Dieser Abschnitt enthält Beispiele für die Programmierung mit dem Lambda Service-Client unter Verwendung von AWS SDK für Java 2.x.

**Topics**
+ [Aufrufen von einer Lambda-Funktion](#invoke-function)
+ [Auflisten von Lambda-Funktionen](#list-function)
+ [Löschen einer Lambda-Funktion](#delete-function)

## Aufrufen von einer Lambda-Funktion
<a name="invoke-function"></a>

Sie können eine Lambda Funktion aufrufen, indem Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/LambdaClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/LambdaClient.html)Objekt erstellen und dessen Methode aufrufen. `invoke` Erstellen Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/InvokeRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/InvokeRequest.html)Objekt, um zusätzliche Informationen wie den Funktionsnamen und die Nutzlast anzugeben, die an die Funktion übergeben werden sollen. Lambda Funktionsnamen werden als *arn:aws:lambda:us-east* - 1:123456789012:function: angezeigt. HelloFunction Sie können den Wert abrufen, indem Sie sich die Funktion in der ansehen. AWS-Managementkonsole

Um Nutzdaten an eine Funktion zu übergeben, erstellen Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/SdkBytes.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/SdkBytes.html)Objekt, das Informationen enthält. Beachten Sie beispielsweise im folgenden Codebeispiel die an die Lambda -Funktion übergebenen JSON-Daten.

 **Importe** 

```
import software.amazon.awssdk.services.lambda.LambdaClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lambda.model.InvokeRequest;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.lambda.model.InvokeResponse;
import software.amazon.awssdk.services.lambda.model.LambdaException;
```

 **Code** 

Das folgende Codebeispiel zeigt, wie eine Lambda Funktion aufgerufen wird.

```
    public static void invokeFunction(LambdaClient awsLambda, String functionName) {

         InvokeResponse res = null ;
        try {
            //Need a SdkBytes instance for the payload
            String json = "{\"Hello \":\"Paris\"}";
            SdkBytes payload = SdkBytes.fromUtf8String(json) ;

            //Setup an InvokeRequest
            InvokeRequest request = InvokeRequest.builder()
                    .functionName(functionName)
                    .payload(payload)
                    .build();

            res = awsLambda.invoke(request);
            String value = res.payload().asUtf8String() ;
            System.out.println(value);

        } catch(LambdaException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

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

## Auflisten von Lambda-Funktionen
<a name="list-function"></a>

Erstellen Sie ein `[Lambda Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/LambdaClient.html)` Objekt und rufen Sie seine `listFunctions` Methode auf. Diese Methode gibt ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/ListFunctionsResponse.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/ListFunctionsResponse.html)Objekt zurück. Sie können die `functions` Methode dieses Objekts aufrufen, um eine Liste von [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/FunctionConfiguration.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/FunctionConfiguration.html)Objekten zurückzugeben. Sie können die Liste durchlaufen, um Informationen über die Funktionen abzurufen. Das folgende Java-Codebeispiel zeigt beispielsweise, wie die einzelnen Funktionsnamen abgerufen werden.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lambda.LambdaClient;
import software.amazon.awssdk.services.lambda.model.LambdaException;
import software.amazon.awssdk.services.lambda.model.ListFunctionsResponse;
import software.amazon.awssdk.services.lambda.model.FunctionConfiguration;
import java.util.List;
```

 **Code** 

Das folgende Java-Codebeispiel veranschaulicht, wie eine Liste von Funktionsnamen abgerufen wird.

```
    public static void listFunctions(LambdaClient awsLambda) {

        try {
            ListFunctionsResponse functionResult = awsLambda.listFunctions();
            List<FunctionConfiguration> list = functionResult.functions();

            for (FunctionConfiguration config: list) {
                System.out.println("The function name is "+config.functionName());
            }

        } catch(LambdaException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

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

## Löschen einer Lambda-Funktion
<a name="delete-function"></a>

Erstellen Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/LambdaClient.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/LambdaClient.html)Objekt und rufen Sie seine `deleteFunction` Methode auf. Erstellen Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/DeleteFunctionRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/lambda/model/DeleteFunctionRequest.html)Objekt und übergeben Sie es an die `deleteFunction` Methode. Dieses Objekt enthält Informationen wie den Namen der zu löschenden Funktion. Funktionsnamen werden als *arn:aws:lambda:us-east* - 1:123456789012:function: angezeigt. HelloFunction Sie können den Wert abrufen, indem Sie sich die Funktion in der ansehen. AWS-Managementkonsole

 **Importe** 

```
import software.amazon.awssdk.services.lambda.LambdaClient;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.lambda.model.DeleteFunctionRequest;
import software.amazon.awssdk.services.lambda.model.LambdaException;
```

 **Code** 

Der folgende Java-Code zeigt, wie eine Lambda Funktion gelöscht wird.

```
    public static void deleteLambdaFunction(LambdaClient awsLambda, String functionName ) {
        try {
            DeleteFunctionRequest request = DeleteFunctionRequest.builder()
                    .functionName(functionName)
                    .build();

            awsLambda.deleteFunction(request);
            System.out.println("The "+functionName +" function was deleted");

        } catch(LambdaException e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
    }
```

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

# Arbeiten Sie mit Amazon S3
<a name="examples-s3"></a>

Dieser Abschnitt enthält Hintergrundinformationen für die Arbeit mit Amazon S3 mithilfe von AWS SDK for Java 2.x. Dieser Abschnitt ergänzt die [Amazon S3 Java v2-Beispiele](java_s3_code_examples.md), die im Abschnitt *Codebeispiele* dieses Handbuchs vorgestellt werden.

## S3-Clients in der AWS SDK for Java 2.x
<a name="s3-clients"></a>

Das AWS SDK for Java 2.x bietet verschiedene Arten von S3-Clients. Die folgende Tabelle zeigt die Unterschiede und kann Ihnen bei der Entscheidung helfen, was für Ihre Anwendungsfälle am besten geeignet ist.


**Verschiedene Varianten von Amazon S3 S3-Clients**  

| S3-Klient | Kurzbeschreibung | Wann sollte dies verwendet werden? | Einschränkung/Nachteil | 
| --- | --- | --- | --- | 
|  **AWS CRT-basierter S3-Client** [Schnittstelle: S3 AsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) Baumeister: [S3 CrtAsyncClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html) Siehe [Verwenden Sie einen leistungsstarken S3-Client: AWS CRT-basierter S3-Client](crt-based-s3-client.md).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  | 
|  ***Java-basierter asynchroner S3-Client mit aktiviertem Multipart*** Schnittstelle[:](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) S3 AsyncClient Baumeister: [S3 AsyncClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html) Siehe [Konfigurieren Sie den Java-basierten asynchronen S3-Client für parallel Übertragungen](s3-async-client-multipart.md).  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  | Weniger leistungsfähig als der AWS CRT-basierte S3-Client. | 
|  ***Java-basierter asynchroner S3-Client ohne aktiviertes Multipart*** Schnittstelle[:](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) S3 AsyncClient Baumeister: [S3 AsyncClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  |  Keine Leistungsoptimierung.  | 
|  **Java-basierter S3-Synchronisierungsclient** [Schnittstelle: S3Client](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) [Baumeister: S3 ClientBuilder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3ClientBuilder.html) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/examples-s3.html)  |  Keine Leistungsoptimierung.  | 

**Anmerkung**  
Ab Version 2.18.x AWS SDK for Java 2.x verwendet der eine [Adressierung im virtuellen Hosting-Stil, wenn eine Endpunkt-Override enthalten](https://docs.aws.amazon.com/AmazonS3/latest/userguide/VirtualHosting.html#virtual-hosted-style-access) ist. Dies gilt, solange der Bucket-Name ein gültiges DNS-Label ist.   
Rufen Sie die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3BaseClientBuilder.html#forcePathStyle(java.lang.Boolean](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3BaseClientBuilder.html#forcePathStyle(java.lang.Boolean)Methode with `true` in Ihrem Client Builder auf, um den Client zu zwingen, die Pfadadressierung für Buckets zu verwenden.  
Das folgende Beispiel zeigt einen Service-Client, der mit einer Endpunktüberschreibung konfiguriert ist und eine Pfadadressierung verwendet.  

```
S3Client client = S3Client.builder()
                          .region(Region.US_WEST_2)
                          .endpointOverride(URI.create("https://s3.us-west-2.amazonaws.com"))
                          .forcePathStyle(true)
                          .build();
```

**Topics**
+ [S3-Clients im SDK](#s3-clients)
+ [Hochladen von Streams auf S3](best-practices-s3-uploads.md)
+ [Vorsigniert URLs](examples-s3-presign.md)
+ [Regionsübergreifender Zugriff](s3-cross-region.md)
+ [Schutz der Datenintegrität mit Prüfsummen](s3-checksums.md)
+ [Verwenden Sie einen performanten S3-Client](crt-based-s3-client.md)
+ [Unterstützung für parallel Übertragung konfigurieren](s3-async-client-multipart.md)
+ [Dateien und Verzeichnisse übertragen](transfer-manager.md)
+ [S3-Ereignisbenachrichtigungen](examples-s3-event-notifications.md)

# Hochladen von Streams auf Amazon S3 mit dem AWS SDK for Java 2.x
<a name="best-practices-s3-uploads"></a>

Wenn Sie einen Stream verwenden, um Inhalte mithilfe von [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest,software.amazon.awssdk.core.sync.RequestBody)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#putObject(software.amazon.awssdk.services.s3.model.PutObjectRequest,software.amazon.awssdk.core.sync.RequestBody))oder auf S3 hochzuladen [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#uploadPart(software.amazon.awssdk.services.s3.model.UploadPartRequest,software.amazon.awssdk.core.sync.RequestBody)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#uploadPart(software.amazon.awssdk.services.s3.model.UploadPartRequest,software.amazon.awssdk.core.sync.RequestBody)), verwenden Sie eine `RequestBody` Factory-Klasse für die synchrone API, um den Stream bereitzustellen. Für die asynchrone API `AsyncRequestBody` ist das die entsprechende Factory-Klasse.

## Welche Methoden laden Streams hoch?
<a name="s3-stream-upload-methods"></a>

Für die synchrone API können Sie die folgenden Factory-Methoden verwenden`RequestBody`, um den Stream bereitzustellen:
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/sync/RequestBody.html#fromInputStream(java.io.InputStream,long))(InputStream inputStream, long contentLength)`

  `[fromContentProvider](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/sync/RequestBody.html#fromContentProvider(software.amazon.awssdk.http.ContentStreamProvider,long,java.lang.String))(ContentStreamProvider provider, long contentLength, String mimeType)`
  + Das `ContentStreamProvider` hat die `fromInputStream(InputStream inputStream)` Factory-Methode
+ `[fromContentProvider](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/sync/RequestBody.html#fromContentProvider(software.amazon.awssdk.http.ContentStreamProvider,java.lang.String))(ContentStreamProvider provider, String mimeType)`

Für die asynchrone API können Sie die folgenden Factory-Methoden verwenden: `AsyncRequestBody`
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#fromInputStream(java.io.InputStream,java.lang.Long,java.util.concurrent.ExecutorService))(InputStream inputStream, Long contentLength, ExecutorService executor)` 
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#fromInputStream(software.amazon.awssdk.core.async.AsyncRequestBodyFromInputStreamConfiguration))(AsyncRequestBodyFromInputStreamConfiguration configuration)`
  + Sie verwenden den AsyncRequestBodyFromInputStreamConfiguration .Builder, um den Stream bereitzustellen
+ `[fromInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#fromInputStream(java.util.function.Consumer))(Consumer<AsyncRequestBodyFromInputStreamConfiguration.Builder> configuration)`
+ `[forBlockingInputStream](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/AsyncRequestBody.html#forBlockingInputStream(java.lang.Long))(Long contentLength)`
  + Das Ergebnis `[BlockingInputStreamAsyncRequestBody](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/core/async/BlockingInputStreamAsyncRequestBody.html)` enthält die Methode`writeInputStream(InputStream inputStream)`, mit der Sie den Stream bereitstellen können

## Der Upload wird durchgeführt
<a name="s3-upload-stream-perform"></a>

### Wenn du die Länge des Streams kennst
<a name="s3-stream-upload-supply-content-length"></a>

Wie Sie der Signatur der zuvor gezeigten Methoden entnehmen können, akzeptieren die meisten Methoden einen Parameter für die Inhaltslänge. 

Wenn Sie die Inhaltslänge in Byte kennen, geben Sie den genauen Wert an:

```
// Always provide the exact content length when it's available.
long contentLength = 1024; // Exact size in bytes.
s3Client.putObject(req -> req
    .bucket("amzn-s3-demo-bucket")
    .key("my-key"),
RequestBody.fromInputStream(inputStream, contentLength));
```

**Warnung**  
 Wenn Sie aus einem Eingabestream hochladen und die angegebene Inhaltslänge nicht der tatsächlichen Byteanzahl entspricht, kann Folgendes auftreten:  
Verkürzte Objekte, wenn die angegebene Länge zu klein ist
Fehlgeschlagene Uploads oder hängende Verbindungen, wenn die angegebene Länge zu groß ist

### Wenn Sie die Länge des Streams nicht kennen
<a name="s3-stream-upload-unknown-length"></a>

#### Verwenden der synchronen API
<a name="s3-upload-unknown-sync-client"></a>

Verwenden Sie das`fromContentProvider(ContentStreamProvider provider, String mimeType)`:

```
public PutObjectResponse syncClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3Client s3Client = S3Client.create();

    RequestBody body = RequestBody.fromContentProvider(ContentStreamProvider.fromInputStream(inputStream), "text/plain");
    PutObjectResponse putObjectResponse = s3Client.putObject(b -> b.bucket(BUCKET_NAME).key(KEY_NAME), body);
    return putObjectResponse;
}
```

Da das SDK den gesamten Stream im Speicher puffert, um die Inhaltslänge zu berechnen, kann es bei großen Streams zu Speicherproblemen kommen. Wenn Sie große Streams mit dem synchronen Client hochladen müssen, sollten Sie die Verwendung der mehrteiligen API in Betracht ziehen:

##### Laden Sie einen Stream mithilfe der synchronen Client-API und der Multipart-API hoch
<a name="sync-multipart-upload-stream"></a>

```
public static void uploadStreamToS3(String bucketName, String key, InputStream inputStream) {
    // Create S3 client
    S3Client s3Client = S3Client.create();
    try {
        // Step 1: Initiate the multipart upload
        CreateMultipartUploadRequest createMultipartUploadRequest = CreateMultipartUploadRequest.builder()
                .bucket(bucketName)
                .key(key)
                .build();

        CreateMultipartUploadResponse createResponse = s3Client.createMultipartUpload(createMultipartUploadRequest);
        String uploadId = createResponse.uploadId();
        System.out.println("Started multipart upload with ID: " + uploadId);

        // Step 2: Upload parts
        List<CompletedPart> completedParts = new ArrayList<>();
        int partNumber = 1;
        byte[] buffer = new byte[PART_SIZE];
        int bytesRead;

        try {
            while ((bytesRead = readFullyOrToEnd(inputStream, buffer)) > 0) {
                // Create request to upload a part
                UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                        .bucket(bucketName)
                        .key(key)
                        .uploadId(uploadId)
                        .partNumber(partNumber)
                        .build();

                // If we didn't read a full buffer, create a properly sized byte array
                RequestBody requestBody;
                if (bytesRead < PART_SIZE) {
                    byte[] lastPartBuffer = new byte[bytesRead];
                    System.arraycopy(buffer, 0, lastPartBuffer, 0, bytesRead);
                    requestBody = RequestBody.fromBytes(lastPartBuffer);
                } else {
                    requestBody = RequestBody.fromBytes(buffer);
                }

                // Upload the part and save the response's ETag
                UploadPartResponse uploadPartResponse = s3Client.uploadPart(uploadPartRequest, requestBody);
                CompletedPart part = CompletedPart.builder()
                        .partNumber(partNumber)
                        .eTag(uploadPartResponse.eTag())
                        .build();
                completedParts.add(part);

                System.out.println("Uploaded part " + partNumber + " with size " + bytesRead + " bytes");
                partNumber++;
            }

            // Step 3: Complete the multipart upload
            CompletedMultipartUpload completedMultipartUpload = CompletedMultipartUpload.builder()
                    .parts(completedParts)
                    .build();

            CompleteMultipartUploadRequest completeRequest = CompleteMultipartUploadRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .multipartUpload(completedMultipartUpload)
                    .build();

            CompleteMultipartUploadResponse completeResponse = s3Client.completeMultipartUpload(completeRequest);
            System.out.println("Multipart upload completed. Object URL: " + completeResponse.location());

        } catch (Exception e) {
            // If an error occurs, abort the multipart upload
            System.err.println("Error during multipart upload: " + e.getMessage());
            AbortMultipartUploadRequest abortRequest = AbortMultipartUploadRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .build();
            s3Client.abortMultipartUpload(abortRequest);
            System.err.println("Multipart upload aborted");
        } finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                System.err.println("Error closing input stream: " + e.getMessage());
            }
        }
    } finally {
        s3Client.close();
    }
}

/**
 * Reads from the input stream into the buffer, attempting to fill the buffer completely
 * or until the end of the stream is reached.
 *
 * @param inputStream the input stream to read from
 * @param buffer      the buffer to fill
 * @return the number of bytes read, or -1 if the end of the stream is reached before any bytes are read
 * @throws IOException if an I/O error occurs
 */
private static int readFullyOrToEnd(InputStream inputStream, byte[] buffer) throws IOException {
    int totalBytesRead = 0;
    int bytesRead;

    while (totalBytesRead < buffer.length) {
        bytesRead = inputStream.read(buffer, totalBytesRead, buffer.length - totalBytesRead);
        if (bytesRead == -1) {
            break; // End of stream
        }
        totalBytesRead += bytesRead;
    }

    return totalBytesRead > 0 ? totalBytesRead : -1;
}
```

**Anmerkung**  
Für die meisten Anwendungsfälle empfehlen wir die Verwendung der asynchronen Client-API für Streams unbekannter Größe. Dieser Ansatz ermöglicht parallel Übertragungen und bietet eine einfachere Programmierschnittstelle, da das SDK die Stream-Segmentierung in mehrteilige Blöcke übernimmt, wenn der Stream groß ist.   
Sowohl der standardmäßige asynchrone S3-Client mit aktiviertem Multipart als auch der AWS CRT-basierte S3-Client implementieren diesen Ansatz. Im folgenden Abschnitt zeigen wir Beispiele für diesen Ansatz.

#### Verwendung der asynchronen API
<a name="s3-stream-upload-unknown-async-client"></a>

Sie können das `contentLength` Argument `null` für das angeben `fromInputStream(InputStream inputStream, Long contentLength, ExecutorService executor)`

**Example mit dem AWS CRT-basierten asynchronen Client:**  

```
public PutObjectResponse crtClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor);  // 'null' indicates that the
                                                                                            // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null){
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

**Example unter Verwendung des standardmäßigen asynchronen Clients mit aktiviertem Multipart:**  

```
public PutObjectResponse asyncClient_multipart_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.builder().multipartEnabled(true).build();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); // 'null' indicates that the
                                                                                           // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null) {
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

# Arbeiten Sie mit Amazon S3 vorsignierten URLs
<a name="examples-s3-presign"></a>

Vorsignierte URLs ermöglichen temporären Zugriff auf private S3-Objekte, ohne dass Benutzer über AWS Anmeldeinformationen oder Berechtigungen verfügen müssen. 

Angenommen, Alice hat Zugriff auf ein S3-Objekt, und sie möchte den Zugriff auf dieses Objekt vorübergehend mit Bob teilen. Alice kann eine vorsignierte GET-Anfrage zur Weitergabe an Bob generieren, sodass er das Objekt herunterladen kann, ohne Zugriff auf Alices Anmeldeinformationen zu benötigen. Sie können vorsignierte URLs HTTP-GET- und HTTP-PUT-Anfragen generieren.

## Generieren Sie eine vorsignierte URL für ein Objekt und laden Sie sie dann herunter (GET-Anfrage)
<a name="get-presignedobject"></a>

Das folgende Beispiel besteht aus zwei Teilen.
+ Teil 1: Alice generiert die vorsignierte URL für ein Objekt.
+ Teil 2: Bob lädt das Objekt mithilfe der vorsignierten URL herunter.

### Teil 1: Generieren Sie die URL
<a name="get-presigned-object-part1"></a>

Alice hat bereits ein Objekt in einem S3-Bucket. Sie verwendet den folgenden Code, um eine URL-Zeichenfolge zu generieren, die Bob in einer nachfolgenden GET-Anfrage verwenden kann.

#### Importe
<a name="get-presigned-example-imports"></a>

```
import com.example.s3.util.PresignUrlUtils;
import org.slf4j.Logger;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.HttpExecuteResponse;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.utils.IoUtils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.UUID;
```

```
    /* Create a pre-signed URL to download an object in a subsequent GET request. */
    public String createPresignedGetUrl(String bucketName, String keyName) {
        try (S3Presigner presigner = S3Presigner.create()) {

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

            GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
                    .signatureDuration(Duration.ofMinutes(10))  // The URL will expire in 10 minutes.
                    .getObjectRequest(objectRequest)
                    .build();

            PresignedGetObjectRequest presignedRequest = presigner.presignGetObject(presignRequest);
            logger.info("Presigned URL: [{}]", presignedRequest.url().toString());
            logger.info("HTTP method: [{}]", presignedRequest.httpRequest().method());

            return presignedRequest.url().toExternalForm();
        }
    }
```

### Teil 2: Laden Sie das Objekt herunter
<a name="get-presigned-object-part2"></a>

Bob verwendet eine der folgenden drei Codeoptionen, um das Objekt herunterzuladen. Alternativ könnte er einen Browser verwenden, um die GET-Anfrage auszuführen.

#### Benutze JDK `HttpURLConnection` (seit v1.1)
<a name="get-presigned-example-useHttpUrlConnection"></a>

```
    /* Use the JDK HttpURLConnection (since v1.1) class to do the download. */
    public byte[] useHttpUrlConnectionToGet(String presignedUrlString) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array.

        try {
            URL presignedUrl = new URL(presignedUrlString);
            HttpURLConnection connection = (HttpURLConnection) presignedUrl.openConnection();
            connection.setRequestMethod("GET");
            // Download the result of executing the request.
            try (InputStream content = connection.getInputStream()) {
                IoUtils.copy(content, byteArrayOutputStream);
            }
            logger.info("HTTP response code is " + connection.getResponseCode());

        } catch (S3Exception | IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArrayOutputStream.toByteArray();
    }
```

#### Benutze JDK `HttpClient` (seit v11)
<a name="get-presigned-example-useHttpClient"></a>

```
    /* Use the JDK HttpClient (since v11) class to do the download. */
    public byte[] useHttpClientToGet(String presignedUrlString) {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array.

        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder();
        HttpClient httpClient = HttpClient.newHttpClient();
        try {
            URL presignedUrl = new URL(presignedUrlString);
            HttpResponse<InputStream> response = httpClient.send(requestBuilder
                            .uri(presignedUrl.toURI())
                            .GET()
                            .build(),
                    HttpResponse.BodyHandlers.ofInputStream());

            IoUtils.copy(response.body(), byteArrayOutputStream);

            logger.info("HTTP response code is " + response.statusCode());

        } catch (URISyntaxException | InterruptedException | IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArrayOutputStream.toByteArray();
    }
```

#### Verwendung `SdkHttpClient` aus dem SDK for Java
<a name="get-presigned-example-useSdkHttpClient"></a>

```
    /* Use the AWS SDK for Java SdkHttpClient class to do the download. */
    public byte[] useSdkHttpClientToGet(String presignedUrlString) {

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); // Capture the response body to a byte array.
        try {
            URL presignedUrl = new URL(presignedUrlString);
            SdkHttpRequest request = SdkHttpRequest.builder()
                    .method(SdkHttpMethod.GET)
                    .uri(presignedUrl.toURI())
                    .build();

            HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
                    .request(request)
                    .build();

            try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
                HttpExecuteResponse response = sdkHttpClient.prepareRequest(executeRequest).call();
                response.responseBody().ifPresentOrElse(
                        abortableInputStream -> {
                            try {
                                IoUtils.copy(abortableInputStream, byteArrayOutputStream);
                            } catch (IOException e) {
                                throw new RuntimeException(e);
                            }
                        },
                        () -> logger.error("No response body."));

                logger.info("HTTP Response code is {}", response.httpResponse().statusCode());
            }
        } catch (URISyntaxException | IOException e) {
            logger.error(e.getMessage(), e);
        }
        return byteArrayOutputStream.toByteArray();
    }
```

Sehen Sie sich das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedGetUrlAndRetrieve.java) an und [testen Sie](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/test/java/com/example/s3/presignurl/GeneratePresignedGetUrlTests.java) es weiter GitHub.

## Generieren Sie eine vorsignierte URL für einen Upload und laden Sie dann eine Datei hoch (PUT-Anfrage)
<a name="put-presignedobject"></a>

Das folgende Beispiel besteht aus zwei Teilen.
+ Teil 1: Alice generiert die vorsignierte URL, um ein Objekt hochzuladen.
+ Teil 2: Bob lädt eine Datei mithilfe der vorsignierten URL hoch.

### Teil 1: Generieren Sie die URL
<a name="put-presigned-object-part1"></a>

Alice hat bereits einen S3-Bucket. Sie verwendet den folgenden Code, um eine URL-Zeichenfolge zu generieren, die Bob in einer nachfolgenden PUT-Anfrage verwenden kann.

#### Importe
<a name="put-presigned-example-imports"></a>

```
import com.example.s3.util.PresignUrlUtils;
import org.slf4j.Logger;
import software.amazon.awssdk.core.internal.sync.FileContentStreamProvider;
import software.amazon.awssdk.http.HttpExecuteRequest;
import software.amazon.awssdk.http.HttpExecuteResponse;
import software.amazon.awssdk.http.SdkHttpClient;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.http.SdkHttpRequest;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.Map;
import java.util.UUID;
```

```
    /* Create a presigned URL to use in a subsequent PUT request */
    public String createPresignedUrl(String bucketName, String keyName, Map<String, String> metadata) {
        try (S3Presigner presigner = S3Presigner.create()) {

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

            PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
                    .signatureDuration(Duration.ofMinutes(10))  // The URL expires in 10 minutes.
                    .putObjectRequest(objectRequest)
                    .build();


            PresignedPutObjectRequest presignedRequest = presigner.presignPutObject(presignRequest);
            String myURL = presignedRequest.url().toString();
            logger.info("Presigned URL to upload a file to: [{}]", myURL);
            logger.info("HTTP method: [{}]", presignedRequest.httpRequest().method());

            return presignedRequest.url().toExternalForm();
        }
    }
```

### Teil 2: Laden Sie ein Dateiobjekt hoch
<a name="put-presigned-object-part2"></a>

Bob verwendet eine der folgenden drei Codeoptionen, um eine Datei hochzuladen.

#### Benutze JDK `HttpURLConnection` (seit v1.1)
<a name="put-presigned-example-useHttpUrlConnection"></a>

```
    /* Use the JDK HttpURLConnection (since v1.1) class to do the upload. */
    public void useHttpUrlConnectionToPut(String presignedUrlString, File fileToPut, Map<String, String> metadata) {
        logger.info("Begin [{}] upload", fileToPut.toString());
        try {
            URL presignedUrl = new URL(presignedUrlString);
            HttpURLConnection connection = (HttpURLConnection) presignedUrl.openConnection();
            connection.setDoOutput(true);
            metadata.forEach((k, v) -> connection.setRequestProperty("x-amz-meta-" + k, v));
            connection.setRequestMethod("PUT");
            OutputStream out = connection.getOutputStream();

            try (RandomAccessFile file = new RandomAccessFile(fileToPut, "r");
                 FileChannel inChannel = file.getChannel()) {
                ByteBuffer buffer = ByteBuffer.allocate(8192); //Buffer size is 8k

                while (inChannel.read(buffer) > 0) {
                    buffer.flip();
                    for (int i = 0; i < buffer.limit(); i++) {
                        out.write(buffer.get());
                    }
                    buffer.clear();
                }
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }

            out.close();
            connection.getResponseCode();
            logger.info("HTTP response code is " + connection.getResponseCode());

        } catch (S3Exception | IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
```

#### Benutze JDK `HttpClient` (seit v11)
<a name="put-presigned-example-useHttpClient"></a>

```
    /* Use the JDK HttpClient (since v11) class to do the upload. */
    public void useHttpClientToPut(String presignedUrlString, File fileToPut, Map<String, String> metadata) {
        logger.info("Begin [{}] upload", fileToPut.toString());

        HttpRequest.Builder requestBuilder = HttpRequest.newBuilder();
        metadata.forEach((k, v) -> requestBuilder.header("x-amz-meta-" + k, v));

        HttpClient httpClient = HttpClient.newHttpClient();
        try {
            final HttpResponse<Void> response = httpClient.send(requestBuilder
                            .uri(new URL(presignedUrlString).toURI())
                            .PUT(HttpRequest.BodyPublishers.ofFile(Path.of(fileToPut.toURI())))
                            .build(),
                    HttpResponse.BodyHandlers.discarding());

            logger.info("HTTP response code is " + response.statusCode());

        } catch (URISyntaxException | InterruptedException | IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
```

#### Verwendung `SdkHttpClient` aus dem SDK for Java
<a name="put-presigned-example-useSdkHttpClient"></a>

```
    /* Use the AWS SDK for Java V2 SdkHttpClient class to do the upload. */
    public void useSdkHttpClientToPut(String presignedUrlString, File fileToPut, Map<String, String> metadata) {
        logger.info("Begin [{}] upload", fileToPut.toString());

        try {
            URL presignedUrl = new URL(presignedUrlString);

            SdkHttpRequest.Builder requestBuilder = SdkHttpRequest.builder()
                    .method(SdkHttpMethod.PUT)
                    .uri(presignedUrl.toURI());
            // Add headers
            metadata.forEach((k, v) -> requestBuilder.putHeader("x-amz-meta-" + k, v));
            // Finish building the request.
            SdkHttpRequest request = requestBuilder.build();

            HttpExecuteRequest executeRequest = HttpExecuteRequest.builder()
                    .request(request)
                    .contentStreamProvider(new FileContentStreamProvider(fileToPut.toPath()))
                    .build();

            try (SdkHttpClient sdkHttpClient = ApacheHttpClient.create()) {
                HttpExecuteResponse response = sdkHttpClient.prepareRequest(executeRequest).call();
                logger.info("Response code: {}", response.httpResponse().statusCode());
            }
        } catch (URISyntaxException | IOException e) {
            logger.error(e.getMessage(), e);
        }
    }
```

Sehen Sie sich das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/GeneratePresignedUrlAndPutFileWithMetadata.java) an und [testen Sie](https://github.com/awsdocs/aws-doc-sdk-examples/blob/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/test/java/com/example/s3/presignurl/GeneratePresignedPutUrlTests.java) es weiter GitHub.

# Regionsübergreifender Zugriff für Amazon S3
<a name="s3-cross-region"></a>

Wenn Sie mit Amazon Simple Storage Service (Amazon S3) -Buckets arbeiten, kennen Sie normalerweise das AWS-Region für den Bucket. Die Region, mit der Sie arbeiten, wird bei der Erstellung des S3-Clients festgelegt. 

Manchmal müssen Sie jedoch möglicherweise mit einem bestimmten Bucket arbeiten, wissen aber nicht, ob sich dieser in derselben Region befindet, die für den S3-Client festgelegt ist. 

Anstatt mehr Aufrufe zu tätigen, um die Bucket-Region zu ermitteln, können Sie das SDK verwenden, um den Zugriff auf S3-Buckets in verschiedenen Regionen zu ermöglichen.

## Aufstellen
<a name="s3-cross-region-setup"></a>

Die Support für den regionsübergreifenden Zugriff wurde mit `2.20.111` der Version des SDK verfügbar. Verwenden Sie diese oder eine neuere Version in Ihrer Maven-Build-Datei für die `s3` Abhängigkeit, wie im folgenden Codeausschnitt gezeigt.

```
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.27.21</version>
</dependency>
```

Wenn Sie als Nächstes Ihren S3-Client erstellen, aktivieren Sie den regionsübergreifenden Zugriff, wie im Snippet gezeigt. Standardmäßig ist der Zugriff nicht aktiviert.

```
S3AsyncClient client = S3AsyncClient.builder()
                                    .crossRegionAccessEnabled(true)
                                    .build();
```

## Wie das SDK regionsübergreifenden Zugriff bietet
<a name="s3-cross-region-routing"></a>

Wenn Sie in einer Anfrage auf einen vorhandenen Bucket verweisen, z. B. wenn Sie die `putObject` Methode verwenden, initiiert das SDK eine Anfrage an die für den Client konfigurierte Region. 

Wenn der Bucket in dieser bestimmten Region nicht existiert, umfasst die Fehlerantwort die tatsächliche Region, in der sich der Bucket befindet. Das SDK verwendet dann in einer zweiten Anfrage die richtige Region.

Um future Anfragen an denselben Bucket zu optimieren, speichert das SDK diese Regionszuweisung im Client zwischen.

## Überlegungen
<a name="s3-cross-region-considerations"></a>

Wenn Sie den regionsübergreifenden Bucket-Zugriff aktivieren, beachten Sie, dass der erste API-Aufruf zu einer erhöhten Latenz führen kann, wenn sich der Bucket nicht in der konfigurierten Region des Clients befindet. Nachfolgende Aufrufe profitieren jedoch von zwischengespeicherten Regionsinformationen, was zu einer verbesserten Leistung führt.

Wenn Sie den regionsübergreifenden Zugriff aktivieren, wird der Zugriff auf den Bucket nicht beeinträchtigt. Der Benutzer muss berechtigt sein, auf den Bucket in der Region zuzugreifen, in der er sich befindet.

# Schutz der Datenintegrität mit Prüfsummen
<a name="s3-checksums"></a>

Amazon Simple Storage Service (Amazon S3) bietet die Möglichkeit, beim Hochladen eines Objekts eine Prüfsumme anzugeben. Wenn Sie eine Prüfsumme angeben, wird diese zusammen mit dem Objekt gespeichert und kann beim Herunterladen des Objekts überprüft werden.

Prüfsummen bieten eine zusätzliche Ebene der Datenintegrität bei der Übertragung von Dateien. Mit Prüfsummen können Sie die Datenkonsistenz überprüfen, indem Sie sicherstellen, dass die empfangene Datei mit der Originaldatei übereinstimmt. Weitere Informationen zu Prüfsummen mit Amazon S3 finden Sie im [Amazon Simple Storage Service-Benutzerhandbuch](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html), einschließlich der [unterstützten Algorithmen](https://docs.aws.amazon.com/AmazonS3/latest/userguide/checking-object-integrity.html#using-additional-checksums).

Sie haben die Flexibilität, den Algorithmus auszuwählen, der Ihren Anforderungen am besten entspricht, und das SDK die Prüfsumme berechnen zu lassen. Alternativ können Sie mithilfe eines der unterstützten Algorithmen einen vorab berechneten Prüfsummenwert angeben. 

**Anmerkung**  
Ab Version 2.30.0 von bietet das SDK standardmäßige Integritätsschutzmaßnahmen AWS SDK for Java 2.x, indem es automatisch eine Prüfsumme für Uploads berechnet. `CRC32` Das SDK berechnet diese Prüfsumme, wenn Sie keinen vorab berechneten Prüfsummenwert angeben oder wenn Sie keinen Algorithmus angeben, den das SDK zur Berechnung einer Prüfsumme verwenden soll.   
[Das SDK bietet auch globale Einstellungen für den Schutz der Datenintegrität, die Sie extern festlegen können. Weitere Informationen finden Sie im Referenzhandbuch und im Tools-Referenzhandbuch.AWS SDKs ](https://docs.aws.amazon.com/sdkref/latest/guide/feature-dataintegrity.html)

Wir behandeln Prüfsummen in zwei Anforderungsphasen: beim Hochladen eines Objekts und beim Herunterladen eines Objekts. 

## Hochladen eines Objekts
<a name="use-service-S3-checksum-upload"></a>

 Wenn Sie ein Objekt mit der `putObject` Methode hochladen und einen Prüfsummenalgorithmus bereitstellen, berechnet das SDK die Prüfsumme für den angegebenen Algorithmus. 

Der folgende Codeausschnitt zeigt eine Anfrage zum Hochladen eines Objekts mit einer Prüfsumme. `SHA256` Wenn das SDK die Anfrage sendet, berechnet es die `SHA256` Prüfsumme und lädt das Objekt hoch. Amazon S3 validiert die Integrität des Inhalts, indem es die Prüfsumme berechnet und mit der vom SDK bereitgestellten Prüfsumme vergleicht. Amazon S3 speichert dann die Prüfsumme mit dem Objekt.

```
public void putObjectWithChecksum() {
        s3Client.putObject(b -> b
                .bucket(bucketName)
                .key(key)
                .checksumAlgorithm(ChecksumAlgorithm.SHA256),
            RequestBody.fromString("This is a test"));
}
```

Wenn Sie mit der Anfrage keinen Prüfsummenalgorithmus angeben, variiert das Prüfsummenverhalten je nach der Version des verwendeten SDK, wie in der folgenden Tabelle dargestellt.

**Prüfsummenverhalten, wenn kein Prüfsummenalgorithmus bereitgestellt wird**


| Java-SDK-Version | Verhalten der Prüfsumme | 
| --- | --- | 
| früher als 2.30.0 | Das SDK berechnet nicht automatisch eine CRC-basierte Prüfsumme und gibt sie in der Anfrage an. | 
| 2.30.0 oder später | Das SDK verwendet den `CRC32` Algorithmus zur Berechnung der Prüfsumme und stellt sie in der Anfrage bereit. Amazon S3 validiert die Integrität der Übertragung, indem es seine eigene `CRC32` Prüfsumme berechnet und sie mit der vom SDK bereitgestellten Prüfsumme vergleicht. Wenn die Prüfsummen übereinstimmen, wird die Prüfsumme zusammen mit dem Objekt gespeichert. | 

### Verwenden Sie einen vorberechneten Prüfsummenwert
<a name="use-service-S3-checksum-upload-pre"></a>

Ein mit der Anfrage bereitgestellter vorberechneter Prüfsummenwert deaktiviert die automatische Berechnung durch das SDK und verwendet stattdessen den angegebenen Wert.

Das folgende Beispiel zeigt eine Anfrage mit einer vorberechneten Prüfsumme. SHA256

```
    public void putObjectWithPrecalculatedChecksum(String filePath) {
        String checksum = calculateChecksum(filePath, "SHA-256");

        s3Client.putObject((b -> b
                .bucket(bucketName)
                .key(key)
                .checksumSHA256(checksum)),
            RequestBody.fromFile(Paths.get(filePath)));
    }
```

Wenn Amazon S3 feststellt, dass der Prüfsummenwert für den angegebenen Algorithmus falsch ist, gibt der Service eine Fehlerantwort zurück.

### Mehrteilige Uploads
<a name="use-service-S3-checksum-upload-multi"></a>

Sie können Prüfsummen auch bei mehrteiligen Uploads verwenden.

 Das SDK for Java 2.x bietet zwei Optionen zur Verwendung von Prüfsummen bei mehrteiligen Uploads. Die erste Option verwendet die. `S3TransferManager` 

Das folgende Transfer-Manager-Beispiel spezifiziert den SHA1 Algorithmus für den Upload.

```
    public void multipartUploadWithChecksumTm(String filePath) {
        S3TransferManager transferManager = S3TransferManager.create();
        UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
            .putObjectRequest(b -> b
                .bucket(bucketName)
                .key(key)
                .checksumAlgorithm(ChecksumAlgorithm.SHA1))
            .source(Paths.get(filePath))
            .build();
        FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);
        fileUpload.completionFuture().join();
        transferManager.close();
    }
```

Wenn Sie bei der Verwendung des Transfer-Managers für Uploads keinen Prüfsummenalgorithmus angeben, berechnet das SDK automatisch eine Prüfsumme auf der Grundlage des Algorithmus. `CRC32` Das SDK führt diese Berechnung für alle Versionen des SDK durch.

Die zweite Option verwendet die [`S3Client`API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html) (oder die [`S3AsyncClient`API](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html)), um den mehrteiligen Upload durchzuführen. Wenn Sie bei diesem Ansatz eine Prüfsumme angeben, müssen Sie den Algorithmus angeben, der bei der Initiierung des Uploads verwendet werden soll. Sie müssen auch den Algorithmus für jede Teilanforderung angeben und die für jedes Teil nach dem Hochladen berechnete Prüfsumme bereitstellen.

```
    public void multipartUploadWithChecksumS3Client(String filePath) {
        ChecksumAlgorithm algorithm = ChecksumAlgorithm.CRC32;

        // Initiate the multipart upload.
        CreateMultipartUploadResponse createMultipartUploadResponse = s3Client.createMultipartUpload(b -> b
            .bucket(bucketName)
            .key(key)
            .checksumAlgorithm(algorithm)); // Checksum specified on initiation.
        String uploadId = createMultipartUploadResponse.uploadId();

        // Upload the parts of the file.
        int partNumber = 1;
        List<CompletedPart> completedParts = new ArrayList<>();
        ByteBuffer bb = ByteBuffer.allocate(1024 * 1024 * 5); // 5 MB byte buffer

        try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
            long fileSize = file.length();
            long position = 0;
            while (position < fileSize) {
                file.seek(position);
                long read = file.getChannel().read(bb);

                bb.flip(); // Swap position and limit before reading from the buffer.
                UploadPartRequest uploadPartRequest = UploadPartRequest.builder()
                    .bucket(bucketName)
                    .key(key)
                    .uploadId(uploadId)
                    .checksumAlgorithm(algorithm) // Checksum specified on each part.
                    .partNumber(partNumber)
                    .build();

                UploadPartResponse partResponse = s3Client.uploadPart(
                    uploadPartRequest,
                    RequestBody.fromByteBuffer(bb));

                CompletedPart part = CompletedPart.builder()
                    .partNumber(partNumber)
                    .checksumCRC32(partResponse.checksumCRC32()) // Provide the calculated checksum.
                    .eTag(partResponse.eTag())
                    .build();
                completedParts.add(part);

                bb.clear();
                position += read;
                partNumber++;
            }
        } catch (IOException e) {
            System.err.println(e.getMessage());
        }

        // Complete the multipart upload.
        s3Client.completeMultipartUpload(b -> b
            .bucket(bucketName)
            .key(key)
            .uploadId(uploadId)
            .multipartUpload(CompletedMultipartUpload.builder().parts(completedParts).build()));
    }
```

Der [Code für die vollständigen Beispiele](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/PerformMultiPartUpload.java) und [Tests befindet](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/test/java/com/example/s3/PerformMultiPartUploadTests.java) sich im GitHub Codebeispiel-Repository.

## Herunterladen eines Objekts
<a name="use-service-S3-checksum-download"></a>

Wenn Sie die [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(software.amazon.awssdk.services.s3.model.GetObjectRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3Client.html#getObject(software.amazon.awssdk.services.s3.model.GetObjectRequest)) verwenden, um ein Objekt herunterzuladen, validiert das SDK automatisch die Prüfsumme, . `ChecksumMode` `enabled` wenn die `checksumMode` Methode des Builders für auf gesetzt ist. `GetObjectRequest` `ChecksumMode.ENABLED` 

Die Anfrage im folgenden Codeausschnitt weist das SDK an, die Prüfsumme in der Antwort zu validieren, indem es die Prüfsumme berechnet und die Werte vergleicht.

```
    public GetObjectResponse getObjectWithChecksum() {
        return s3Client.getObject(b -> b
                        .bucket(bucketName)
                        .key(key)
                        .checksumMode(ChecksumMode.ENABLED))
                .response();
    }
```

**Anmerkung**  
Wenn das Objekt nicht mit einer Prüfsumme hochgeladen wurde, findet keine Überprüfung statt. 

## Andere Optionen zur Berechnung der Prüfsumme
<a name="S3-checsum-calculation-options"></a>

**Anmerkung**  
Um die Datenintegrität der übertragenen Daten zu überprüfen und etwaige Übertragungsfehler zu identifizieren, empfehlen wir Benutzern, die SDK-Standardeinstellungen für die Optionen zur Berechnung der Prüfsumme beizubehalten. Standardmäßig fügt das SDK diese wichtige Prüfung für viele S3-Operationen hinzu, einschließlich `PutObject` und`GetObject`.

Wenn Ihre Verwendung von Amazon S3 jedoch nur eine minimale Prüfsummenvalidierung erfordert, können Sie viele Prüfungen deaktivieren, indem Sie die Standardkonfigurationseinstellungen ändern. 

### Deaktivieren Sie die automatische Prüfsummenberechnung, sofern sie nicht erforderlich ist
<a name="S3-minimize-checksum-calc-global"></a>

Sie können die automatische Prüfsummenberechnung durch das SDK für Operationen deaktivieren, die sie unterstützen, z. B. `PutObject` und. `GetObject` Einige S3-Operationen erfordern jedoch eine Prüfsummenberechnung. Sie können die Prüfsummenberechnung für diese Operationen nicht deaktivieren.

Das SDK bietet separate Einstellungen für die Berechnung einer Prüfsumme für die Nutzlast einer Anfrage und für die Nutzlast einer Antwort.

In der folgenden Liste werden die Einstellungen beschrieben, die Sie verwenden können, um die Prüfsummenberechnungen in den verschiedenen Bereichen zu minimieren.
+ **Geltungsbereich für alle Anwendungen** — Wenn Sie die Einstellungen in Umgebungsvariablen oder in einem Profil in den gemeinsam genutzten AWS `config` `credentials` Dateien ändern, können alle Anwendungen diese Einstellungen verwenden. Diese Einstellungen wirken sich auf alle Service-Clients in allen AWS SDK-Anwendungen aus, sofern sie nicht im Anwendungs- oder Service-Client-Bereich außer Kraft gesetzt werden.
  + Fügen Sie die Einstellungen zu einem Profil hinzu:

    ```
    [default]
    request_checksum_calculation = WHEN_REQUIRED
    response_checksum_validation = WHEN_REQUIRED
    ```
  + Umgebungsvariablen hinzufügen:

    ```
    AWS_REQUEST_CHECKSUM_CALCULATION=WHEN_REQUIRED
    AWS_RESPONSE_CHECKSUM_VALIDATION=WHEN_REQUIRED
    ```
+ **Aktueller Anwendungsbereich** — Sie können die Java-Systemeigenschaft auf einstellen, `aws.requestChecksumCalculation` `WHEN_REQUIRED` um die Prüfsummenberechnung einzuschränken. Die entsprechende Systemeigenschaft für Antworten ist. `aws.responseChecksumValidation`

  Diese Einstellungen wirken sich auf alle SDK-Dienstclients in der Anwendung aus, sofern sie nicht bei der Erstellung des Dienstclients außer Kraft gesetzt werden.

  Stellen Sie die Systemeigenschaft zu Beginn Ihrer Anwendung ein:

  ```
  import software.amazon.awssdk.core.SdkSystemSetting;
  import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
  import software.amazon.awssdk.core.checksums.ResponseChecksumValidation;
  import software.amazon.awssdk.services.s3.S3Client;
  
  class DemoClass {
      public static void main(String[] args) {
  
          System.setProperty(SdkSystemSetting.AWS_REQUEST_CHECKSUM_CALCULATION.property(), // Resolves to "aws.requestChecksumCalculation".
                  "WHEN_REQUIRED");
          System.setProperty(SdkSystemSetting.AWS_RESPONSE_CHECKSUM_VALIDATION.property(), // Resolves to "aws.responseChecksumValidation".
                  "WHEN_REQUIRED");
  
          S3Client s3Client = S3Client.builder().build();
  
          // Use s3Client.
      }
  }
  ```
+ **Einzelner S3-Dienstclientbereich** — Sie können einen einzelnen S3-Serviceclient so konfigurieren, dass er mithilfe von Builder-Methoden die Mindestanzahl an Prüfsummen berechnet:

  ```
  import software.amazon.awssdk.core.checksums.RequestChecksumCalculation;
  import software.amazon.awssdk.services.s3.S3Client;
  
  public class RequiredChecksums {
      public static void main(String[] args) {
          S3Client s3 = S3Client.builder()
                  .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                  .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
                  .build();
  
          // Use s3Client. 
      }
  // ...
  }
  ```

### Verwenden Sie aus Gründen der `LegacyMd5Plugin` vereinfachten Kompatibilität MD5
<a name="S3-checksum-legacy-md5"></a>

Mit der Veröffentlichung des CRC32 Prüfsummenverhaltens in Version 2.30.0 hat das SDK die Berechnung von MD5 Prüfsummen für erforderliche Operationen eingestellt.

Wenn Sie ein veraltetes MD5 Prüfsummenverhalten für S3-Operationen benötigen, können Sie das verwenden`LegacyMd5Plugin`, das mit Version 2.31.32 des SDK veröffentlicht wurde.

Dies `LegacyMd5Plugin` ist besonders nützlich, wenn Sie die Kompatibilität mit Anwendungen aufrechterhalten müssen, die vom alten MD5 Prüfsummenverhalten abhängen, insbesondere wenn Sie mit S3-kompatiblen Speicheranbietern von Drittanbietern arbeiten, z. B. solchen, die mit S3A-Dateisystem-Konnektoren (Apache Spark, Iceberg) verwendet werden.

Um das zu verwenden`LegacyMd5Plugin`, fügen Sie es Ihrem S3-Client-Builder hinzu:

```
// For synchronous S3 client.
S3Client s3Client = S3Client.builder()
                           .addPlugin(LegacyMd5Plugin.create())
                           .build();

// For asynchronous S3 client.
S3AsyncClient asyncClient = S3AsyncClient.builder()
                                       .addPlugin(LegacyMd5Plugin.create())
                                       .build();
```

Wenn Sie den Vorgängen, die MD5 Prüfsummen erfordern, Prüfsummen hinzufügen und das Hinzufügen von SDK-Standardprüfsummen für Operationen, die Prüfsummen unterstützen, aber nicht erforderlich sind, überspringen möchten, können Sie die `ClientBuilder` Optionen und als aktivieren. `requestChecksumCalculation` `responseChecksumValidation` `WHEN_REQUIRED` Dadurch werden SDK-Standardprüfsummen nur für Operationen hinzugefügt, für die Prüfsummen erforderlich sind:

```
// Use the `LegacyMd5Plugin` with `requestChecksumCalculation` and `responseChecksumValidation` set to WHEN_REQUIRED.
S3AsyncClient asyncClient = S3AsyncClient.builder()
                                       .addPlugin(LegacyMd5Plugin.create())
                                       .requestChecksumCalculation(RequestChecksumCalculation.WHEN_REQUIRED)
                                       .responseChecksumValidation(ResponseChecksumValidation.WHEN_REQUIRED)
                                       .build();
```

Diese Konfiguration ist besonders nützlich, wenn Sie mit S3-kompatiblen Speichersystemen von Drittanbietern arbeiten, die die neueren Prüfsummenalgorithmen möglicherweise nicht vollständig unterstützen, aber dennoch Prüfsummen für bestimmte Operationen benötigen MD5 .

# Verwenden Sie einen leistungsstarken S3-Client: AWS CRT-basierter S3-Client
<a name="crt-based-s3-client"></a>

Der AWS CRT-basierte S3-Client, der auf [AWS Common Runtime (CRT)](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html) aufbaut, ist ein alternativer asynchroner S3-Client. Es überträgt Objekte zu und von Amazon Simple Storage Service (Amazon S3) mit verbesserter Leistung und Zuverlässigkeit, indem es automatisch die [mehrteilige Upload-API](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) und [Bytebereichs-Abrufe](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range) von Amazon S3 verwendet. 

Der AWS CRT-basierte S3-Client verbessert die Zuverlässigkeit der Übertragung im Falle eines Netzwerkausfalls. Die Zuverlässigkeit wird verbessert, indem einzelne fehlgeschlagene Teile einer Dateiübertragung erneut versucht werden, ohne die Übertragung von vorne neu zu starten.

Darüber hinaus bietet der AWS CRT-basierte S3-Client ein erweitertes Verbindungspooling und einen DNS-Lastenausgleich (Domain Name System), wodurch auch der Durchsatz verbessert wird.

Sie können den AWS CRT-basierten S3-Client anstelle des standardmäßigen asynchronen S3-Clients des SDK verwenden und sofort von seinem verbesserten Durchsatz profitieren.

**Wichtig**  
Der AWS CRT-basierte S3-Client unterstützt derzeit weder die [Erfassung von SDK-Metriken auf Client- noch auf Anforderungsebene](metrics.md).

**AWS CRT-basierte Komponenten im SDK**

Der AWS CRT-basierte *S3-Client*, der in diesem Thema beschrieben wird, und der AWS CRT-basierte *HTTP-Client* sind unterschiedliche Komponenten im SDK. 

Der **AWS CRT-basierte S3-Client** ist eine Implementierung der [AsyncClientS3-Schnittstelle](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html) und wird für die Arbeit mit dem Amazon S3 S3-Service verwendet. Es ist eine Alternative zur Java-basierten Implementierung der `S3AsyncClient` Schnittstelle und bietet mehrere Vorteile.

Der [AWS CRT-basierte HTTP-Client](http-configuration-crt.md) ist eine Implementierung der [SdkAsyncHttpClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/http/async/SdkAsyncHttpClient.html)Schnittstelle und wird für die allgemeine HTTP-Kommunikation verwendet. Es ist eine Alternative zur Netty-Implementierung der `SdkAsyncHttpClient` Schnittstelle und bietet mehrere Vorteile.

Obwohl beide Komponenten Bibliotheken aus der [AWS Common Runtime](https://docs.aws.amazon.com/sdkref/latest/guide/common-runtime.html) verwenden, verwendet der AWS CRT-basierte S3-Client die [3-Bibliothek](https://github.com/awslabs/aws-c-s3) und unterstützt die aws-c-s [S3-Funktionen der mehrteiligen Upload-API](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html). Da der AWS CRT-basierte HTTP-Client für allgemeine Zwecke vorgesehen ist, unterstützt er die API-Funktionen für mehrteilige Uploads von S3 nicht.

## Fügen Sie Abhängigkeiten hinzu, um den CRT-basierten S3-Client zu verwenden AWS
<a name="crt-based-s3-client-depend"></a>

Um den AWS CRT-basierten S3-Client zu verwenden, fügen Sie Ihrer Maven-Projektdatei die folgenden beiden Abhängigkeiten hinzu. Das Beispiel zeigt die zu verwendenden Mindestversionen. Suchen Sie im zentralen Maven-Repository nach den neuesten Versionen der [s3](https://central.sonatype.com/artifact/software.amazon.awssdk/s3) - und [aws-crt-Artefakte](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt).

```
<dependency>
  <groupId>software.amazon.awssdk</groupId>
  <artifactId>s3</artifactId>
  <version>2.27.21</version>
</dependency>
<dependency>
  <groupId>software.amazon.awssdk.crt</groupId>
  <artifactId>aws-crt</artifactId>
  <version>0.30.11</version>
</dependency>
```

## Erstellen Sie eine Instanz des CRT-basierten S3-Clients AWS
<a name="crt-based-s3-client-create"></a>

 Erstellen Sie eine Instanz des AWS CRT-basierten S3-Clients mit Standardeinstellungen, wie im folgenden Codeausschnitt gezeigt.

```
S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
```

Verwenden Sie den CRT-Client-Builder, um den AWS Client zu konfigurieren. Sie können vom standardmäßigen asynchronen S3-Client zum AWS CRT-basierten Client wechseln, indem Sie die Builder-Methode ändern.

```
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;


S3AsyncClient s3AsyncClient = 
        S3AsyncClient.crtBuilder()
                     .credentialsProvider(DefaultCredentialsProvider.create())
                     .region(Region.US_WEST_2)
                     .targetThroughputInGbps(20.0)
                     .minimumPartSizeInBytes(8 * 1025 * 1024L)
                     .build();
```

**Anmerkung**  
Einige Einstellungen im Standard-Builder werden derzeit möglicherweise nicht im AWS CRT-Client-Builder unterstützt. Rufen `S3AsyncClient#builder()` Sie den Standard Builder an.

## Verwenden Sie den AWS CRT-basierten S3-Client
<a name="crt-based-s3-client-use"></a>

Verwenden Sie den AWS CRT-basierten S3-Client, um Amazon S3 S3-API-Operationen aufzurufen. Das folgende Beispiel zeigt die [GetObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#getObject(java.util.function.Consumer,software.amazon.awssdk.core.async.AsyncResponseTransformer))Operationen [PutObject](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClient.html#putObject(java.util.function.Consumer,software.amazon.awssdk.core.async.AsyncRequestBody))und, die über die verfügbar sind. AWS SDK für Java

```
import software.amazon.awssdk.core.async.AsyncRequestBody;
import software.amazon.awssdk.core.async.AsyncResponseTransformer;
import software.amazon.awssdk.services.s3.S3AsyncClient;
import software.amazon.awssdk.services.s3.model.GetObjectResponse;
import software.amazon.awssdk.services.s3.model.PutObjectResponse;


S3AsyncClient s3Client = S3AsyncClient.crtCreate();

// Upload a local file to Amazon S3.
PutObjectResponse putObjectResponse = 
      s3Client.putObject(req -> req.bucket(<BUCKET_NAME>)
                                   .key(<KEY_NAME>),
                        AsyncRequestBody.fromFile(Paths.get(<FILE_NAME>)))
              .join();

// Download an object from Amazon S3 to a local file.
GetObjectResponse getObjectResponse = 
      s3Client.getObject(req -> req.bucket(<BUCKET_NAME>)
                                   .key(<KEY_NAME>),
                        AsyncResponseTransformer.toFile(Paths.get(<FILE_NAME>)))
              .join();
```

## Streams unbekannter Größe werden hochgeladen
<a name="crt-stream-unknown-size"></a>

Ein wesentlicher Vorteil des AWS AWS CRT-basierten S3-Clients ist seine Fähigkeit, Eingabestreams unbekannter Größe effizient zu verarbeiten. Dies ist besonders nützlich, wenn Sie Daten aus einer Quelle hochladen müssen, bei der die Gesamtgröße nicht im Voraus bestimmt werden kann.

```
public PutObjectResponse crtClient_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.crtCreate();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor);  // 'null' indicates that the
                                                                                            // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null){
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

Diese Funktion hilft dabei, häufig auftretende Probleme bei herkömmlichen Uploads zu vermeiden, bei denen eine falsche Angabe der Inhaltslänge zu verkürzten Objekten oder fehlgeschlagenen Uploads führen kann.

## Einschränkungen der Konfiguration
<a name="crt-based-s3-client-limitations"></a>

Der AWS CRT-basierte S3-Client und der Java-basierte asynchrone S3-Client [bieten vergleichbare Funktionen, wobei der CRT-basierte S3-Client einen](examples-s3.md#s3-clients) Leistungsvorteil bietet. AWS Dem AWS CRT-basierten S3-Client fehlen jedoch die Konfigurationseinstellungen, über die der Java-basierte asynchrone S3-Client verfügt. Diese Einstellungen umfassen Folgendes:
+ *Konfiguration auf Clientebene:* Timeout für API-Aufrufversuche, Interzeptoren für die Ausführung von Komprimierung, Herausgeber von Metriken, benutzerdefinierte Ausführungsattribute, benutzerdefinierte erweiterte Optionen, benutzerdefinierter geplanter Ausführungsdienst, benutzerdefinierte Header
+ *Konfiguration auf Anforderungsebene*: benutzerdefinierte Unterzeichner, Timeout für API-Aufrufversuche

Eine vollständige Liste der Konfigurationsunterschiede finden Sie in der API-Referenz.


| Java-basierter asynchroner S3-Client | AWS CRT-basierter S3-Client | 
| --- | --- | 
| Konfigurationen auf Client-Ebene[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)Konfigurationen auf Anforderungsebene[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | Konfigurationen auf Client-Ebene[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/crt-based-s3-client.html)Konfigurationen auf Anforderungsebene[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/de_de/sdk-for-java/latest/developer-guide/crt-based-s3-client.html) | 

# Konfigurieren Sie den Java-basierten asynchronen S3-Client für parallel Übertragungen
<a name="s3-async-client-multipart"></a>

Seit Version 2.27.5 unterstützt der standardmäßige Java-basierte S3-Async-Client automatische parallel Übertragungen (mehrteilige Uploads und Downloads). Sie konfigurieren die Unterstützung für parallel Übertragungen, wenn Sie den Java-basierten asynchronen S3-Client erstellen. 

In diesem Abschnitt wird gezeigt, wie parallel Übertragungen aktiviert und die Konfiguration angepasst werden.

## Erstellen Sie eine Instanz von `S3AsyncClient`
<a name="s3-async-client-multipart-create"></a>

Wenn Sie eine `S3AsyncClient` Instanz erstellen, ohne eine der `multipart*` Methoden auf dem [Builder](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/S3AsyncClientBuilder.html) aufzurufen, sind parallel Übertragungen nicht aktiviert. Jede der folgenden Anweisungen erstellt einen Java-basierten asynchronen S3-Client ohne Unterstützung für mehrteilige Uploads und Downloads.

### *Ohne mehrteilige Unterstützung erstellen*
<a name="s3-async-client-mp-off"></a>

**Example**  

```
import software.amazon.awssdk.auth.credentials.ProcessCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3AsyncClient;


S3AsyncClient s3Client = S3AsyncClient.create();

S3AsyncClient s3Client2 = S3AsyncClient.builder().build();

S3AsyncClient s3Client3 = S3AsyncClient.builder()
        .credentialsProvider(ProcessCredentialsProvider.builder().build())
        .region(Region.EU_NORTH_1)
        .build();
```

### Erstellen Sie *mit mehrteiliger* Unterstützung
<a name="s3-async-client-mp-on"></a>

Um parallel Übertragungen mit Standardeinstellungen zu aktivieren, rufen Sie den `multipartEnabled` On the Builder auf und übergeben Sie ihn, `true` wie im folgenden Beispiel gezeigt.

**Example**  

```
S3AsyncClient s3AsyncClient2 = S3AsyncClient.builder()
        .multipartEnabled(true)
        .build();
```

Der Standardwert ist 8 MiB für die `minimumPartSizeInBytes` Einstellungen `thresholdInBytes` und.

Wenn Sie die Multipart-Einstellungen anpassen, werden parallel Übertragungen automatisch aktiviert, wie im Folgenden gezeigt.

**Example**  

```
import software.amazon.awssdk.services.s3.S3AsyncClient;
import static software.amazon.awssdk.transfer.s3.SizeConstant.MB;


S3AsyncClient s3AsyncClient2 = S3AsyncClient.builder()
        .multipartConfiguration(b -> b
                .thresholdInBytes(16 * MB)
                .minimumPartSizeInBytes(10 * MB))
        .build();
```

## Streams unbekannter Größe werden hochgeladen
<a name="java-async-client-stream-unknown-size"></a>

Der Java-basierte asynchrone S3-Client mit aktiviertem Multipart kann Eingabestreams effizient verarbeiten, bei denen die Gesamtgröße nicht im Voraus bekannt ist:

```
public PutObjectResponse asyncClient_multipart_stream_unknown_size(String bucketName, String key, InputStream inputStream) {

    S3AsyncClient s3AsyncClient = S3AsyncClient.builder().multipartEnabled(true).build();
    ExecutorService executor = Executors.newSingleThreadExecutor();
    AsyncRequestBody body = AsyncRequestBody.fromInputStream(inputStream, null, executor); // 'null' indicates that the
                                                                                           // content length is unknown.
    CompletableFuture<PutObjectResponse> responseFuture =
            s3AsyncClient.putObject(r -> r.bucket(bucketName).key(key), body)
                    .exceptionally(e -> {
                        if (e != null) {
                            logger.error(e.getMessage(), e);
                        }
                        return null;
                    });

    PutObjectResponse response = responseFuture.join(); // Wait for the response.
    executor.shutdown();
    return response;
}
```

Dieser Ansatz verhindert Probleme, die auftreten können, wenn manuell eine falsche Inhaltslänge angegeben wird, wie z. B. gekürzte Objekte oder fehlgeschlagene Uploads.

# Dateien und Verzeichnisse mit dem Amazon S3 Transfer Manager übertragen
<a name="transfer-manager"></a>

Der Amazon S3 Transfer Manager ist ein Open-Source-Hilfsprogramm zur Dateiübertragung auf hohem Niveau für AWS SDK for Java 2.x. Verwenden Sie es, um Dateien und Verzeichnisse zu und von Amazon Simple Storage Service (Amazon S3) zu übertragen. 

[Wenn der [S3 Transfer Manager auf dem AWS CRT-basierten S3-Client](crt-based-s3-client.md) oder dem [standardmäßigen Java-basierten asynchronen S3-Client mit aktiviertem Multipart](s3-async-client-multipart.md) aufbaut, kann er Leistungsverbesserungen wie die [mehrteilige](https://docs.aws.amazon.com/AmazonS3/latest/userguide/mpuoverview.html) Upload-API und Abrufe im Bytebereich nutzen.](https://docs.aws.amazon.com/AmazonS3/latest/userguide/optimizing-performance-guidelines.html#optimizing-performance-guidelines-get-range) 

Mit dem S3 Transfer Manager können Sie auch den Fortschritt einer Übertragung in Echtzeit überwachen und die Übertragung für eine spätere Ausführung unterbrechen.

## Erste Schritte
<a name="transfer-manager-prerequisites"></a>

### Fügen Sie Ihrer Build-Datei Abhängigkeiten hinzu
<a name="transfer-manager-add-dependency"></a>

Um den S3 Transfer Manager mit verbesserter Mehrteile-Leistung zu verwenden, konfigurieren Sie Ihre Build-Datei mit den erforderlichen Abhängigkeiten.

------
#### [ Use the AWS CRT-based S3 client ]

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.27.211</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-transfer-manager</artifactId>
    </dependency>
    <dependency>
        <groupId>software.amazon.awssdk.crt</groupId>
        <artifactId>aws-crt</artifactId>
        <version>0.29.1432</version>
    </dependency>
</dependencies>
```

1 [Letzte Version](https://central.sonatype.com/artifact/software.amazon.awssdk/bom). 2 [Letzte Version](https://central.sonatype.com/artifact/software.amazon.awssdk.crt/aws-crt).

------
#### [ Use the Java-based S3 async client ]

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.27.211</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-transfer-manager</artifactId>
    </dependency>
</dependencies>
```

1 [Letzte Version](https://central.sonatype.com/artifact/software.amazon.awssdk/bom).

------

### Erstellen Sie eine Instanz des S3 Transfer Managers
<a name="transfer-manager-create"></a>

Um die parallel Übertragung zu aktivieren, müssen Sie einen AWS CRT-basierten S3-Client ODER einen Java-basierten asynchronen S3-Client mit aktiviertem Multipart übergeben. Die folgenden Beispiele zeigen, wie Sie einen S3 Transfer Manager mit benutzerdefinierten Einstellungen konfigurieren. 

------
#### [ Use the AWS CRT-based S3 client ]

```
        S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder()
                .credentialsProvider(DefaultCredentialsProvider.create())
                .region(Region.US_EAST_1)
                .targetThroughputInGbps(20.0)
                .minimumPartSizeInBytes(8 * MB)
                .build();

        S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();
```

------
#### [ Use the Java-based S3 async client ]

Wenn die `aws-crt` Abhängigkeit nicht in der Build-Datei enthalten ist, baut der S3 Transfer Manager auf dem standardmäßigen Java-basierten asynchronen S3-Client auf, der im SDK for Java 2.x verwendet wird. 

**Benutzerdefinierte Konfiguration des S3-Clients — Multipart muss aktiviert sein**

```
        S3AsyncClient s3AsyncClient = S3AsyncClient.builder()
                .multipartEnabled(true)
                .credentialsProvider(DefaultCredentialsProvider.create())
                .region(Region.US_EAST_1)
                .build();

        S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();
```

**Keine Konfiguration des S3-Clients — Multipart-Support wird automatisch aktiviert**

```
S3TransferManager transferManager = S3TransferManager.create();
```

------

## Laden Sie eine Datei in einen S3-Bucket hoch
<a name="transfer-manager-upload"></a>

Das folgende Beispiel zeigt ein Beispiel für den Datei-Upload zusammen mit der optionalen Verwendung von a [LoggingTransferListener](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/LoggingTransferListener.html), das den Fortschritt des Uploads protokolliert.

Um eine Datei mit dem S3 Transfer Manager auf Amazon S3 hochzuladen, übergeben Sie ein [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadFileRequest.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadFileRequest.html)Objekt an die [UploadFile-Methode `S3TransferManager`](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#uploadFile(software.amazon.awssdk.transfer.s3.model.UploadFileRequest)) von.

Das von der `uploadFile` Methode zurückgegebene [FileUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/FileUpload.html)Objekt repräsentiert den Upload-Vorgang. Nach Abschluss der Anfrage enthält das [CompletedFileUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedFileUpload.html)Objekt Informationen über den Upload.

```
    public void trackUploadFile(S3TransferManager transferManager, String bucketName,
                             String key, URI filePathURI) {
        UploadFileRequest uploadFileRequest = UploadFileRequest.builder()
                .putObjectRequest(b -> b.bucket(bucketName).key(key))
                .addTransferListener(LoggingTransferListener.create())  // Add listener.
                .source(Paths.get(filePathURI))
                .build();

        FileUpload fileUpload = transferManager.uploadFile(uploadFileRequest);

        fileUpload.completionFuture().join();
        /*
            The SDK provides a LoggingTransferListener implementation of the TransferListener interface.
            You can also implement the interface to provide your own logic.

            Configure log4J2 with settings such as the following.
                <Configuration status="WARN">
                    <Appenders>
                        <Console name="AlignedConsoleAppender" target="SYSTEM_OUT">
                            <PatternLayout pattern="%m%n"/>
                        </Console>
                    </Appenders>

                    <Loggers>
                        <logger name="software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener" level="INFO" additivity="false">
                            <AppenderRef ref="AlignedConsoleAppender"/>
                        </logger>
                    </Loggers>
                </Configuration>

            Log4J2 logs the progress. The following is example output for a 21.3 MB file upload.
                Transfer initiated...
                |                    | 0.0%
                |====                | 21.1%
                |============        | 60.5%
                |====================| 100.0%
                Transfer complete!
        */
    }
```

### Importe
<a name="transfer-manager-upload-imports"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileUpload;
import software.amazon.awssdk.transfer.s3.model.FileUpload;
import software.amazon.awssdk.transfer.s3.model.UploadFileRequest;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.UUID;
```

## Laden Sie eine Datei aus einem S3-Bucket herunter
<a name="transfer-manager-download"></a>

Das folgende Beispiel zeigt ein Download-Beispiel zusammen mit der optionalen Verwendung von a [LoggingTransferListener](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/progress/LoggingTransferListener.html), das den Fortschritt des Downloads protokolliert.

Um ein Objekt mit dem S3 Transfer Manager aus einem S3-Bucket herunterzuladen, erstellen Sie ein [DownloadFileRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DownloadFileRequest.html)Objekt und übergeben es an die Methode [DownloadFile](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#downloadFile(software.amazon.awssdk.transfer.s3.model.DownloadFileRequest)).

Das von der `S3TransferManager` `downloadFile` Methode zurückgegebene [FileDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/FileDownload.html)Objekt stellt die Dateiübertragung dar. Nach Abschluss des Downloads [CompletedFileDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedFileDownload.html)enthält der Zugriff auf Informationen über den Download.

```
    public void trackDownloadFile(S3TransferManager transferManager, String bucketName,
                             String key, String downloadedFileWithPath) {
        DownloadFileRequest downloadFileRequest = DownloadFileRequest.builder()
                .getObjectRequest(b -> b.bucket(bucketName).key(key))
                .addTransferListener(LoggingTransferListener.create())  // Add listener.
                .destination(Paths.get(downloadedFileWithPath))
                .build();

        FileDownload downloadFile = transferManager.downloadFile(downloadFileRequest);

        CompletedFileDownload downloadResult = downloadFile.completionFuture().join();
        /*
            The SDK provides a LoggingTransferListener implementation of the TransferListener interface.
            You can also implement the interface to provide your own logic.

            Configure log4J2 with settings such as the following.
                <Configuration status="WARN">
                    <Appenders>
                        <Console name="AlignedConsoleAppender" target="SYSTEM_OUT">
                            <PatternLayout pattern="%m%n"/>
                        </Console>
                    </Appenders>

                    <Loggers>
                        <logger name="software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener" level="INFO" additivity="false">
                            <AppenderRef ref="AlignedConsoleAppender"/>
                        </logger>
                    </Loggers>
                </Configuration>

            Log4J2 logs the progress. The following is example output for a 21.3 MB file download.
                Transfer initiated...
                |=======             | 39.4%
                |===============     | 78.8%
                |====================| 100.0%
                Transfer complete!
        */
    }
```

### Importe
<a name="transfer-manager-download-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.exception.SdkException;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedFileDownload;
import software.amazon.awssdk.transfer.s3.model.DownloadFileRequest;
import software.amazon.awssdk.transfer.s3.model.FileDownload;
import software.amazon.awssdk.transfer.s3.progress.LoggingTransferListener;

import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
```

## Ein Amazon S3 S3-Objekt in einen anderen Bucket kopieren
<a name="transfer-manager-copy"></a>

Das folgende Beispiel zeigt, wie ein Objekt mit dem S3 Transfer Manager kopiert wird.

Um mit dem Kopieren eines Objekts von einem S3-Bucket in einen anderen Bucket zu beginnen, erstellen Sie eine [CopyObjectRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/model/CopyObjectRequest.html)Basisinstanz.

Verpacken Sie als Nächstes die Basisdatei `CopyObjectRequest` in eine [CopyRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CopyRequest.html), die vom S3 Transfer Manager verwendet werden kann. 

Das von der `S3TransferManager` `copy` Methode zurückgegebene `Copy` Objekt stellt den Kopiervorgang dar. Nach Abschluss des Kopiervorgangs enthält das [CompletedCopy](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedCopy.html)Objekt Details zur Antwort.

```
    public String copyObject(S3TransferManager transferManager, String bucketName,
            String key, String destinationBucket, String destinationKey) {
        CopyObjectRequest copyObjectRequest = CopyObjectRequest.builder()
                .sourceBucket(bucketName)
                .sourceKey(key)
                .destinationBucket(destinationBucket)
                .destinationKey(destinationKey)
                .build();

        CopyRequest copyRequest = CopyRequest.builder()
                .copyObjectRequest(copyObjectRequest)
                .build();

        Copy copy = transferManager.copy(copyRequest);

        CompletedCopy completedCopy = copy.completionFuture().join();
        return completedCopy.response().copyObjectResult().eTag();
    }
```

**Anmerkung**  
Um eine regionsübergreifende Kopie mit dem S3 Transfer Manager durchzuführen, aktivieren Sie ihn `crossRegionAccessEnabled` auf dem AWS CRT-basierten S3-Client-Builder, wie im folgenden Codeausschnitt gezeigt.  

```
S3AsyncClient s3AsyncClient = S3AsyncClient.crtBuilder()
                .crossRegionAccessEnabled(true)
                .build();

S3TransferManager transferManager = S3TransferManager.builder()
                .s3Client(s3AsyncClient)
                .build();
```

### Importe
<a name="transfer-manager-copy-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.CopyObjectRequest;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedCopy;
import software.amazon.awssdk.transfer.s3.model.Copy;
import software.amazon.awssdk.transfer.s3.model.CopyRequest;

import java.util.UUID;
```

## Laden Sie ein lokales Verzeichnis in einen S3-Bucket hoch
<a name="transfer-manager-upload_directory"></a>

Das folgende Beispiel zeigt, wie Sie ein lokales Verzeichnis auf S3 hochladen können.

Rufen Sie zunächst die [UploadDirectory-Methode](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#uploadDirectory(software.amazon.awssdk.transfer.s3.model.UploadDirectoryRequest)) der `S3TransferManager` Instanz auf und übergeben Sie eine [UploadDirectoryRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/UploadDirectoryRequest.html).

Das [DirectoryUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DirectoryUpload.html)Objekt stellt den Upload-Vorgang dar, der nach [CompletedDirectoryUpload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedDirectoryUpload.html)Abschluss der Anforderung eine generiert. Das `CompleteDirectoryUpload` Objekt enthält Informationen über die Ergebnisse der Übertragung, einschließlich der Dateien, die nicht übertragen werden konnten.

```
    public Integer uploadDirectory(S3TransferManager transferManager,
            URI sourceDirectory, String bucketName) {
        DirectoryUpload directoryUpload = transferManager.uploadDirectory(UploadDirectoryRequest.builder()
                .source(Paths.get(sourceDirectory))
                .bucket(bucketName)
                .build());

        CompletedDirectoryUpload completedDirectoryUpload = directoryUpload.completionFuture().join();
        completedDirectoryUpload.failedTransfers()
                .forEach(fail -> logger.warn("Object [{}] failed to transfer", fail.toString()));
        return completedDirectoryUpload.failedTransfers().size();
    }
```

### Importe
<a name="transfer-manager-upload_directory-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.services.s3.model.ObjectIdentifier;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryUpload;
import software.amazon.awssdk.transfer.s3.model.DirectoryUpload;
import software.amazon.awssdk.transfer.s3.model.UploadDirectoryRequest;

import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Paths;
import java.util.UUID;
```

## Laden Sie S3-Bucket-Objekte in ein lokales Verzeichnis herunter
<a name="transfer-manager-download_directory"></a>

Sie können die Objekte in einem S3-Bucket in ein lokales Verzeichnis herunterladen, wie im folgenden Beispiel gezeigt.

Um die Objekte in einem S3-Bucket in ein lokales Verzeichnis herunterzuladen, rufen Sie zunächst die Methode [DownloadDirectory](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/S3TransferManager.html#downloadDirectory(software.amazon.awssdk.transfer.s3.model.DownloadDirectoryRequest)) des Transfer Managers auf und übergeben Sie eine [DownloadDirectoryRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DownloadDirectoryRequest.html).

Das [DirectoryDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/DirectoryDownload.html)Objekt stellt den Download-Vorgang dar, der nach [CompletedDirectoryDownload](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/transfer/s3/model/CompletedDirectoryDownload.html)Abschluss der Anforderung eine generiert. Das `CompleteDirectoryDownload` Objekt enthält Informationen über die Ergebnisse der Übertragung, einschließlich der Dateien, die nicht übertragen werden konnten.

```
    public Integer downloadObjectsToDirectory(S3TransferManager transferManager,
            URI destinationPathURI, String bucketName) {
        DirectoryDownload directoryDownload = transferManager.downloadDirectory(DownloadDirectoryRequest.builder()
                .destination(Paths.get(destinationPathURI))
                .bucket(bucketName)
                .build());
        CompletedDirectoryDownload completedDirectoryDownload = directoryDownload.completionFuture().join();

        completedDirectoryDownload.failedTransfers()
                .forEach(fail -> logger.warn("Object [{}] failed to transfer", fail.toString()));
        return completedDirectoryDownload.failedTransfers().size();
    }
```

### Importe
<a name="transfer-manager-download_directory-import"></a>

```
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.services.s3.model.ObjectIdentifier;
import software.amazon.awssdk.transfer.s3.S3TransferManager;
import software.amazon.awssdk.transfer.s3.model.CompletedDirectoryDownload;
import software.amazon.awssdk.transfer.s3.model.DirectoryDownload;
import software.amazon.awssdk.transfer.s3.model.DownloadDirectoryRequest;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
```

## Vollständige Beispiele anzeigen
<a name="transfer-manager-example-location"></a>

[GitHub enthält den vollständigen](https://github.com/awsdocs/aws-doc-sdk-examples/tree/d73001daea05266eaa9e074ccb71b9383832369a/javav2/example_code/s3/src/main/java/com/example/s3/transfermanager) Code für alle Beispiele auf dieser Seite.

# Arbeiten Sie mit S3-Ereignisbenachrichtigungen
<a name="examples-s3-event-notifications"></a>

Um Ihnen bei der Überwachung der Aktivitäten in Ihren Buckets zu helfen, kann Amazon S3 Benachrichtigungen senden, wenn bestimmte Ereignisse eintreten. Das Amazon S3 S3-Benutzerhandbuch enthält Informationen zu den [Benachrichtigungen, die ein Bucket versenden kann](https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventNotifications.html#notification-how-to-overview). 

Mit dem SDK for Java können Sie einen Bucket einrichten, um Ereignisse an vier mögliche Ziele zu senden: 
+ Amazon-Simple-Notification-Service-Themen
+ Amazon-Simple-Queue-Service-Warteschlangen als Ziele
+ AWS Lambda Funktionen
+ Amazon EventBridge

Wenn Sie einen Bucket einrichten, an den Ereignisse gesendet werden sollen EventBridge, haben Sie die Möglichkeit, eine EventBridge Regel zu konfigurieren, um dasselbe Ereignis an mehrere Ziele weiterzuleiten. Wenn Sie Ihren Bucket so konfigurieren, dass er direkt an eines der ersten drei Ziele sendet, kann für jedes Ereignis nur ein Zieltyp angegeben werden.

Im nächsten Abschnitt erfahren Sie, wie Sie mithilfe des SDK for Java einen Bucket konfigurieren, um S3-Ereignisbenachrichtigungen auf zwei Arten zu senden: direkt an eine Amazon SQS SQS-Warteschlange und an EventBridge.

Im letzten Abschnitt erfahren Sie, wie Sie die S3-API für Ereignisbenachrichtigungen verwenden, um objektorientiert mit Benachrichtigungen zu arbeiten.

## Konfigurieren Sie einen Bucket so, dass er direkt an ein Ziel gesendet wird
<a name="s3-event-conf-bucket-direct"></a>

Im folgenden Beispiel wird ein Bucket so konfiguriert, dass Benachrichtigungen gesendet werden, wenn in *einem* Bucket Ereignisse zur *Objekterstellung oder Objektkennzeichnung* auftreten.

```
static void processS3Events(String bucketName, String queueArn) {
    // Configure the bucket to send Object Created and Object Tagging notifications to an existing SQS queue.
    s3Client.putBucketNotificationConfiguration(b -> b
            .notificationConfiguration(ncb -> ncb
                    .queueConfigurations(qcb -> qcb
                            .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING)
                            .queueArn(queueArn)))
                    .bucket(bucketName)
    );
}
```

Der oben gezeigte Code richtet eine Warteschlange für den Empfang von zwei Arten von Ereignissen ein. Praktischerweise können Sie mit `queueConfigurations` dieser Methode bei Bedarf mehrere Warteschlangenziele festlegen. Außerdem können Sie in der `notificationConfiguration` Methode zusätzliche Ziele festlegen, z. B. ein oder mehrere Amazon SNS SNS-Themen oder eine oder mehrere Lambda-Funktionen. Der folgende Ausschnitt zeigt ein Beispiel mit zwei Warteschlangen und drei Arten von Zielen.

```
s3Client.putBucketNotificationConfiguration(b -> b
                .notificationConfiguration(ncb -> ncb
                        .queueConfigurations(qcb -> qcb
                                .events(Event.S3_OBJECT_CREATED, Event.S3_OBJECT_TAGGING)
                                .queueArn(queueArn), 
                                qcb2 -> qcb2.<...>)
                        .topicConfigurations(tcb -> tcb.<...>)
                        .lambdaFunctionConfigurations(lfcb -> lfcb.<...>))
                        .bucket(bucketName)
        );
```

Das GitHub Codebeispiel-Repository enthält das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java) für das direkte Senden von S3-Ereignisbenachrichtigungen an eine Warteschlange.

## Konfigurieren Sie einen Bucket, an den gesendet werden soll EventBridge
<a name="s3-event-conf-bucket-eventbridge"></a>

Im folgenden Beispiel wird ein Bucket konfiguriert, an den Benachrichtigungen gesendet werden sollen EventBridge.

```
public static String setBucketNotificationToEventBridge(String bucketName) {
    // Enable bucket to emit S3 Event notifications to EventBridge.
    s3Client.putBucketNotificationConfiguration(b -> b
            .bucket(bucketName)
            .notificationConfiguration(b1 -> b1
                    .eventBridgeConfiguration(SdkBuilder::build))
    .build());
```

Wenn Sie einen Bucket konfigurieren, an den Ereignisse gesendet werden sollen EventBridge, geben Sie einfach das EventBridge Ziel an, nicht die Art der Ereignisse oder das endgültige Ziel, an das gesendet EventBridge werden soll. Sie konfigurieren die ultimativen Ziele und Ereignistypen mithilfe des Java EventBridge SDK-Clients.

Der folgende Code zeigt, wie Sie die Konfiguration so konfigurieren EventBridge , dass durch *Objekte erzeugte* Ereignisse zu einem Thema und einer Warteschlange aufgefächert werden.

```
   public static String configureEventBridge(String topicArn, String queueArn) {
        try {
            // Create an EventBridge rule to route Object Created notifications.
            PutRuleRequest putRuleRequest = PutRuleRequest.builder()
                    .name(RULE_NAME)
                    .eventPattern("""
                            {
                              "source": ["aws.s3"],
                              "detail-type": ["Object Created"],
                              "detail": {
                                "bucket": {
                                  "name": ["%s"]
                                }
                              }
                            }
                            """.formatted(bucketName))
                    .build();

            // Add the rule to the default event bus.
            PutRuleResponse putRuleResponse = eventBridgeClient.putRule(putRuleRequest)
                    .whenComplete((r, t) -> {
                        if (t != null) {
                            logger.error("Error creating event bus rule: " + t.getMessage(), t);
                            throw new RuntimeException(t.getCause().getMessage(), t);
                        }
                        logger.info("Event bus rule creation request sent successfully. ARN is: {}", r.ruleArn());
                    }).join();

            // Add the existing SNS topic and SQS queue as targets to the rule.
            eventBridgeClient.putTargets(b -> b
                    .eventBusName("default")
                    .rule(RULE_NAME)
                    .targets(List.of (
                            Target.builder()
                                    .arn(queueArn)
                                    .id("Queue")
                                    .build(),
                            Target.builder()
                                    .arn(topicArn)
                                    .id("Topic")
                                    .build())
                            )
                    ).join();
            return putRuleResponse.ruleArn();
        } catch (S3Exception e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return null;
    }
```

Um EventBridge in Ihrem Java-Code damit zu arbeiten, fügen Sie Ihrer `pom.xml` Maven-Datei eine Abhängigkeit vom `eventbridge` Artefakt hinzu.

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

Das GitHub Repository mit den Codebeispielen enthält das [vollständige Beispiel zum](https://github.com/awsdocs/aws-doc-sdk-examples/blob/main/javav2/example_code/s3/src/main/java/com/example/s3/PutBucketS3EventNotificationEventBridge.java) Senden von S3-Ereignisbenachrichtigungen an EventBridge und dann an ein Thema und eine Warteschlange.

## Verwenden Sie die S3-API für Ereignisbenachrichtigungen, um Ereignisse zu verarbeiten
<a name="s3-event-notification-read"></a>

Nachdem ein Ziel S3-Benachrichtigungsereignisse empfangen hat, können Sie diese mithilfe der S3-API für Ereignisbenachrichtigungen objektorientiert verarbeiten. Sie können die S3-API für Ereignisbenachrichtigungen verwenden, um mit Ereignisbenachrichtigungen zu arbeiten, die direkt an ein Ziel gesendet werden (wie im [ersten Beispiel](#s3-event-conf-bucket-direct) gezeigt), aber nicht mit weitergeleiteten Benachrichtigungen. EventBridge S3-Ereignisbenachrichtigungen, die von Buckets gesendet werden und eine [andere Struktur EventBridge ](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ev-events.html#ev-events-list) enthalten, die die S3-API für Ereignisbenachrichtigungen derzeit nicht verarbeitet.

### Abhängigkeit hinzufügen
<a name="s3-event-notifications-dep"></a>

Die S3-API für Ereignisbenachrichtigungen wurde mit Version 2.25.11 des SDK for Java 2.x veröffentlicht.

Um die S3-API für Ereignisbenachrichtigungen zu verwenden, fügen Sie Ihrem Maven das erforderliche Abhängigkeitselement hinzu, `pom.xml` wie im folgenden Codeausschnitt gezeigt.

```
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>bom</artifactId>
            <version>2.X.X1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
<dependencies>
    <dependency>
        <groupId>software.amazon.awssdk</groupId>
        <artifactId>s3-event-notifications</artifactId>
    </dependency>
</dependencies>
```

1 Letzte Version[.](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)

### Benutze die `S3EventNotification` Klasse
<a name="s3-event-notifications-use"></a>

#### Erstellen Sie eine `S3EventNotification` Instanz aus einer JSON-Zeichenfolge
<a name="s3-event-notifications-use-from-json"></a>

Um eine JSON-Zeichenfolge in ein `S3EventNotification` Objekt zu konvertieren, verwenden Sie die statischen Methoden der `S3EventNotification` Klasse, wie im folgenden Beispiel gezeigt.

```
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotificationRecord
import software.amazon.awssdk.services.sqs.model.Message; 

public class S3EventNotificationExample {
    ...
    
    void receiveMessage(Message message) {
       // Message received from SQSClient.
       String sqsEventBody = message.body();
       S3EventNotification s3EventNotification = S3EventNotification.fromJson(sqsEventBody);
    
       // Use getRecords() to access all the records in the notification.                                                                                                       
       List<S3EventNotificationRecord> records = s3EventNotification.getRecords();   
    
        S3EventNotificationRecord record = records.stream().findFirst();
        // Use getters on the record to access individual attributes.
        String awsRegion = record.getAwsRegion();
        String eventName = record.getEventName();
        String eventSource = record.getEventSource();                                                                                                   
    }
}
```

In diesem Beispiel konvertiert die `fromJson` Methode die JSON-Zeichenfolge in ein `S3EventNotification` Objekt. Fehlende Felder in der JSON-Zeichenfolge führen zu `null` Werten in den entsprechenden Java-Objektfeldern, und alle zusätzlichen Felder in der JSON-Zeichenfolge werden ignoriert.

 APIs Weitere Informationen zu einer Ereignisbenachrichtigung finden Sie in der API-Referenz für`[S3EventNotificationRecord](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/eventnotifications/s3/model/S3EventNotificationRecord.html)`.

#### Konvertiert eine `S3EventNotification` Instanz in eine JSON-Zeichenfolge
<a name="s3-event-notifications-use-to-json"></a>

Verwenden Sie die Methode `toJson` (or`toJsonPretty`), um ein `S3EventNotification` Objekt in eine JSON-Zeichenfolge zu konvertieren, wie im folgenden Beispiel gezeigt.

```
import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification

public class S3EventNotificationExample {
    ...

    void toJsonString(S3EventNotification event) {

        String json = event.toJson();
        String jsonPretty = event.toJsonPretty();

        System.out.println("JSON: " + json);
        System.out.println("Pretty JSON: " + jsonPretty);
    }
}
```

Felder für`GlacierEventData`, `ReplicationEventData``IntelligentTieringEventData`, und `LifecycleEventData` sind aus dem JSON ausgeschlossen, falls sie es sind`null`. Andere `null` Felder werden als `null` serialisiert.

Im Folgenden wird eine Beispielausgabe der `toJsonPretty` Methode für ein S3-Objekt-Tagging-Ereignis gezeigt.

```
{
  "Records" : [ {
    "eventVersion" : "2.3",
    "eventSource" : "aws:s3",
    "awsRegion" : "us-east-1",
    "eventTime" : "2024-07-19T20:09:18.551Z",
    "eventName" : "ObjectTagging:Put",
    "userIdentity" : {
      "principalId" : "AWS:XXXXXXXXXXX"
    },
    "requestParameters" : {
      "sourceIPAddress" : "XXX.XX.XX.XX"
    },
    "responseElements" : {
      "x-amz-request-id" : "XXXXXXXXXXXX",
      "x-amz-id-2" : "XXXXXXXXXXXXX"
    },
    "s3" : {
      "s3SchemaVersion" : "1.0",
      "configurationId" : "XXXXXXXXXXXXX",
      "bucket" : {
        "name" : "amzn-s3-demo-bucket",
        "ownerIdentity" : {
          "principalId" : "XXXXXXXXXXX"
        },
        "arn" : "arn:aws:s3:::XXXXXXXXXX"
      },
      "object" : {
        "key" : "akey",
        "size" : null,
        "eTag" : "XXXXXXXXXX",
        "versionId" : null,
        "sequencer" : null
      }
    }
  } ]
}
```

Ein [vollständiges Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/75c3daadf750406156fc87fa30ee499a206b4a36/javav2/example_code/s3/src/main/java/com/example/s3/ProcessS3EventNotification.java#L117) ist verfügbar GitHub , das zeigt, wie die API verwendet wird, um mit Benachrichtigungen zu arbeiten, die von einer Amazon SQS SQS-Warteschlange empfangen wurden.

## S3-Ereignisse in Lambda mit Java-Bibliotheken verarbeiten: AWS SDK for Java 2.x und `aws-lambda-java-events`
<a name="s3-event-notif-processing-options"></a>

Anstatt das SDK for Java 2.x zur Verarbeitung von Amazon S3 S3-Ereignisbenachrichtigungen in einer Lambda-Funktion zu verwenden, können Sie die `[aws-lambda-java-events](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-events)` Bibliothek in Version 3.x.x verwenden. AWS verwaltet die `aws-lambda-java-events` Bibliothek unabhängig und hat ihre eigenen Abhängigkeitsanforderungen. Die `aws-lambda-java-events` Bibliothek funktioniert nur mit S3-Ereignissen in Lambda-Funktionen, wohingegen das SDK for Java 2.x mit S3-Ereignissen in Lambda-Funktionen, Amazon SNS und Amazon SQS funktioniert.

Beide Ansätze modellieren die Nutzlast für JSON-Ereignisbenachrichtigungen auf objektorientierte Weise mit ähnlichen Methoden. APIs Die folgende Tabelle zeigt die wesentlichen Unterschiede zwischen der Verwendung der beiden Ansätze.


****  

|  | AWS SDK für Java | aws-lambda-java-events Bibliothek | 
| --- | --- | --- | 
| Benennung von Paketen |  `software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification`  | com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification | 
| RequestHandler Parameter |  Schreiben Sie die `RequestHandler` Implementierung Ihrer Lambda-Funktion, um eine JSON-Zeichenfolge zu erhalten: <pre>import com.amazonaws.services.lambda.runtime.Context;<br />import com.amazonaws.services.lambda.runtime.RequestHandler;<br />import software.amazon.awssdk.eventnotifications.s3.model.S3EventNotification;<br /><br />public class Handler implements RequestHandler<String, String> {<br /><br />    @Override<br />        public String handleRequest(String jsonS3Event, Context context) {<br />            S3EventNotification s3Event = S3EventNotification<br />                                             .fromJson(jsonS3Event);<br />            // Work with the s3Event object.        <br />            ...<br />    }<br />}</pre>  | Schreiben Sie die RequestHandler Implementierung Ihrer Lambda-Funktion, um ein S3Event Objekt zu empfangen:<pre>import com.amazonaws.services.lambda.runtime.Context;<br />import com.amazonaws.services.lambda.runtime.RequestHandler;<br />import com.amazonaws.services.lambda.runtime.events.S3Event;<br /><br />public class Handler implements RequestHandler<S3Event, String> {<br /><br />    @Override<br />        public String handleRequest(S3Event s3event, Context context) {<br />            // Work with the s3Event object.        <br />            ...<br />    }<br />}</pre> | 
| Maven-Abhängigkeiten |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.X.X</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <dependency><br />        <groupId>software.amazon.awssdk</groupId><br />        <artifactId>s3-event-notifications</artifactId><br />    </dependency><br />    <!-- Add other SDK dependencies that you need. --><br /></dependencies></pre>  |  <pre><dependencyManagement><br />    <dependencies><br />        <dependency><br />            <groupId>software.amazon.awssdk</groupId><br />            <artifactId>bom</artifactId><br />            <version>2.X.X</version><br />            <type>pom</type><br />            <scope>import</scope><br />        </dependency><br />    </dependencies><br /></dependencyManagement><br /><dependencies><br />    <!-- The following two dependencies are for the <br />         aws-lambda-java-events library. --><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-lambda-java-core</artifactId><br />        <version>1.2.3</version>     <br />    </dependency><br />    <dependency><br />        <groupId>com.amazonaws</groupId><br />        <artifactId>aws-lambda-java-events</artifactId><br />        <version>3.15.0</version><br />    </dependency><br />    <!-- Add other SDK dependencies that you need. --><br /></dependencies></pre>  | 

# Arbeite mit Amazon Simple Notification Service
<a name="examples-simple-notification-service"></a>

Mit Amazon Simple Notification Service können Sie ganz einfach Benachrichtigungen in Echtzeit von Ihren Anwendungen über mehrere Kommunikationskanäle an Abonnenten senden. In diesem Thema wird beschrieben, wie Sie einige der Grundfunktionen von ausführen Amazon SNS.

## Erstellen eines Themas
<a name="sns-create-topic"></a>

Ein **Thema** ist eine logische Gruppierung von Kommunikationskanälen, die definiert, an welche Systeme eine Nachricht gesendet werden soll, z. B. das Auffächern einer Nachricht AWS Lambda und ein HTTP-Webhook. Sie senden Nachrichten an Amazon SNS, dann werden sie an die im Thema definierten Kanäle verteilt. Dadurch werden die Nachrichten für Abonnenten zur Verfügung gestellt.

Um ein Thema zu erstellen, erstellen Sie zunächst ein [CreateTopicRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/CreateTopicRequest.html)Objekt, wobei der Name des Themas mithilfe der `name()` Methode im Builder festgelegt ist. Senden Sie dann das Anforderungsobjekt an, Amazon SNS indem Sie die `createTopic()` Methode von verwenden [SnsClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/SnsClient.html). Sie können das Ergebnis dieser Anfrage als [CreateTopicResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/CreateTopicResponse.html)Objekt erfassen, wie im folgenden Codeausschnitt gezeigt.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CreateTopicRequest;
import software.amazon.awssdk.services.sns.model.CreateTopicResponse;
import software.amazon.awssdk.services.sns.model.SnsException;
```

 **Code** 

```
    public static String createSNSTopic(SnsClient snsClient, String topicName ) {

        CreateTopicResponse result = null;
        try {
            CreateTopicRequest request = CreateTopicRequest.builder()
                    .name(topicName)
                    .build();

            result = snsClient.createTopic(request);
            return result.topicArn();
        } catch (SnsException e) {

            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return "";
    }
```

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

## Listen Sie Ihre Amazon SNS Themen auf
<a name="sns-crelistate-topics"></a>

Um eine Liste Ihrer vorhandenen Amazon SNS Themen abzurufen, erstellen Sie ein [ListTopicsRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/ListTopicsRequest.html)Objekt. Senden Sie dann das Anforderungsobjekt an, Amazon SNS indem Sie die `listTopics()` Methode von verwenden`SnsClient`. Sie können das Ergebnis dieser Anfrage als [ListTopicsResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/ListTopicsResponse.html)Objekt erfassen.

Der folgende Codeausschnitt druckt den HTTP-Statuscode der Anfrage und eine Liste von Amazon-Ressourcennamen (ARNs) für Ihre Amazon SNS Themen aus.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.ListTopicsRequest;
import software.amazon.awssdk.services.sns.model.ListTopicsResponse;
import software.amazon.awssdk.services.sns.model.SnsException;
```

 **Code** 

```
    public static void listSNSTopics(SnsClient snsClient) {

        try {
            ListTopicsRequest request = ListTopicsRequest.builder()
                   .build();

            ListTopicsResponse result = snsClient.listTopics(request);
            System.out.println("Status was " + result.sdkHttpResponse().statusCode() + "\n\nTopics\n\n" + result.topics());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Abonnieren eines Endpunkts für ein Thema
<a name="sns-subscribe-endpoint-topic"></a>

Nachdem Sie ein Thema erstellt haben, können Sie konfigurieren, welche Kommunikationskanäle Endpunkte für dieses Thema sein sollen. Nachrichten werden an diese Endpunkte verteilt, nachdem sie Amazon SNS empfangen wurden.

Wenn Sie einen Kommunikationskanal als Endpunkt für ein Thema konfigurieren möchten, abonnieren Sie diesen Endpunkt für das Thema. Erstellen Sie zunächst ein [SubscribeRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/SubscribeRequest.html)Objekt. Geben Sie den Kommunikationskanal (z. B. `lambda` oder`email`) als an`protocol()`. Stellen Sie das `endpoint()` auf den entsprechenden Ausgabespeicherort ein (z. B. den ARN einer Lambda Funktion oder eine E-Mail-Adresse), und legen Sie dann den ARN des Themas fest, das Sie abonnieren möchten, als`topicArn()`. Senden Sie das Anforderungsobjekt mit der `subscribe()` Methode von`SnsClient`. Amazon SNS Sie können das Ergebnis dieser Anfrage als [SubscribeResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/SubscribeResponse.html)Objekt erfassen.

Im folgenden Codeausschnitt wird dargestellt, wie Sie eine E-Mail-Adresse für ein Thema abonnieren.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.SubscribeRequest;
import software.amazon.awssdk.services.sns.model.SubscribeResponse;
```

 **Code** 

```
    public static void subEmail(SnsClient snsClient, String topicArn, String email) {

        try {
            SubscribeRequest request = SubscribeRequest.builder()
                .protocol("email")
                .endpoint(email)
                .returnSubscriptionArn(true)
                .topicArn(topicArn)
                .build();

            SubscribeResponse result = snsClient.subscribe(request);
            System.out.println("Subscription ARN: " + result.subscriptionArn() + "\n\n Status is " + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Veröffentlichen einer Nachricht für ein Thema
<a name="sns-publish-message-topic"></a>

Nachdem Sie ein Thema und einen oder mehrere Endpunkte dafür konfiguriert haben, können Sie eine Nachricht dafür veröffentlichen. Erstellen Sie zunächst ein [PublishRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/PublishRequest.html)Objekt. Geben Sie zum Senden `message()` und den ARN des Themas (`topicArn()`) an, an das es gesendet werden soll. Senden Sie dann das Anforderungsobjekt an, Amazon SNS indem Sie die `publish()` Methode von verwenden`SnsClient`. Sie können das Ergebnis dieser Anfrage als [PublishResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/PublishResponse.html)Objekt erfassen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.PublishRequest;
import software.amazon.awssdk.services.sns.model.PublishResponse;
import software.amazon.awssdk.services.sns.model.SnsException;
```

 **Code** 

```
    public static void pubTopic(SnsClient snsClient, String message, String topicArn) {

        try {
            PublishRequest request = PublishRequest.builder()
                .message(message)
                .topicArn(topicArn)
                .build();

            PublishResponse result = snsClient.publish(request);
            System.out.println(result.messageId() + " Message sent. Status is " + result.sdkHttpResponse().statusCode());

         } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
         }
    }
```

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

## Abmelden eines Endpunkts von einem Thema
<a name="sns-unsubscribe-endpoint-topic"></a>

Sie können die als Endpunkte für ein Thema konfigurierten Kommunikationskanäle entfernen. Danach ist das Thema selbst weiterhin vorhanden und verteilt Nachrichten an alle anderen Endpunkte, die für dieses Thema konfiguriert sind.

Wenn Sie einen Kommunikationskanal als Endpunkt für ein Thema entfernen möchten, melden Sie diesen Endpunkt für das Thema ab. Erstellen Sie zunächst ein [UnsubscribeRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/UnsubscribeRequest.html)Objekt und legen Sie den ARN des Themas fest, von dem Sie sich abmelden möchten, als`subscriptionArn()`. Senden Sie dann das Anforderungsobjekt an SNS, indem Sie die Methode `unsubscribe()` von `SnsClient` verwenden. Sie können das Ergebnis dieser Anfrage als [UnsubscribeResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/UnsubscribeResponse.html)Objekt erfassen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.UnsubscribeRequest;
import software.amazon.awssdk.services.sns.model.UnsubscribeResponse;
```

 **Code** 

```
    public static void unSub(SnsClient snsClient, String subscriptionArn) {

        try {
            UnsubscribeRequest request = UnsubscribeRequest.builder()
                .subscriptionArn(subscriptionArn)
                .build();

            UnsubscribeResponse result = snsClient.unsubscribe(request);

            System.out.println("\n\nStatus was " + result.sdkHttpResponse().statusCode()
                + "\n\nSubscription was removed for " + request.subscriptionArn());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

## Löschen eines Themas
<a name="sns-delete-topic"></a>

Um ein Amazon SNS Thema zu löschen, erstellen Sie zunächst ein [DeleteTopicRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/DeleteTopicRequest.html)Objekt mit dem ARN des Themas, der als `topicArn()` Methode im Builder festgelegt ist. Senden Sie dann das Anforderungsobjekt an, Amazon SNS indem Sie die `deleteTopic()` Methode von verwenden`SnsClient`. Sie können das Ergebnis dieser Anfrage als [DeleteTopicResponse](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sns/model/DeleteTopicResponse.html)Objekt erfassen, wie im folgenden Codeausschnitt gezeigt.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.DeleteTopicRequest;
import software.amazon.awssdk.services.sns.model.DeleteTopicResponse;
import software.amazon.awssdk.services.sns.model.SnsException;
```

 **Code** 

```
    public static void deleteSNSTopic(SnsClient snsClient, String topicArn ) {

        try {
            DeleteTopicRequest request = DeleteTopicRequest.builder()
                .topicArn(topicArn)
                .build();

            DeleteTopicResponse result = snsClient.deleteTopic(request);
            System.out.println("\n\nStatus was " + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

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

Weitere Informationen finden Sie im [Amazon Simple Notification Service -Entwicklerhandbuch](https://docs.aws.amazon.com/sns/latest/dg/).

# Arbeite mit Amazon Simple Queue Service
<a name="examples-sqs"></a>

Dieser Abschnitt enthält Beispiele für die Programmierung [Amazon Simple Queue Service](https://docs.aws.amazon.com/sqs/)mit AWS SDK für Java 2.x.

Die folgenden Beispiele enthalten nur den Code, der zur Demonstration jeder Technik nötig ist. Der [vollständige Beispielcode ist verfügbar unter GitHub](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2). Von dort aus können Sie eine einzelne Quelldatei herunterladen oder das Repository klonen, um alle Beispiele lokal zu erstellen und auszuführen.

**Topics**
+ [Verwenden Sie die automatische Batchverarbeitung von Anfragen](sqs-auto-batch.md)
+ [Vorgänge in der Warteschlange](examples-sqs-message-queues.md)
+ [Nachrichtenoperationen](examples-sqs-messages.md)

# Verwenden Sie die automatische Batchverarbeitung von Anfragen für Amazon SQS mit dem AWS SDK for Java 2.x
<a name="sqs-auto-batch"></a>

Die Automatic Request Batching API für Amazon SQS ist eine Bibliothek auf hoher Ebene, die eine effiziente Möglichkeit bietet, Anfragen für SQS-Operationen zu stapeln und zu puffern. Durch die Verwendung der Batching-API reduzieren Sie die Anzahl der Anfragen an SQS, was den Durchsatz verbessert und die Kosten minimiert. 

Da die Batch-API-Methoden mit den `[SqsAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsAsyncClient.html)` Methoden—`sendMessage`,,`changeMessageVisibility`, `receiveMessage` —übereinstimmen`deleteMessage`, können Sie die Batch-API als direkten Ersatz mit minimalen Änderungen verwenden. 

Dieses Thema gibt Ihnen einen Überblick über die Konfiguration und die Arbeit mit der Automatic Request Batching API für Amazon SQS.

## Überprüfen Sie die Voraussetzungen
<a name="sqs-auto-batch-requirements"></a>

Sie müssen Version *2.28.0* oder höher des SDK for Java 2.x verwenden, um auf die Batching-API zugreifen zu können. Ihr Maven `pom.xml` sollte mindestens die folgenden Elemente enthalten.

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

1 [Letzte Version](https://central.sonatype.com/artifact/software.amazon.awssdk/bom)

## Erstellen Sie einen Batch-Manager
<a name="sqs-auto-batch-create"></a>

Die automatische Batching-API für Anfragen wird von der [SqsAsyncBatchManager](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html)Schnittstelle implementiert. Sie können eine Instanz des Managers auf verschiedene Arten erstellen.

### Standardkonfiguration mithilfe von `SqsAsyncClient`
<a name="sqs-batch-manager-create-default"></a>

Die einfachste Methode zum Erstellen eines Batch-Managers besteht darin, die `batchManager` Factory-Methode für eine vorhandene [SqsAsyncClient](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsAsyncClient.html)Instanz aufzurufen. Der einfache Ansatz wird im folgenden Snippet gezeigt. 

```
SqsAsyncClient asyncClient = SqsAsyncClient.create();
SqsAsyncBatchManager sqsAsyncBatchManager = asyncClient.batchManager();
```

Wenn Sie diesen Ansatz verwenden, verwendet die `SqsAsyncBatchManager` Instanz die Standardwerte, die in der Tabelle im [Überschreiben Sie die Konfigurationseinstellungen für `SqsAsyncBatchManager`](#sqs-auto-batch-config-settings) Abschnitt aufgeführt sind. Darüber hinaus verwendet die `SqsAsyncBatchManager` Instanz die `ExecutorService` der `SqsAsyncClient` Instanz, aus der sie erstellt wurde.

### Benutzerdefinierte Konfiguration mithilfe von `SqsAsyncBatchManager.Builder`
<a name="sqs-batch-manager-create-custom"></a>

Für fortgeschrittenere Anwendungsfälle können Sie den Batch-Manager mithilfe von anpassen [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.Builder.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.Builder.html). Wenn Sie diesen Ansatz verwenden, um eine `SqsAsyncBatchManager` Instanz zu erstellen, können Sie das Batching-Verhalten fein abstimmen. Der folgende Ausschnitt zeigt ein Beispiel dafür, wie Sie den Builder verwenden können, um das Batching-Verhalten anzupassen.

```
SqsAsyncBatchManager batchManager = SqsAsyncBatchManager.builder()
    .client(SqsAsyncClient.create())
    .scheduledExecutor(Executors.newScheduledThreadPool(5))
    .overrideConfiguration(b -> b
        .receiveMessageMinWaitDuration(Duration.ofSeconds(10))
        .receiveMessageVisibilityTimeout(Duration.ofSeconds(1))
        .receiveMessageAttributeNames(Collections.singletonList("*"))
        .receiveMessageSystemAttributeNames(Collections.singletonList(MessageSystemAttributeName.ALL)))
    .build();
```

Wenn Sie diesen Ansatz verwenden, können Sie die Einstellungen für das `BatchOverrideConfiguration` Objekt anpassen, die in der Tabelle im Abschnitt aufgeführt sind. [Überschreiben Sie die Konfigurationseinstellungen für `SqsAsyncBatchManager`](#sqs-auto-batch-config-settings) Mit diesem Ansatz können Sie auch einen benutzerdefinierten Wert [https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/ScheduledExecutorService.html](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/concurrent/ScheduledExecutorService.html)für den Batch-Manager angeben.

## Senden Sie Nachrichten
<a name="sqs-auto-batch-send"></a>

Verwenden Sie die `[SqsAsyncBatchManager\$1sendMessage](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html#sendMessage(software.amazon.awssdk.services.sqs.model.SendMessageRequest))` Methode, um Nachrichten mit dem Batch-Manager zu senden. Das SDK puffert Anfragen und sendet sie als Batch, wenn die `sendRequestFrequency` Werte `maxBatchSize` oder erreicht sind.

Das folgende Beispiel zeigt eine `sendMessage` Anfrage, auf die unmittelbar eine weitere Anfrage folgt. In diesem Fall sendet das SDK beide Nachrichten in einem einzigen Batch.

```
// Sending the first message
CompletableFuture<SendMessageResponse> futureOne = 
    sqsAsyncBatchManager.sendMessage(r -> r.messageBody("One").queueUrl("queue"));

// Sending the second message
CompletableFuture<SendMessageResponse> futureTwo = 
    sqsAsyncBatchManager.sendMessage(r -> r.messageBody("Two").queueUrl("queue"));

// Waiting for both futures to complete and retrieving the responses
SendMessageResponse messageOne = futureOne.join();
SendMessageResponse messageTwo = futureTwo.join();
```

## Ändern Sie das Timeout für die Sichtbarkeit von Nachrichten
<a name="sqs-auto-batch-change-vis"></a>

Sie können das Sichtbarkeits-Timeout von Nachrichten in einem Batch mithilfe der [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html#changeMessageVisibility(java.util.function.Consumer)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html#changeMessageVisibility(java.util.function.Consumer))Methode ändern. Das SDK puffert Anfragen und sendet sie als Batch, wenn die `sendRequestFrequency` Werte `maxBatchSize` oder erreicht sind.

Das folgende Beispiel zeigt, wie die `changeMessageVisibility` Methode aufgerufen wird.

```
CompletableFuture<ChangeMessageVisibilityResponse> futureOne =
    sqsAsyncBatchManager.changeMessageVisibility(r -> 
        r.receiptHandle("receiptHandle")
         .queueUrl("queue"));
ChangeMessageVisibilityResponse response = futureOne.join();
```

## Nachrichten löschen
<a name="sqs-auto-batch-delete"></a>

Mit [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html#deleteMessage(java.util.function.Consumer)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html#deleteMessage(java.util.function.Consumer))dieser Methode können Sie Nachrichten stapelweise löschen. Das SDK puffert Anfragen und sendet sie als Batch, wenn die `sendRequestFrequency` Werte `maxBatchSize` oder erreicht sind.

Das folgende Beispiel zeigt, wie Sie die `deleteMessage` Methode aufrufen können.

```
CompletableFuture<DeleteMessageResponse> futureOne = 
    sqsAsyncBatchManager.deleteMessage(r -> 
        r.receiptHandle("receiptHandle")
         .queueUrl("queue"));
DeleteMessageResponse response = futureOne.join();
```

## Empfangen Sie Nachrichten
<a name="sqs-auto-batch-receive"></a>

### Verwenden Sie die Standardeinstellungen
<a name="sqs-auto-batch-receive-default-settings"></a>

Wenn Sie die `[SqsAsyncBatchManager\$1receiveMessage](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/SqsAsyncBatchManager.html#receiveMessage(java.util.function.Consumer))` Methode in Ihrer Anwendung abfragen, ruft der Batch-Manager Nachrichten aus seinem internen Puffer ab, den das SDK automatisch im Hintergrund aktualisiert.

Das folgende Beispiel zeigt, wie die `receiveMessage` Methode aufgerufen wird.

```
CompletableFuture<ReceiveMessageResponse> responseFuture = 
    sqsAsyncBatchManager.receiveMessage(r -> r.queueUrl("queueUrl"));
```

### Verwenden Sie benutzerdefinierte Einstellungen
<a name="sqs-auto-batch-receive-custom-settings"></a>

Wenn Sie die Anfrage weiter anpassen möchten, indem Sie beispielsweise benutzerdefinierte Wartezeiten festlegen und die Anzahl der abzurufenden Nachrichten angeben, können Sie die Anforderung wie im folgenden Beispiel dargestellt anpassen.

```
CompletableFuture<ReceiveMessageResponse> response = 
    sqsAsyncBatchManager.receiveMessage(r -> 
        r.queueUrl("queueUrl")
         .waitTimeSeconds(5)
         .visibilityTimeout(20));
```

**Anmerkung**  
Wenn Sie `receiveMessage` mit einer aufrufen`[ReceiveMessageRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/ReceiveMessageRequest.html)`, die einen der folgenden Parameter enthält, umgeht das SDK den Batch-Manager und sendet eine reguläre asynchrone Anfrage`receiveMessage`:  
`messageAttributeNames`
`messageSystemAttributeNames`
`messageSystemAttributeNamesWithStrings`
`overrideConfiguration`

## Überschreiben Sie die Konfigurationseinstellungen für `SqsAsyncBatchManager`
<a name="sqs-auto-batch-config-settings"></a>

Sie können die folgenden Einstellungen anpassen, wenn Sie eine `SqsAsyncBatchManager` Instanz erstellen. Die folgende Liste von Einstellungen ist auf der verfügbar [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/BatchOverrideConfiguration.Builder.html](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/batchmanager/BatchOverrideConfiguration.Builder.html).


| Einstellung | Description | Standardwert | 
| --- | --- | --- | 
| maxBatchSize | Maximale Anzahl von Anfragen pro Stapel für jedesSendMessageBatchRequest,ChangeMessageVisibilityBatchRequest, oderDeleteMessageBatchRequest. Der Höchstwert ist 10. | 10 | 
| sendRequestFrequency |  Zeit bis zum Senden eines Batches, sofern sie nicht `maxBatchSize` früher erreicht wurde. Höhere Werte können die Anzahl der Anfragen reduzieren, aber die Latenz erhöhen.  | 200 ms | 
| receiveMessageVisibilityTimeout | Timeout für die Sichtbarkeit von Nachrichten. Wenn diese Option nicht gesetzt ist, wird die Standardeinstellung der Warteschlange verwendet. | Die Standardeinstellung der Warteschlange | 
| receiveMessageMinWaitDuration | Minimale Wartezeit für receiveMessage Anfragen. Vermeiden Sie es, auf 0 zu setzen, um CPU-Verschwendung zu vermeiden. | 50 ms | 
| receiveMessageSystemAttributeNames | Liste der [Systemattributnamen](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/MessageSystemAttributeName.html), die für receiveMessage Anrufe angefordert werden sollen. | Keine | 
| receiveMessageAttributeNames | Liste der [Attributnamen](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-metadata.html#sqs-message-attributes), die für receiveMessage Anrufe angefordert werden sollen. | Keine | 

# Mit Amazon Simple Queue Service Nachrichtenwarteschlangen arbeiten
<a name="examples-sqs-message-queues"></a>

Eine *Nachrichtenwarteschlange* ist der logische Container, in den Nachrichten zuverlässig gesendet werden Amazon Simple Queue Service. Es gibt zwei Arten von Warteschlangen: *Standard* und *First-in-First-out-Verfahren* (FIFO). Weitere Informationen zu Warteschlangen und den Unterschieden zwischen diesen Typen finden Sie im [Amazon Simple Queue Service Entwicklerhandbuch](https://docs.aws.amazon.com//AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html).

In diesem Thema wird beschrieben, wie Sie mithilfe von eine Amazon Simple Queue Service Warteschlange erstellen, auflisten, löschen und deren URL abrufen. AWS SDK für Java

Die in den folgenden Beispielen verwendete `sqsClient` Variable kann aus dem folgenden Codeausschnitt erstellt werden.

```
SqsClient sqsClient = SqsClient.create();
```

Wenn Sie eine `SqsClient` mit der statischen `create()` Methode erstellen, konfiguriert das SDK die Region mithilfe der [Standardregion-Anbieterkette](region-selection.md#default-region-provider-chain) und die Anmeldeinformationen mithilfe der [Standard-Anbieterkette für Anmeldeinformationen](credentials-chain.md).

## Erstellen einer Warteschlange
<a name="sqs-create-queue"></a>

Verwenden Sie die `SqsClient’s` `createQueue` Methode und stellen Sie ein `[CreateQueueRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/CreateQueueRequest.html)` Objekt bereit, das die Warteschlangenparameter beschreibt, wie im folgenden Codeausschnitt dargestellt.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
            CreateQueueRequest createQueueRequest = CreateQueueRequest.builder()
                .queueName(queueName)
                .build();

            sqsClient.createQueue(createQueueRequest);
```

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

## Auflisten von Warteschlangen
<a name="sqs-list-queues"></a>

Um die Amazon Simple Queue Service Warteschlangen für Ihr Konto aufzulisten, rufen Sie die `SqsClient’s` `listQueues` Methode mit einem `[ListQueuesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/ListQueuesRequest.html)` Objekt auf.

Wenn Sie die Form der [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsClient.html#listQueues()](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsClient.html#listQueues())Methode verwenden, die keine Parameter akzeptiert, gibt der Dienst *alle Warteschlangen zurück — bis zu 1.000 Warteschlangen*. 

Sie können dem `[ListQueuesRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/ListQueuesRequest.html)` Objekt ein Präfix für den Warteschlangennamen angeben, um die Ergebnisse auf Warteschlangen zu beschränken, die diesem Präfix entsprechen, wie im folgenden Code gezeigt.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
        String prefix = "que";

        try {
            ListQueuesRequest listQueuesRequest = ListQueuesRequest.builder().queueNamePrefix(prefix).build();
            ListQueuesResponse listQueuesResponse = sqsClient.listQueues(listQueuesRequest);

            for (String url : listQueuesResponse.queueUrls()) {
                System.out.println(url);
            }

        } catch (SqsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
```

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

## Abrufen der URL für eine Warteschlange
<a name="sqs-get-queue-url"></a>

Der folgende Code zeigt, wie Sie die URL für eine Warteschlange abrufen, indem Sie die `SqsClient’s` `getQueueUrl` Methode mit einem `[GetQueueUrlRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/GetQueueUrlRequest.html)` Objekt aufrufen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
            GetQueueUrlResponse getQueueUrlResponse =
                sqsClient.getQueueUrl(GetQueueUrlRequest.builder().queueName(queueName).build());
            String queueUrl = getQueueUrlResponse.queueUrl();
            return queueUrl;
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/7486a1a092aa8e16a21698ef26f9d524fef62e55/javav2/example_code/sqs/src/main/java/com/example/sqs/SQSExample.java#L70) finden Sie unter GitHub.

## Löschen einer Warteschlange
<a name="sqs-delete-queue"></a>

Geben Sie die [URL](#sqs-get-queue-url) der Warteschlange für das `[DeleteQueueRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/DeleteQueueRequest.html)` Objekt an. Rufen Sie dann die `SqsClient’s` `deleteQueue` Methode zum Löschen einer Warteschlange auf, wie im folgenden Code gezeigt.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
    public static void deleteSQSQueue(SqsClient sqsClient, String queueName) {

        try {

            GetQueueUrlRequest getQueueRequest = GetQueueUrlRequest.builder()
                    .queueName(queueName)
                    .build();

            String queueUrl = sqsClient.getQueueUrl(getQueueRequest).queueUrl();

            DeleteQueueRequest deleteQueueRequest = DeleteQueueRequest.builder()
                    .queueUrl(queueUrl)
                    .build();

            sqsClient.deleteQueue(deleteQueueRequest);

        } catch (SqsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/6240df86c5f17eae1e23d1139d1435c7dc4b2a11/javav2/example_code/sqs/src/main/java/com/example/sqs/DeleteQueue.java#L48) finden Sie unter GitHub.

## Weitere Informationen
<a name="more-information"></a>
+  [CreateQueue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_CreateQueue.html)in der Amazon Simple Queue Service API-Referenz
+  [GetQueueUrl](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_GetQueueUrl.html)in der Amazon Simple Queue Service API-Referenz
+  [ListQueues](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ListQueues.html)in der Amazon Simple Queue Service API-Referenz
+  [DeleteQueue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteQueue.html)in der Amazon Simple Queue Service API-Referenz

# Amazon Simple Queue Service Nachrichten senden, empfangen und löschen
<a name="examples-sqs-messages"></a>

Eine Nachricht ist ein Datenabschnitt, der von verteilten Komponenten gesendet und empfangen werden kann. Nachrichten werden immer mit einer [SQS-Warteschlange](examples-sqs-message-queues.md) geliefert.

Die in den folgenden Beispielen verwendete `sqsClient` Variable kann aus dem folgenden Codeausschnitt erstellt werden.

```
SqsClient sqsClient = SqsClient.create();
```

Wenn Sie eine `SqsClient` mit der statischen `create()` Methode erstellen, konfiguriert das SDK die Region mithilfe der [Standardregion-Anbieterkette](region-selection.md#default-region-provider-chain) und die Anmeldeinformationen mithilfe der [Standard-Anbieterkette für Anmeldeinformationen](credentials-chain.md).

## Senden einer Nachricht
<a name="sqs-message-send"></a>

Fügen Sie einer Amazon Simple Queue Service Warteschlange eine einzelne Nachricht hinzu, indem Sie die SqsClient `sendMessage` Client-Methode aufrufen. Geben Sie ein [SendMessageRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/SendMessageRequest.html)Objekt an, das die [URL](examples-sqs-message-queues.md#sqs-get-queue-url), den Nachrichtentext und den optionalen Verzögerungswert (in Sekunden) der Warteschlange enthält.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
            sqsClient.sendMessage(SendMessageRequest.builder()
                .queueUrl(queueUrl)
                .messageBody("Hello world!")
                .delaySeconds(10)
                .build());

            sqsClient.sendMessage(sendMsgRequest);
```

## Senden Sie mehrere Nachrichten in einer Anfrage
<a name="sqs-messages-send-multiple"></a>

Senden mehrerer Nachrichten in einer einzigen Anforderung unter Verwendung der `sendMessageBatch`-Methode des SqsClient . Diese Methode verwendet eine [SendMessageBatchRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/SendMessageBatchRequest.html), die die URL der Warteschlange und eine Liste der zu sendenden Nachrichten enthält. (Jede Nachricht ist eine [SendMessageBatchRequestEntry](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/SendMessageBatchRequestEntry.html).) Sie können das Senden einer bestimmten Nachricht auch verzögern, indem Sie einen Verzögerungswert für die Nachricht festlegen.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
            SendMessageBatchRequest sendMessageBatchRequest = SendMessageBatchRequest.builder()
                .queueUrl(queueUrl)
                .entries(SendMessageBatchRequestEntry.builder().id("id1").messageBody("Hello from msg 1").build(),
                        SendMessageBatchRequestEntry.builder().id("id2").messageBody("msg 2").delaySeconds(10).build())
                .build();
            sqsClient.sendMessageBatch(sendMessageBatchRequest);
```

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

## Nachrichten abrufen
<a name="sqs-messages-receive"></a>

Abrufen von aktuell in der Warteschlange enthaltenen Nachrichten durch Aufruf der `receiveMessage`-Methode des SqsClient . Diese Methode verwendet eine [ReceiveMessageRequest](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/ReceiveMessageRequest.html), die die Warteschlangen-URL enthält. Sie können auch die maximale Anzahl von Nachrichten angeben, die zurückgegeben werden soll. Nachrichten werden als Liste von [Message](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/model/Message.html)-Objekten zurückgegeben.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
        try {
            ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
                .queueUrl(queueUrl)
                .maxNumberOfMessages(5)
                .build();
            List<Message> messages = sqsClient.receiveMessage(receiveMessageRequest).messages();
            return messages;
        } catch (SqsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return null;
```

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

## Löschen Sie eine Nachricht nach Erhalt
<a name="sqs-messages-delete"></a>

Nachdem Sie eine Nachricht empfangen und ihren Inhalt verarbeitet haben, löschen Sie die Nachricht aus der Warteschlange, indem Sie das Empfangs-Handle und die Warteschlangen-URL der Nachricht an die `SqsClient's` [https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsClient.html#deleteMessage(software.amazon.awssdk.services.sqs.model.DeleteMessageRequest)](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/sqs/SqsClient.html#deleteMessage(software.amazon.awssdk.services.sqs.model.DeleteMessageRequest))Methode senden.

 **Importe** 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sqs.SqsClient;
import software.amazon.awssdk.services.sqs.model.*;
import java.util.List;
```

 **Code** 

```
        try {
            for (Message message : messages) {
                DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
                        .queueUrl(queueUrl)
                        .receiptHandle(message.receiptHandle())
                        .build();
                sqsClient.deleteMessage(deleteMessageRequest);
            }
```

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

## Weitere Infos
<a name="more-info"></a>
+  [So funktionieren Amazon Simple Queue Service Warteschlangen](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-basic-architecture.html) im Amazon Simple Queue Service Entwicklerhandbuch
+  [SendMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html)in der Amazon Simple Queue Service API-Referenz
+  [SendMessageBatch](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessageBatch.html)in der Amazon Simple Queue Service API-Referenz
+  [ReceiveMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_ReceiveMessage.html)in der Amazon Simple Queue Service API-Referenz
+  [DeleteMessage](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_DeleteMessage.html)in der Amazon Simple Queue Service API-Referenz

# Arbeite mit Amazon Transcribe
<a name="examples-transcribe"></a>

Das folgende Beispiel zeigt, wie bidirektionales Streaming mit Amazon Transcribe funktioniert. Bidirektionales Streaming bedeutet, dass ein Datenstrom zum Service gesendet wird und auch in Echtzeit wieder empfangen wird. Das Beispiel verwendet Amazon Transcribe Streaming-Transkription, um einen Audiostream zu senden und einen Stream mit transkribiertem Text in Echtzeit zurück zu empfangen.

Weitere Informationen zu dieser Funktion finden Sie unter [Streaming-Transkription](https://docs.aws.amazon.com//transcribe/latest/dg/streaming.html) im Amazon Transcribe Entwicklerhandbuch.

Informationen [zu den ersten](https://docs.aws.amazon.com//transcribe/latest/dg/getting-started.html) Schritten finden Sie unter Amazon Transcribe Erste Schritte im Amazon Transcribe Entwicklerhandbuch.

## Richten Sie das Mikrofon ein
<a name="set-up-the-microphone"></a>

Dieser Code verwendet das javax.sound.sampled-Paket zum Streamen von Audio aus einem Eingabegerät.

 **Code** 

```
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;

public class Microphone {

    public static TargetDataLine get() throws Exception {
        AudioFormat format = new AudioFormat(16000, 16, 1, true, false);
        DataLine.Info datalineInfo = new DataLine.Info(TargetDataLine.class, format);

        TargetDataLine dataLine = (TargetDataLine) AudioSystem.getLine(datalineInfo);
        dataLine.open(format);

        return dataLine;
    }
}
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/ac748d8ef99cd17e297cb74fe13aa671e2679088/javav2/example_code/transcribe/src/main/java/com/amazonaws/transcribe/Microphone.java) finden Sie unter GitHub.

## Erstellen Sie einen Herausgeber
<a name="create-a-publisher"></a>

Dieser Code implementiert einen Herausgeber, der Audiodaten aus dem Amazon Transcribe Audiostream veröffentlicht.

 **Code** 

```
package com.amazonaws.transcribe;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.transcribestreaming.model.AudioEvent;
import software.amazon.awssdk.services.transcribestreaming.model.AudioStream;
import software.amazon.awssdk.services.transcribestreaming.model.TranscribeStreamingException;


public class AudioStreamPublisher implements Publisher<AudioStream> {
    private final InputStream inputStream;

    public AudioStreamPublisher(InputStream inputStream) {
        this.inputStream = inputStream;
    }

    @Override
    public void subscribe(Subscriber<? super AudioStream> s) {
        s.onSubscribe(new SubscriptionImpl(s, inputStream));
    }

    private class SubscriptionImpl implements Subscription {
        private static final int CHUNK_SIZE_IN_BYTES = 1024 * 1;
        private ExecutorService executor = Executors.newFixedThreadPool(1);
        private AtomicLong demand = new AtomicLong(0);

        private final Subscriber<? super AudioStream> subscriber;
        private final InputStream inputStream;

        private SubscriptionImpl(Subscriber<? super AudioStream> s, InputStream inputStream) {
            this.subscriber = s;
            this.inputStream = inputStream;
        }

        @Override
        public void request(long n) {
            if (n <= 0) {
                subscriber.onError(new IllegalArgumentException("Demand must be positive"));
            }

            demand.getAndAdd(n);

            executor.submit(() -> {
                try {
                    do {
                        ByteBuffer audioBuffer = getNextEvent();
                        if (audioBuffer.remaining() > 0) {
                            AudioEvent audioEvent = audioEventFromBuffer(audioBuffer);
                            subscriber.onNext(audioEvent);
                        } else {
                            subscriber.onComplete();
                            break;
                        }
                    } while (demand.decrementAndGet() > 0);
                } catch (TranscribeStreamingException e) {
                    subscriber.onError(e);
                }
            });
        }

        @Override
        public void cancel() {

        }

        private ByteBuffer getNextEvent() {
            ByteBuffer audioBuffer;
            byte[] audioBytes = new byte[CHUNK_SIZE_IN_BYTES];

            int len = 0;
            try {
                len = inputStream.read(audioBytes);

                if (len <= 0) {
                    audioBuffer = ByteBuffer.allocate(0);
                } else {
                    audioBuffer = ByteBuffer.wrap(audioBytes, 0, len);
                }
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }

            return audioBuffer;
        }

        private AudioEvent audioEventFromBuffer(ByteBuffer bb) {
            return AudioEvent.builder()
                    .audioChunk(SdkBytes.fromByteBuffer(bb))
                    .build();
        }
    }
}
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/ac748d8ef99cd17e297cb74fe13aa671e2679088/javav2/example_code/transcribe/src/main/java/com/amazonaws/transcribe/AudioStreamPublisher.java) finden Sie unter GitHub.

## Erstellen Sie den Client und starten Sie den Stream
<a name="create-the-client-and-start-the-stream"></a>

Erstellen Sie in der Hauptmethode ein Anforderungsobjekt, starten Sie den Audioeingabe-Stream und instanziieren Sie den Herausgeber mit der Audioeingabe.

Sie müssen auch eine erstellen [StartStreamTranscriptionResponseHandler](https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/transcribestreaming/model/StartStreamTranscriptionResponseHandler.html), um anzugeben, wie die Antwort von behandelt werden soll Amazon Transcribe.

Verwenden Sie dann die `startStreamTranscription` Methode TranscribeStreamingAsyncClient's, um das bidirektionale Streaming zu starten.

 **Importe** 

```
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.TargetDataLine;
import javax.sound.sampled.AudioInputStream;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.transcribestreaming.TranscribeStreamingAsyncClient;
import software.amazon.awssdk.services.transcribestreaming.model.TranscribeStreamingException ;
import software.amazon.awssdk.services.transcribestreaming.model.StartStreamTranscriptionRequest;
import software.amazon.awssdk.services.transcribestreaming.model.MediaEncoding;
import software.amazon.awssdk.services.transcribestreaming.model.LanguageCode;
import software.amazon.awssdk.services.transcribestreaming.model.StartStreamTranscriptionResponseHandler;
import software.amazon.awssdk.services.transcribestreaming.model.TranscriptEvent;
```

 **Code** 

```
    public static void convertAudio(TranscribeStreamingAsyncClient client) throws Exception {

        try {

            StartStreamTranscriptionRequest request = StartStreamTranscriptionRequest.builder()
                    .mediaEncoding(MediaEncoding.PCM)
                    .languageCode(LanguageCode.EN_US)
                    .mediaSampleRateHertz(16_000).build();

            TargetDataLine mic = Microphone.get();
            mic.start();

            AudioStreamPublisher publisher = new AudioStreamPublisher(new AudioInputStream(mic));

            StartStreamTranscriptionResponseHandler response =
                    StartStreamTranscriptionResponseHandler.builder().subscriber(e -> {
                        TranscriptEvent event = (TranscriptEvent) e;
                        event.transcript().results().forEach(r -> r.alternatives().forEach(a -> System.out.println(a.transcript())));
                    }).build();

            // Keeps Streaming until you end the Java program
            client.startStreamTranscription(request, publisher, response);

        } catch (TranscribeStreamingException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
         }
    }
```

Das [vollständige Beispiel](https://github.com/awsdocs/aws-doc-sdk-examples/blob/ac748d8ef99cd17e297cb74fe13aa671e2679088/javav2/example_code/transcribe/src/main/java/com/amazonaws/transcribe/BidirectionalStreaming.java) finden Sie unter. GitHub

## Weitere Informationen
<a name="more-info"></a>
+  [Wie es funktioniert](https://docs.aws.amazon.com//transcribe/latest/dg/how-it-works.html), finden Sie im Amazon Transcribe Entwicklerhandbuch.
+  [Erste Schritte mit dem Streamen von Audio](https://docs.aws.amazon.com//transcribe/latest/dg/getting-started.html) im Amazon Transcribe Entwicklerhandbuch.