2016-04-18 4 views
0

würde Ich mag eine benutzerdefinierte Aktion erstellen, die den Textvorschlag des Schreibens Aktionen wie diese wegnimmt:Wiedergabe Aktion Composition - hartzucodieren parametrisierte Parser

Action[MyClass](BodyParsers.parse.json[MyClass]) { req => ... 

Allerdings habe ich immer laufen in Klassendefinition Fehler. Hier ist meine erfolgreichste Versuch gewesen:

class JsonAction[A: Reads] extends ActionBuilder[Request] { 
    def hardcodedJson[A: Reads](action: Action[A]) = 
    Action.async(BodyParsers.parse.json[A]) { request => action(request) } 

    def invokeBlock[A: Reads](request: Request[A], block: (Request[A]) => Future[Result]) = { 
    block(request) 
    } 
    override def composeAction[A: Reads](action: Action[A]) = hardcodedJson(action) 
} 

aber ich bekomme die folgende Fehlermeldung: method composeAction overrides nothing.

Wenn ich composeAction[A: Reads] ändern composeAction[A] es sagt mir, es ist nicht ein Json Serializer für Typ A.

Gibt es eine andere Möglichkeit, diese benutzerdefinierte Aktion zu definieren?

Antwort

1

Ja, ich habe versucht, dies mit der offiziellen ActionBuilder Way-of-doing-it zu arbeiten und konnte einfach nicht die Typen zur Aufstellung bringen.

Hier ist etwas, das allerdings für mich gearbeitet:

object JsonActionHelper { 
    def withReads[A](act: Request[A] => Future[Result])(implicit reads:Reads[A]) = 
    Action.async(BodyParsers.parse.json(reads))(act) 
} 

Verwendung in Ihrem Controller (FooJson ist ein object eine implizite Reads[Foo] enthält):

import models.FooJson._ 
import JsonActionHelper._ 

def handleIncomingFoo(fooId:String) = withReads[Foo] { req => 
    val foo:Foo = req.body 
    ... 
    Ok(...) 
} 
1

ActionBuilder nicht generisch ist genug für Ihre Einsatz- Fall; es gibt keinen Platz für Sie in Ihrem Reads[T] übergeben.

Es gibt nichts besonderes über ActionBuilder obwohl. Es ist eine Sammlung von apply und async Factory-Methoden. Sie können Ihren eigenen Aktionstyp mit den von Ihnen benötigten Fabrikmethoden definieren:

object JsonAction { 
    def apply[A : Reads](request: Request[A] => Result) = Action(BodyParsers.parse.json[A])(request) 
} 

// these are equivalent: 
Action[MyClass](BodyParsers.parse.json[MyClass]) { req => ??? } 
JsonAction[MyClass] { req => ??? }