2016-07-18 26 views
4

Ich versuche, den Körper einer http-Anfrage zu bekommen, aber es scheint, als ob es nicht so einfach ist, wie es klingen mag, es sei denn, natürlich fehlt mir etwas.Akka HTTP mit Java - get String von RequestEntity

Ich habe eine Instanz der HttpRequest (von akka.http.javadsl.model) und davon kann ich die RequestEntity bekommen, aber ich kann nicht herausfinden, wie man die Zeichenfolge aus der Entität extrahieren.
Ich möchte das synchron tun, nur eine einfache Operation, die Zeichenfolge aus dort zu bekommen.

ich zwei verschiedene Wege versucht:

(1)

Source<ByteString, Object> source = RequestEntity.getDataBytes(); 

Ich bin nicht sicher, was ich mit dem source tun soll, hat es eine Menge von Methoden, und es ist unklar, wie man diese benutzt und wenn einer von ihnen mir tatsächlich helfen kann.

(2)

Unmarshaller<HttpEntity, String> unmarshaller = Unmarshaller.entityToString(); 
CompletionStage<String> result = unmarshaller.unmarshall(entity, ExecutionContext, Materializer); 

unmarshaller.unmarshall Aufruf erfordert nicht nur eine Instanz von RequestEntity sondern auch ein ExecutionContext und ein Materializer, die ich auch nicht an dem Teil des unmarshalling haben, gibt es eine CompletionStage<String>, welches komplett redundant, wie ich möchte, dass es synchronisiert wird.

Die Dokumentation und Beispiele für Java nicht viel helfen, da sie sehr kurz sind und kurz, wenn sie überhaupt existieren, zum Beispiel in der Marshalling & Unmarshalling section:

Verwenden Sie die vordefinierten Unmarshaller.entityToString, Unmarshaller. entityToByteString, Unmarshaller.entityToByteArray, Unmarshaller.entityToCharArray auf diese Grundtypen

zu konvertieren Wie Sie sehen können, ist dies nicht sehr informativ.

Irgendwelche Ideen?

+0

Ich wundere mich, wenn Sie kein Glück mit dieser Aufgabe haben? – fnt

+3

@fnt Nein, ich habe beschlossen, 'Akka' nicht zu verwenden, da die Dokumentation und die Unterstützung sehr schlecht sind (zumindest für Java), es war einfach zu frustrierend. –

Antwort

0

Die Java-Dokumente sind ein Work-in-Progress und das ist einer der Bereiche, in denen es Proben fehlt.

Um Ihre Frage mit der entity Richtlinie mit einem der vordefinierten Einweiser wie folgt aussehen würde zu antworten:

path("example",() -> 
    entity(Unmarshaller.entityToString(), (string) -> { 
    System.out.println("request body: " + string); 
    return complete("ok"); 
    }) 
) 

Beachten Sie, dass es den gesamten Anforderungs Körper in den Speicher des JVM gelesen werden, die einige Gedanken erfordern . Für Anforderungsstellen gibt es ein Standardlimit von 8 M, das durch Konfiguration geändert oder für einen bestimmten Pfad mit den Anweisungen withSizeLimit und withoutSizeLimit überschrieben werden kann.

Ich habe Akka ticket 21001 geöffnet, um das Hinzufügen dieser zu den Dokumenten zu verfolgen.

+2

Danke für die Info. Die Größenbeschränkung stört mich nicht, da die Anfragen, die ich zu unterstützen beabsichtige, nicht nah an "8M" kommen, aber ich bevorzuge nur die "Low-Level-Server-API" und nicht die "High-Level-API". . Ich bin mir der "Entity" -Richtlinie bewusst, es ist nur so, dass ich überhaupt keine Richtlinien verwenden möchte. Die Frage ist also, wie kann ich das von der Request-Entity erreichen? –

+0

@johanandren Haben Sie ein Beispiel dafür, wie Sie einen benutzerdefinierten Unmarshaller erstellen können? Der Blick auf die Javadocs, Dokumentation und Online-Ressourcen ist nicht viel. – Quy

2

Sie können das globale ExecutionContext und das gleiche Materializer für den Betrieb akka-http verwendet verwenden.Sie müssen die Future komponieren, die HTTP-Anforderung mit dem von den Unmarshaller vorausgesetzt, man macht:

import akka.actor.ActorSystem; 
    import akka.dispatch.ExecutionContexts; 
    import akka.http.javadsl.Http; 
    import akka.http.javadsl.model.HttpRequest; 
    import akka.http.javadsl.model.HttpResponse; 
    import akka.http.javadsl.model.ResponseEntity; 
    import akka.http.javadsl.unmarshalling.Unmarshaller; 
    import akka.stream.ActorMaterializer; 
    import akka.stream.Materializer; 

    ActorSystem system = ActorSystem.create(); 
    Materializer materializer = ActorMaterializer.create(system); 

    Http.get(system). 
     singleRequest(HttpRequest.create("http://stackoverflow.com/"), materializer). 
     thenCompose(response -> Unmarshaller.entityToString().unmarshal(response.entity(), ExecutionContexts.global(), materializer)). 
     thenAccept(System.out::println);