2013-09-01 8 views
6

Ich bin ziemlich neu in vielen der Konzepte und Technologien, die in dieser Frage verwendet werden, so würde ich ein wenig Verständnis und Hilfe für einen Anfänger aus der Community schätzen. Ich benutze die Play Framework Version 2.1.3 und ich muss Daten an einen REST-fähigen Web-Service senden, damit er in eine entfernte Datenbank eingefügt werden kann. Eine XML-Antwort wird zurückgegeben, die entweder Erfolg oder Misserfolg anzeigt.Wie: Zugreifen auf RESTful Web Services mit Play Framework 2.1 für Anfänger

Ich bin mir sicher, dass Sie wissen, dass die Dokumentation für das Play Framework ziemlich fehlt und für Anfänger nicht hilfreich ist. Daher bin ich unsicher, wie ich diese Aufgabe mit Best Practices erfüllen soll. Ich suche eine Java-Lösung für dieses Problem, ich habe derzeit keine Zeit, die Sprache Scala zu lernen. Meine Erfahrung mit Web Services ist ziemlich begrenzt, normalerweise würde ich ein DAO-Entwurfsmuster (oder benutze eine der vielen verfügbaren ORM-Bibliotheken je nach Bedarf) in meiner Anwendung implementieren und JDBC verwenden, um eine direkte Verbindung zur Datenbank herzustellen. Das ist keine Option hier.

Meine erste Frage müsste sein, gibt es ein empfohlenes Design-Muster für den Zugriff auf Web-Services? Betrachten wir nun das MVC-Framework von Play, wie würde man ein solches Designmuster am besten implementieren, die Daten verpacken (vorausgesetzt, die Anwendung hat bereits Daten vom Benutzer erfasst und validiert), sie abschickt und die Antworten zurück an den Benutzer verarbeitet?

Ich weiß, es ist eine ziemlich lange Frage, aber meine Absicht dahinter ist, eine Wissensdatenbank für Anfänger zu schaffen, die leicht mit begrenzter Erfahrung kommen, lesen, verstehen und replizieren können, was sie hier finden, um eine funktionierende Lösung zu produzieren . Nachdem ich das Web ziemlich ausführlich durchsucht habe, habe ich ein paar unzusammenhängende Schnipsel gefunden, aber nichts Konkretes, was diese Technologien und keine aktuellen Tutorials betrifft. Vielen Dank für Ihre Zeit.

+0

Dieser Beitrag ist sehr ähnlich, wenn auch nicht gerade nach oben duplizieren Ich glaube: http://stackoverflow.com/questions/4379485/restful-on-play-framework - kombinieren diese mit das Spiel! ToDo List Beispiel und das sollte Ihnen einen soliden Ausgangspunkt geben. – pfairbairn

+0

Vielen Dank für die Antwort, da die Frage im Jahr 2010 gestellt wurde Ich nehme an, es bezieht sich auf Spiel-Framework-Version 1, seit Spiel 2 wurde nur im Jahr 2012 veröffentlicht. Sie sind in keiner Weise gleich. Ich könnte aber falsch liegen und werde den Post überprüfen. Ich bin hier auch mehr auf Best Practices fokussiert. – Hegemon

+0

Fair-Point, jedoch Querverweise auf diesen Beitrag mit der Java Play 2.1 ToDo-Liste, http://www.playframework.com/documentation/2.1.x/JavaTodoList, die Informationen zum Routing, POST, GET und PUT für HTTP-Anfragen verwenden würde Machen Sie das SO-Post immer noch nützlich, auch wenn es etwas veraltet ist. – pfairbairn

Antwort

11

Erstellen von Anfragen ist einfach. Zuerst geben Sie eine URL an. Es gibt verschiedene Methoden, um der Anfrage Inhaltstypen, Abfrageparameter, Timeouts usw. hinzuzufügen. Dann wählen Sie einen Anfragetyp und fügen optional einige Inhalte zum Senden hinzu. Beispiele:

WSRequestHolder request = WS.url("http://example.com"); 
request.setQueryParameter("page", "1"); 
Promise<Response> promise = request.get(); 
Promise<Response> promise = WS.url("http://example.com").post(content); 

Der komplizierteste Teil ist es zu senden und die Antwort der Anfrage zu verwenden. Ich nehme an, Sie haben einen Controller, der dem Benutzer basierend auf der Antwort des Webdienstes eine Result zurückgeben soll. Das Ergebnis ist normalerweise eine gerenderte Vorlage oder nur ein Statuscode.

Play vermeidet Blockierung durch Verwendung von Futures and Promises. Die async Methode des Controllers nimmt eine Promise<Result> und gibt zu einem späteren Zeitpunkt ein Ergebnis (den zukünftigen Wert) zurück. Ein einfach zu verwendendes Versprechen wird von den oben gezeigten Methoden get und post zur Verfügung gestellt. Sie müssen nicht auf ihre Implementierung achten, Sie müssen nur wissen, dass sie versprechen, eine Response bereitzustellen, sobald die Anfrage abgeschlossen ist.

Hinweis hier das Problem: Wenn eine Anfrage mit WS.url("...").get() Erstellen es wird Ihnen ein Promise<Response> obwohl async eine Promise<Result> nimmt. Hier müssen Sie selbst ein weiteres Versprechen setzen, das die Antwort mit Hilfe der Methode map in ein Ergebnis umwandelt. Wenn Sie der Play-Dokumentation folgen, sieht das etwas verwirrend aus, da Java (noch) keine Closures hat und alles in einer Klasse verpackt werden muss. Sie müssen jedoch keine anonymen Klassen innerhalb des Methodenaufrufs verwenden. Wenn Sie mehr sauberen Code bevorzugen, können Sie es auch tun, wie folgt:

return async( 
    request     
    .get()     // returns a `Promise<Response>` 
    .map(resultFromResponse) // map takes a `Function<Response, Result>` and 
          // returns the `Promise<Result>` we need 
); 

Das Objekt resultFromResponse wie folgt aussehen.Es ist eigentlich wie eine umständliche Definition einer Art Callback-Methode, die ein Response als einziges Argument nimmt und eine Result zurückgibt.

Function<Response, List<T>> resultFromResponse = 
    new Function<Response /* 1st parameter type */, Result /* return type */>() { 
     @Override 
     public Result apply(Response response) { 
      // example: read some json from the response 
      String message = response.asJson().get("message"); 
      Result result = ok(message); 
      return result; 
     } 
    }; 

Wie @itsjeyd wies in den Kommentaren aus, wenn calling webservices in Play 2.2.x Sie den Anruf nicht in async mehr wickeln. Sie einfach Rückkehr der Promise<Result>:

public static Promise<Result> index() { 
    return request.get().map(resultFromResponse); 
} 
+1

Vielen Dank für die eingehende Antwort, obwohl das meiste davon auf der Play-Seite verfügbar ist, haben Sie es geschafft, allot der Verwirrung aufzulösen. Ich werde es versuchen. – Hegemon

+1

+1 für eine gute Antwort. @Hegemon, da du möchtest, dass dies eine "Wissensbasis" wird, möchte ich das zum Spiel hinzufügen! 2.2.x, die Rückgabe 'Ergebnis's über' async' ist veraltet; Aktionen, die Anrufe zu anderen Webdiensten tätigen, sollten statt dessen eine "Promise " zurückgeben. Dies kann erreicht werden, indem die obige Anweisung return in request request.get() geändert wird. Map (resultFromResponse); – itsjeyd