2013-07-23 14 views
9

Próbuję napisać filtr podobny do prostego opisanego w http://www.playframework.com/documentation/2.1.1/ScalaHttpFilters, ale muszę uzyskać dostęp do treści żądania. Poniższa dokumentacja stwierdza, że ​​"kiedy przywołamy następną, otrzymamy z powrotem Iteratee.Możesz zawinąć to w Enumeratee, aby zrobić transformacje, jeśli chcesz." Próbuję dowiedzieć się, jak owinąć Iteratee, aby uzyskać treść żądania jako ciąg w filtrze, więc mogę to również zarejestrować.Scala odgrywa http filtry: jak znaleźć ciało żądania

+0

Nie jestem pewien, czy rozumiem problem, ale jeśli masz prośbę, to uzyskanie ciała jest po prostu request.body ... – Jakob

+0

Mam tylko nagłówek żądania, jak Julien stwierdził poniżej – Nonos

+0

czy to działa? Jestem też ciekawy, jak to zrobić. – Setheron

Odpowiedz

1

Spędziłem trochę czasu na tym. Nie jestem ekspertem od Scali, ale działa to całkiem nieźle! :)

object AccessLog extends EssentialFilter { 
    def apply(nextFilter: EssentialAction) = new EssentialAction { 
    def apply(requestHeader: RequestHeader) = { 
     val startTime = System.currentTimeMillis 

     nextFilter(requestHeader).map { result => 
     val endTime = System.currentTimeMillis 
     val requestTime = endTime - startTime 

     val bytesToString: Enumeratee[ Array[Byte], String ] = Enumeratee.map[Array[Byte]]{ bytes => new String(bytes) } 
     val consume: Iteratee[String,String] = Iteratee.consume[String]()  
     val resultBody : Future[String] = result.body |>>> bytesToString &>> consume 

     resultBody.map { 
      body => 
      Logger.info(s"${requestHeader.method} ${requestHeader.uri}" + 
      s" took ${requestTime}ms and returned ${result.header.status}") 
      val jsonBody = Json.parse(body) 
      Logger.debug(s"Response\nHeader:\n${result.header.headers.toString}\nBody:\n${Json.prettyPrint(jsonBody)}") 
     } 

     result.withHeaders("Request-Time" -> requestTime.toString) 

     } 
    } 
    } 

Wynik końcowy wydrukuje ciało jako ciąg JSON (wydrukowany dość pięknie).

+0

W Play 2.1.x ciało wartości nie jest członkiem play.api.mvc.Result –

+0

Jestem w Play 2.2x http://www.playframework.com/documentation/2.2. x/api/scala/index.html # play.api.mvc.SimpleResult – Setheron

+13

Przykro mi, ale to drukuje treść odpowiedzi na żądanie, a nie treść żądania –

-2

W metodzie kontrolera, który kieruje do działania, wystarczy zadzwonić

Map<String, String[]> params = request().queryString(); 

To będzie Ci mapę parametrów, gdzie można następnie zadzwonić

params.get("someParam")[0] 

uzyskać param (jeśli jest to pojedyncza wartość). Jeśli parametr jest listą, zignoruj ​​indeksowanie i to zwróci tablicę.

+0

Dzięki za odpowiedź, ale próbuję uzyskać dostęp do parametry w filtrze globalnym dla wszystkich żądań (wszystkie kontrolery i akcje ..etc), więc to nie zadziała. – Nonos

6

Pierwszą rzeczą, którą musisz wiedzieć, kiedy filtr jest wywoływany, treść żądania nie jest jeszcze przeanalizowana. Dlatego daje ci RequestHeader. Musisz znaleźć typ ciała i odpowiednio wywołać odpowiedni parser ciała.

Możesz znaleźć przykład analizowania treści w filtrze CSRF (może wyszukiwać tokeny CSRF w pierwszych bajtach treści żądania).

Zobacz: https://github.com/playframework/playframework/blob/master/framework/src/play-filters-helpers/src/main/scala/csrf.scala#L221-L233.

Mam nadzieję, że to pomaga.

+0

Wydaje się to bardzo pomocne. Muszę tylko przekonwertować treść na ciąg znaków w celu rejestrowania. Moja aplikacja zajmuje się głównie żądaniami GET lub POST z treścią JSON. – Nonos

+3

Link do pliku źródłowego jest zepsuty –

Powiązane problemy