2014-01-29 4 views
10

Ich habe folgende Play (Scala) Code:Get Response Körper aus play.api.mvc.Action [anycontent] im Play-Framework (Scala)

object Experiment extends Controller { 

//routes file directs /genki here 
def genki(name: String) = Action(pipeline(name)) 

def pipeline(name: String) = { 
    req:play.api.mvc.RequestHeader => { 
     val template = views.html.genki(name) 
     Experiment.Status(200).apply(template).as("text/html") 
    } 
} 

def simple = Action { 
    SimpleResult(
     header = ResponseHeader(200, Map(CONTENT_TYPE -> "text/plain")), 
     body = Enumerator("Hello World!".getBytes()) 
    ) 
} 

} 

Dies kompiliert fein und funktioniert wie erwartet.

Wie benutze ich die scala REPL, um den tatsächlichen HTML-Code anzuzeigen?

ich habe:

scala> val action = simple 
action: play.api.mvc.Action[play.api.mvc.AnyContent] = Action(parser=BodyParser(anyContent))  

, die ich, dass jetzt der Referenzwert ‚Aktion‘ in der REPL bedeuten, um ein Action-Objekt, das für anycontent typ eingeschränkt ist (ist das richtig so, wie es zu sagen?).

Wie kann ich jetzt diese Aktion verwenden, um den HTTP-Antwort-HTML-Inhalt auszudrucken?

Vielen Dank

+0

Es tut mir leid, aber die Frage ist mir unklar. Sie möchten die endgültige HTML-Antwort auf repl ausdrucken? – Jatin

Antwort

2

Action keinen Inhalt, da es ein Objekt ist, dass Sie ein Request anwenden können und ein Ergebnis zu bekommen.

val request: Request[A] = ... // create a request instance 
val resultFuture: Future[SimpleResult] = simple(request) 

val bodyAsBytes: Array[Byte] = Await.result(Await.result(resultFuture, timeout.duration).body |>>> Iteratee.consume[Array[Byte]](), timeout.duration) 

Beachten Sie, dass für Ihr Beispiel eine leere Anfrage ausreicht, da Sie sie nicht verwenden.

Beachten Sie auch, dass body von SimpleResult ist ein Enumerator, benötigen Sie einen Iteratee, um es anzuwenden, hier bin Anwendung ich nur ein Verbraucher die ganze Liste zu bekommen. Die 2 Await.result verwendet:

  1. für die Future[SimpleResult] zu warten, bis die Enumerator bis vollständig
  2. warten Daten an die Iteratee zu tun zu senden.
+0

danke, wie instanziiere ich ein neues Request [A] -Objekt, und was ist das [A]? Ich denke, das ist eine Klassenbeschränkung, aber ich bekomme das 'A' nicht. Viel meiner Unklarheit mit Scala ist nicht zu wissen, wenn wir im OO-Modus oder FP-Modus sind! – Zuriar

+0

Das 'A' ist, was Sie wollen, es ist ein Typparameter, der dem Typkonstruktor zur Verfügung gestellt wird, um einen konkreten Typ zu erstellen. Für Ihr Beispiel können Sie sich 'play.api.test ansehen.FakeRequest', wird von Play zur Verfügung gestellt! um Unit-Tests zu erleichtern. – vptheron

+0

danke, ich habe bemerkt, dass es ein play.api.test.FakeRequest in den api docs gab, aber ich kann es nicht auf dem repl oder in meinem Code importieren, was bedeutet, dass es nicht mit der standard play distro ausgeliefert wird. – Zuriar

6

Anstatt das manuelle Ergebnis Extraktion vptheron beschreibt, können Sie play.api.test.Helpers verwenden:

import play.api.test.Helpers._ 
val result: Future[SimpleResult] = … 
val bodyAsBytes: Array[Byte] = contentAsBytes(result) 

Es gibt auch contentAsString usw.

6

Aufbauend auf den answer by Huw, hier ist der volle Arbeitscode:

import play.api.test._ 
def getStringFromAction(action:Action[AnyContent]):String = { 
    val request = new FakeRequest("fakeMethod", "fakeUrl", new FakeHeaders, "fakeBody") 
    val result = action.apply(request).run 
    import scala.concurrent.duration._ 
    Helpers.contentAsString(result)(1000 millis) 
} 

Sie müssen die folgenden Bibliotheken einschließen (Standardmäßig nicht im Play enthalten): play-test_2.11.jar, selenium-java.jar, selenium-api.jar, selenium-chrome-driver.jar, selenium-firefox-driver.jar, selenium-remote-driver.jar, selenium-htmlunit-driver.jar, fluentlenium-core.jar, htmlunit-core-js.jar und htmlunit.jar. Diese sind in der Play- oder Activator-Distribution verfügbar. Sie können auch eine Abhängigkeit in build.sbt als explained here hinzufügen.

+0

Es funktioniert für mich – code4j

+1

@ Jus12 Wissen Sie, wie Sie Ihre Antwort mit Play 2.5 arbeiten lassen? FakeRequest ist weg, ersetzt durch RequestBuilder, und der obige Code will nun auch einen Akka Materializer. Seit dem Upgrade auf 2.5 wird der obige Code nicht mehr kompiliert. – gknauth

Verwandte Themen