Ich halte alle Anfragen an meine Play-Anwendung ab, indem ich die onRouteRequest-Methode von GlobalSettings überschreibe. Jetzt muss ich von hier aus Daten an die gesendete Aktion senden, damit ich nicht all diese Berechnungen in allen Aktionen ausführen kann. Wie setze ich ein Attribut auf das Anfrageobjekt (play.api.mvc.RequestHeader), das ich an die super onRouteRequest-Methode übergebe?Wie wird eine Variable an eine Aktion von einer abgefangenen Anfrage in PlayFramework übergeben?
Antwort
Für Ihre Notwendigkeit, ich ding nicht mit der onRouteRequest
wird funktionieren (elegant zumindest).
Aber versuchen wir, eine dedizierte Struktur zum Abfangen zu verwenden.
Hier ist, wie Sie die Anforderung abfangen könnte, einige generische Sachen berechnen und übergeben es an Aktion
Zunächst einmal ist hier ein Interceptor
Objekt, das ein Verfahren intercept
und eine bequeme Methode hat username
:
object Interceptor {
def intercept[A, B](f: RequestHeader => Option[B], e: RequestHeader => Result)(action: B => Action[A]): Action[(Action[A], A)] = {
val bodyParser = BodyParser {
request =>
f(request) map {
b =>
val innerAction = action(b)
innerAction.parser(request).mapDone {
body => body.right.map(innerBody => (innerAction, innerBody))
}
} getOrElse {
Done(Left(e(request)), Input.Empty)
}
}
Action(bodyParser) {
request =>
val (innerAction, innerBody) = request.body
innerAction(request.map(_ => innerBody))
}
}
def username[A](check: RequestHeader => Option[String]): ((String) => Action[A]) => Action[(Action[A], A)] = intercept(check, r => Results.Unauthorized("not logged in"))
}
Wie Sie sehen können, gibt Ihnen die Worker-Funktion intercept
die Möglichkeit, basierend auf dem Inhalt der Anfrage einige Dinge zu berechnen. Welches Berechnungsergebnis vom Typ B
fehlgeschlagen ist (Option
), in diesem Fall ist ein Handler da, um zu sagen, was zu tun ist.
Nachdem definiert was zu berechnen, können Sie Ihre action
mit einer Funktion, die eine B
und gibt eine Action[A]
.
Die Methode username
ist nur ein einfacher vordefinierter Interceptor, mit dem wir festlegen können, wie der angemeldete Benutzername abgerufen werden soll, um dies zu verdeutlichen.
Hier ist, wie wir beide in Ihrem Controller
//index is defined for both GET and POST in routes, but fails on POST
// thanks to the interceptor that checks at first the used method
// the case mustn't be handled in the Action definition
def index = Interceptor.intercept(
/*check the method*/
request => if (request.method == "GET") Some(request.method) else None,
/*not a GET => bad request*/
request => BadRequest(request.method + " not allowed")
) { /*the computation result*/method => Action {
Ok("The method : " + method)
}
}
//this controller retrieve the username in the session and renders it in a OK response
def secured = Interceptor.username(r => r.session.get("username")) { username => Action {
Ok("You're logged in as " + username)
}
}
//this enables you to logged in => store in session
def login(u:String) = Action { request => {
Ok("Logged in as " + u) withSession(("username" -> u))
}
}
Jetzt verwenden können, wenn Sie eine allgemeine Berechnung haben, können Sie Ihre vorkonfigurierte Interceptor erstellen (hier habe ich einen Fall, Klasse bin mit aber nur ein bestimmendes Funktion, die die interceptor
gilt teilweise genügt)
case class Intercept[B] (f: RequestHeader => Option[B], e: RequestHeader => Result) {
def apply[A](action: B => Action[A]) = Interceptor.intercept[A,B](f, e)(action)
}
val getInterceptor = Intercept[String](
request => if (request.method == "GET") Some(request.method) else None,
request => BadRequest(request.method + " not allowed")
)
def index2 = getInterceptor { method => Action {
Ok("Da method : " + method)
}
}
EDIT auf den Kommentar bezogen werden:
entsprechend Ihren Kommentar, hier ist, wie Sie ein Interceptor mit tun könnte (man beachte, dass ich den Host-Abruf und Überprüfung verspottet)
Mit hosted
und anotherHosted
, Sie werden in der Lage sein, diesen Workflow zu testen:
- /hosted/falsch? host = myhost => 404, weil auf den ersten myhost nicht zwischengespeichert und ich zur Verfügung gestellt falsch auf die geprüft Mockup
- /hosted/true? host = myhost => nicht im Cache, aber es wird fügen Sie es hinzu, und dann keine 404
- /gehostet/anotherHosted/false? Host = myhost => im Cache, weil es ist gehostet => nein 404
- /gehostet/anotherHosted/false?host = notMyhost => 404
Hier ist der Code
def getHost(request:RequestHeader) = request.queryString.get("host").get.head
def checkHost(host:String, b: Boolean) = b
val checkHosted = (b: Boolean) => Intercept[String](
request => {
val host = getHost(request)
Cache.getAs[String](host) match {
case [email protected](_) => x
case None => if (checkHost(host, b)) {
Cache.set(host, host)
Some(host)
} else None
}
},
request => NotFound(getHost(request) + "not hosted")
)
def hosted(b:String) = checkHosted(b.toBoolean) {
host => Action {
Ok("this host is ok : " + host)
}
}
def anotherHosted(b:String) = checkHosted(b.toBoolean) {
host => Action {
Ok("this host is ok : " + host)
}
}
Danke Andy, lassen Sie mich Ihnen sagen Im exakten Szenario erstelle ich eine gehostete Anwendung, für die sich Benutzer anmelden und ihre Domäne zuordnen können. Wenn ihre Benutzer/Kunden ihre zugeordnete Domäne erreichen, überprüft sie zunächst, ob die Domäne von uns gehostet wird, oder geben einen 404-Fehler zurück. Wenn die Domain gehostet wird, möchte ich die Site-Informationen an alle Aktionen weitergeben, damit ich sie nicht erneut in ihnen abrufe. – Aman
- 1. Wie eine Variable an $ scope übergeben wird in $ routeProvider
- 2. wie eine Variable an eine UIButton Aktion passiert
- 3. Übergeben einer Redux-Aktion an eine untergeordnete Komponente mit Requisiten
- 4. Anfrage an eine andere MVC Aktion innerhalb einer Aktions
- 5. Eine Bash-Variable an Git-Formatierer übergeben
- 6. Wie übergebe ich eine Variable von einem ActionFilter an eine Controller-Aktion in C# MVC?
- 7. Wie kann ich hier eine Variable an eine Funktion übergeben?
- 8. So übergeben Sie eine Sammlung/Array-Parameter an eine Aktion
- 9. PlayFramework-Anfrage an Google Places API
- 10. Eine Variable an eine Funktion übergeben (Scope-Problem)
- 11. Eine Variable an PhantomJS über exec übergeben
- 12. Wie kann ich eine Variable von einer Funktion an eine andere übergeben?
- 13. Eine JavaScript-Variable an eine JavaScript-Funktion übergeben?
- 14. Übergeben einer lokalen Variablen von einer Funktion an eine andere
- 15. jQuery - Variable innerhalb einer Funktion an eine andere Funktion übergeben
- 16. Wie man eine zusätzliche Variable an Listview in yii2 übergeben
- 17. Wie füge ich eine Aktion an eine UIPicker-Änderung an?
- 18. Wie wird die Variable von app.js an routes/index.js übergeben?
- 19. JavaScript: Übergeben Sie eine Variable von einer Funktion an eine andere mit setInterval()?
- 20. Übergeben Sie eine Variable an eine Dockerfile von einer docker-compose.yml-Datei
- 21. Übergeben einer Abfragezeichenfolge an eine Anfrage als eine tatsächliche Zeichenfolge mit Knoten und Express
- 22. Wie wird eine Anfrage an eine Route gesendet und Informationen von einer API abgerufen?
- 23. So übergeben Sie eine Variable von Twig an JavaScript
- 24. Wie eine Django-Variable von HTML-Seite an Javascript übergeben wird
- 25. Übergeben von Parametern an die Selektor-Aktion
- 26. Wie wird ein Ereignis an eine Javascript-Methode übergeben?
- 27. Übergeben Sie eine Variable an JQuery UI-Dialogfeld
- 28. Wie kann ich eine variable Anzahl von Argumenten an Methode2 von Methode1 übergeben, die eine variable Anzahl von Argumenten akzeptiert?
- 29. Wie man JavaScript-Variable an eine JSP-Methode übergeben?
- 30. R: Wie Standard-Argument an eine Funktion übergeben wird?
ein Attribut einstellen, weil in der funktionellen nicht verfügbar ist, sind wir in einer unveränderlichen Umgebung. Wenn Sie beispielsweise Sachen zu der Sitzung hinzufügen, erstellen Sie mit "withSession" eine "neue". Und im Kontext von onRouteRequest können Sie keine neue Anfrage erstellen, weil Sie nicht in der Lage sein werden, Ihrer zugrundeliegenden Aktion –
+100, demselben Boot, ein Datenschnipsel zu geben, das in die Anfrage eingefügt wird, die für ALLE Routen/Aktionen gilt -Typen. Ich würde gerne die Datenberechnung an einem Ort machen, onRouteRequest, und dann irgendwo in der Anwendung, wo eine implizite Anfrage im Umfang ist, Zugriff auf die Daten haben (im Gegensatz zu re-f-ing es an verschiedenen Orten oder Hinzufügen von Boilerplate für jede Aktion, um es zu handhaben). – virtualeyes
@andypetrella scala ist nicht rein funktional. Wir können Daten in die Komposition "Anfrage über Aktion" und "WrappedRequest" einfügen, wodurch die Post-Route der Anforderung effektiv geändert wird. Ich würde liebend gerne eine Platzhalter Map [String, String] in onRouteRequest setzen. Sie können die Anfrage kopieren und beispielsweise der Karte "Tags" auf dem RequestHeader einen Wert zuweisen. Spielen Sie natürlich, bläst Ihre wertvollen Daten weg, verwenden Sie die Tags Map für Routing-Ergebnisse (Controller-Methode, Typ GET, etc.) – virtualeyes