Przechwytuję wszystkie żądania do mojej aplikacji odtwarzania, zastępując metodę GlobalSettings onRouteRequest. Teraz muszę wysłać dane do wysłanej akcji, aby nie wykonywać tych wszystkich obliczeń we wszystkich działaniach. Jak ustawić atrybut dla obiektu request (play.api.mvc.RequestHeader), który przekazuję do metody super onRouteRequest?Jak przekazać zmienną do działania z przechwyconego żądania w PlayFramework?
Odpowiedz
Dla twoich potrzeb nie będę używał funkcji onRouteRequest
(przynajmniej elegancko).
Ale spróbujmy użyć specjalnej struktury do przechwycenia.
Oto w jaki sposób można przechwycić żądania, oblicz rodzajowe rzeczy i przekazać go do działania
Przede wszystkim tutaj jest Interceptor
obiekt, który ma metodę intercept
i wygodny sposób 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"))
}
Jak widać, funkcja pracownika intercept
daje możliwość obliczenia niektórych rzeczy na podstawie treści żądania. Który wynik obliczeń typu B
może się nie udać (Option
), w takim przypadku przewodnik będzie mógł powiedzieć, co zrobić.
uwzględniając określić co do obliczenia, można zdefiniować action
stosując funkcję, która pobiera B
i daje Action[A]
.
Metoda jest tylko prostym predefiniowanym przechwytywaczem, który umożliwia nam zdefiniowanie sposobu pobierania zalogowanej nazwy użytkownika, aby zilustrować.
Teraz tutaj jest to, jak możemy korzystać zarówno z nich w swojej 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))
}
}
Teraz, jeśli masz ogólne obliczenia można utworzyć wstępnie skonfigurowaną przechwytujących (tu używam klasę przypadku, ale po prostu wyznaczającą funkcja, która częściowo stosuje interceptor
wystarczy)
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 związane z komentarzem:
Odpowiednio do Twojego komentarza, oto jak można to zrobić za pomocą przechwytywania (zauważ, że mam wyśmiewali się na pobieranie hosta i sprawdzania)
Korzystanie hosted
i anotherHosted
, będziesz mógł przetestować ten obieg:
- = myhost => 404, ponieważ na pierwszy myhost nie są buforowane i pod warunkiem fałszywe sprawdzanego makieta
- /gospodarzem/host prawda? = myhost => nie w pamięci podręcznej, ale to będzie dodaj, a następnie nie 404
- /hosted/anotherHosted/false? host = myhost => w pamięci podręcznej, ponieważ jest hostowany => nie 404
- /hosted/anotherHosted/false?host = notMyhost => 404
Oto kod
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)
}
}
Dzięki Andy, Pozwól, że ci powiem dokładny scenariusz, buduję hostowaną aplikację, do której użytkownicy mogą się zarejestrować i mapować swoją domenę. Kiedy ich użytkownicy/klienci trafiają na zmapowaną domenę, najpierw sprawdza, czy domena jest hostowana przez nas, czy też zwraca błąd 404. Jeśli domena jest hostowana, chcę przekazać informacje o witrynie wszystkim działaniom, aby nie pobierać jej ponownie. – Aman
- 1. Jak przekazać zmienną z settings.py do widoku?
- 2. jak przekazać zmienną z redirect_to?
- 3. Jak przekazać argumentu do działania w UIGestureRecognizer initWithTarget działania
- 4. Jak przekazać żądanie z serwletu do działania struts2?
- 5. Jak przekazać zmienną do $ scope w $ routeProvider
- 6. Jak przekazać tablicę obiektów do działania?
- 7. Jak przekazać dane z BroadcastReceiver do uruchamianego działania?
- 8. ansibl: przekazać zmienną do obsługi
- 9. przekazać zmienną z ajax do php
- 10. asp.net przekazać zmienną z kodu do .aspx
- 11. PHP - Jak przekazać zmienną globalną do funkcji
- 12. Jak przekazać zmienną AngularJS do Javascript?
- 13. Jak przekazać zmienną z bloku do phtml w magento
- 14. jak przekazać zmienną argument do exe?
- 15. Jak przekazać zmienną do SelectCommand SqlDataSource?
- 16. Jak przekazać zmienną niestandardową do koszyka?
- 17. Jak mogę przekazać zmienną R do sqldf?
- 18. jak przekazać zmienną do funkcji Cache :: pamiętać
- 19. angularjs przekazać zmienną do fabryki
- 20. Jak przekazać zmienną do klauzuli IN?
- 21. Jak przekazać zmienną Bash do Pythona?
- 22. Jak przekazać treść żądania do kontekstu GraphQL?
- 23. Jak przekazać wartość postępu z wątku do działania?
- 24. Przekierowanie do działania i trzeba przekazać dane
- 25. Jak przekazać nazwę kolumny jako parametr do działania w dplyr?
- 26. Jak przekazać zmienną z pliku szablonu jade do pliku skryptu?
- 27. jak przekazać zmienną do następnej strony z ciasteczkami
- 28. Jak przekazać zmienną z jednej domeny do innej aplikacji
- 29. Jak przekazać zmienną z kontrolera do MVC widok joomla
- 30. MVC przekazać identyfikatory oddzielone przez „+” do działania
Ustawienie atrybutu nie jest dostępna, ponieważ w funkcjonalny, jesteśmy w niezmiennej środowiska. Tak więc, na przykład dodając rzeczy do sesji, tworzysz "nowy" z 'withSession'. A w kontekście onRouteRequest nie można utworzyć nowego żądania, ponieważ nie będzie możliwe przekazanie tego nowego do podstawowej akcji –
+100, ta sama łódź, aby fragment danych został wstawiony do Żądania, które dotyczy WSZYSTKICH tras/akcji -types. Chciałbym wykonać obliczenia danych w jednym miejscu, onRouteRequest, a następnie w dowolnym miejscu aplikacji, w której niejawne żądanie jest w zakresie, mieć dostęp do danych (w odróżnieniu od ponownego obliczania w różnych miejscach lub dodawanie tablicy dla każdego działania, aby sobie z tym poradzić). – virtualeyes
@ andypetrella scala nie jest czysto funkcjonalna. Możemy wstrzykiwać dane do kompozycji Request via Action i WrappedRequest, skutecznie modyfikując zapytanie po trasie. Chciałbym bardzo miło zapełnić mapę zastępczą [String, String], aby ustawić w onRouteRequest. Możesz skopiować żądanie i, na przykład, podać wartość do "znaczników" Map na RequestHeader. Zagraj oczywiście, zdmuchnij swoje cenne dane, używając znaczników Mapa dla wyników trasowania (metoda kontrolera, typ GET, itp.) – virtualeyes