Anträge abholen und prüfen
TL;DR – Submission per submissionId (oder per Polling über die eigene Destination) abrufen.
Das SDK entschlüsselt und validiert und legt einen Prüfbericht vor.
Auf Fachdaten, Metadaten und Anhänge zugreifen, dann mit accept oder reject abschließen — das
entscheiden Sie, nicht das SDK.
Der volle Ablauf — abholen über die eigene Organisation, lesen, den Prüfbericht auswerten, annehmen oder ablehnen:
- Java
- .NET (C#)
Organisation organisation = sdk.organisation(myDestinationId, keys);
ReceivedSubmission received = organisation.receive(submissionId);
String data = received.getDataAsString();
List<Attachment> attachments = received.getAttachments();
if (received.acceptable()) {
organisation.accept(received);
} else {
organisation.reject(received, received.report().asProblems());
}
IOrganisationClient organisation = client.AsOrganisation();
IncomingSubmission received = await organisation.FetchSubmission(submissionId, caseId);
string data = received.GetDataAsString();
List<Attachment> attachments = received.Attachments;
if (received.Acceptable())
await organisation.AcceptSubmission(received);
else
await organisation.RejectSubmission(received, received.Report.AsProblems().ToList());
Der Ablauf in einem Bild
Eine bekannte Submission abholen
Wenn Sie submissionId und caseId bereits kennen (z. B. aus einem Callback), holen Sie
die Submission direkt:
- Java
- .NET (C#)
Organisation organisation = sdk.organisation(myDestinationId, keys);
UUID submissionId = UUID.fromString("...");
ReceivedSubmission received = organisation.receive(submissionId);
IOrganisationClient organisation = client.AsOrganisation();
IncomingSubmission received = await organisation.FetchSubmission(submissionId, caseId);
Abholbereite Submissions per Polling erfragen
Wenn Sie keine Callbacks verwenden, fragen Sie aktiv beim Zustelldienst nach allen für einen Zustellpunkt vorliegenden Einreichungen.
- Java
- .NET (C#)
SubmissionsForPickup page =
organisation.awaitingSubmissions(/* offset */ 0, /* limit */ 100);
List<SubmissionForPickup> all = organisation.awaitingSubmissions();
organisation ist bereits an genau eine Destination gebunden (myDestinationId beim Erzeugen)
— anders als früher übergeben Sie die Destination hier nicht mehr pro Aufruf. SubmissionsForPickup
/ SubmissionForPickup enthalten zunächst nur die IDs. Mit organisation.receive(submissionForPickup)
holen Sie eine konkrete Einreichung mit Fach- und Metadaten.
var destinationId = Guid.Parse("d2d43892-9d9c-4630-980a-5af341179b14");
List<IncomingSubmission> available =
await organisation.FetchAvailableSubmissionsFromDestination(destinationId);
Das .NET-SDK lädt die verfügbaren Submissions direkt vollständig (entschlüsselt + validiert, jede
mit ihrem Report). Brauchen Sie nur die IDs — etwa für ein eigenes Locking oder um den Zustand
ohne Entschlüsselung zu prüfen (GetSubmissionState(submission)) — greifen Sie auf
client.SubmissionApiService.GetAvailableSubmissionsFromDestination(...) zurück.
Auf Fachdaten, Metadaten und Anhänge zugreifen
Das SDK liefert Ihnen eine ReceivedSubmission (Java) bzw. IncomingSubmission (.NET), in der die
Daten bereits entschlüsselt und alle Signaturen geprüft sind. Schlägt eine Prüfung fehl, wird
nichts automatisch zurückgewiesen — die Submission trägt stattdessen einen Prüfbericht
(report() / Report), den Sie vor dem Annehmen auswerten. Siehe
Konzept: Der Prüfbericht.
- Java
- .NET (C#)
ReceivedSubmission received = organisation.receive(submissionId);
Fachdaten kommen bereits entschlüsselt als Text, zusammen mit Schema und MIME-Type:
String data = received.getDataAsString();
URI schemaUri = received.getDataSchemaUri();
String mimeType = received.getDataMimeType();
Die Metadaten (Absender, Verwaltungsleistung, Rückkanal, …) stecken in einem eigenen Objekt:
Metadata meta = received.getMetadata();
Anhänge iterieren Sie einzeln — für große Dateien stream-basiert statt komplett in den RAM geladen:
for (Attachment a : received.getAttachments()) {
String filename = a.getFileName();
try (InputStream in = a.openStream()) {
// streamen statt komplett in den RAM laden
}
}
Und die relevanten IDs für Status-Abfragen oder spätere Antworten:
UUID submission = received.id();
UUID caseId = received.caseId();
UUID destination = received.getDestinationId();
IncomingSubmission received = await organisation.FetchSubmission(submissionId, caseId);
// --- Fachdaten ---
string data = received.GetDataAsString();
Uri schemaUri = received.GetDataSchemaUri();
SchemaMimeType mimeType = received.GetDataMimeType();
Metadata metadata = received.Metadata;
// --- Anhänge ---
foreach (Attachment a in received.Attachments)
{
string filename = a.FileName;
await using Stream stream = a.OpenStream();
// streamen statt komplett in den RAM laden
}
// --- IDs ---
Guid submission = received.SubmissionId;
Guid caseRef = received.CaseId;
Guid destination = received.DestinationId;
Guid? sender = received.FromDestinationId; // Zustellpunkt des Absenders
Wenn Sie planen, dem Onlinedienst zu antworten (Bidirektionale Kommunikation),
persistieren Sie an dieser Stelle die caseId und den replyEncryptionKey aus dem
ReplyChannel der Metadaten. Beide werden nach dem accept-submission-Event benötigt –
siehe Antworten senden und lesen.
Submission akzeptieren oder zurückweisen
Akzeptieren signalisiert dem Onlinedienst und dem Zustelldienst, dass die Einreichung
erfolgreich entgegengenommen wurde. Zurückweisen schlägt die Einreichung mit Problems
ab. Das SDK entscheidet das nicht selbst (kein Auto-Reject mehr, siehe
Konzept: Der Prüfbericht) — Ihr Fachverfahren ruft immer explizit
accept(...) oder reject(...) auf. Beides schreibt ein mit Ihrem Signaturschlüssel signiertes
Event in den Vorgang.
- Java
- .NET (C#)
Der Regelfall: erst den mitgelieferten Prüfbericht auswerten, dann anhand von
acceptable() entscheiden. report().describe() liefert eine lesbare Zusammenfassung aller
Befunde, report().asProblems() reicht die Fehler direkt an reject(...) durch:
if (!received.acceptable()) {
System.out.println(received.report().describe());
organisation.reject(received, received.report().asProblems());
} else {
organisation.accept(received);
}
Akzeptieren nimmt zusätzlich optional informative Problems als Varargs entgegen — Annahme trotz
Beanstandung ist damit möglich, auch wenn acceptable() bereits true ist:
organisation.accept(received);
organisation.accept(received, new MyCustomProblem("Anhang wird nachgereicht"));
Ein accept(...)-Aufruf, während acceptable() false liefert, wirft
SubmissionNotAcceptableException statt das Accept-Event zu senden — die Submission bleibt
unbeantwortet und lässt sich weiterhin ablehnen.
Zurückweisen mit eigenen, zusätzlichen Problems statt (oder neben) dem Report geht ebenso:
organisation.reject(received, List.of(
new DataSchemaViolation("Feld X fehlt"),
new MyCustomProblem("Stadtname existiert nicht")
));
Und geht auch direkt aus dem noch unentschlüsselten SubmissionForPickup — etwa wenn schon der
Schlüssel fehlt:
organisation.reject(submissionForPickup, List.of(new TechnicalError()));
Der Regelfall: erst den Bericht prüfen, dann anhand von Acceptable() entscheiden.
Report.Describe() liefert eine lesbare Zusammenfassung, Report.AsProblems() die Fehler als
Problem-Liste für RejectSubmission:
if (!received.Acceptable())
{
logger.LogWarning(received.Report.Describe());
await organisation.RejectSubmission(received, received.Report.AsProblems().ToList());
}
else
{
await organisation.AcceptSubmission(received);
}
Akzeptieren nimmt optional informative Problems entgegen; Zurückweisen mit eigenen Gründen geht neben oder statt dem Bericht:
await organisation.AcceptSubmission(received, [new MyCustomProblem("Anhang wird nachgereicht")]);
await organisation.RejectSubmission(received,
[
new DataJsonSyntaxViolation(),
new MyCustomProblem("Stadtname existiert nicht"),
]);
Ein AcceptSubmission(...)-Aufruf, während Acceptable() false liefert, wirft
SubmissionNotAcceptableException statt das Accept-Event zu senden — die Submission bleibt
unbeantwortet und lässt sich weiterhin ablehnen.
Nach accept-submission wird die Einreichung in den Zustand deleted versetzt und vom
Zustelldienst gelöscht. Sichern Sie alle benötigten Daten vorher in Ihrem Fachverfahren.
Häufige Stolperfallen
- Gechunkte Anhänge im RAM: Wenn ein Sender ein Attachment mit Chunking übertragen
hat, sollten Sie stream-basiert auf den Anhang zugreifen (
openStream()/OpenStream()) statt mitgetDataAsBytes()/GetDataAsBytes()— siehe Große Anhänge. - Mehrere
Organisation-Instanzen, ein Zustellpunkt: Die Methoden liefern alle abholbereiten Submissions. Wenn mehrere Instanzen pollen, sollten Sie Locking in Ihrem Fachverfahren vorsehen, um Doppelverarbeitung zu vermeiden. - Ungeprüft angenommen: Wer
accept(...)aufruft, ohne vorheracceptable()zu prüfen, riskiert eineSubmissionNotAcceptableExceptionbei fehlerhaften Einreichungen. Das SDK reagiert nicht mehr automatisch (kein Auto-Reject) — siehe Konzept: Der Prüfbericht. - Persistenz vor Accept: Sichern Sie Fachdaten und Anhänge in Ihrem Fachverfahren,
bevor Sie
acceptrufen. Danach ist die Submission im Zustelldienst gelöscht.
Weiter geht's
- Antworten senden und lesen – den Bescheid in den Vorgang senden
- Callbacks prüfen – Push-Benachrichtigungen statt Polling
- Status verfolgen
- Custom Schemata – eigene JSON/XSD-Schemata für die Fachdatenvalidierung registrieren (Java)
- Virenscanner anbinden – Anhänge vor dem Import scannen
- Konzept: Der Prüfbericht