2012-06-10 18 views
6

मैं ग्लोबल सेटिंग्स के रूटआउट प्रोवेस्ट विधि पर ओवरराइड करके अपने प्ले एप्लिकेशन के सभी अनुरोधों को रोक रहा हूं। अब, मुझे यहां से प्रेषित कार्रवाई में कुछ डेटा भेजने की आवश्यकता है ताकि मैं उन सभी गणनाओं को सभी कार्यों में न कर सकूं। मैं अनुरोध (play.api.mvc.RequestHeader) ऑब्जेक्ट में एक विशेषता कैसे सेट करूं जो मैं सुपर ऑन रूट रूट प्रक्रिया में पास करता हूं?PlayFramework में एक अवरुद्ध अनुरोध से एक चर को एक चर में कैसे पास किया जाए?

+0

एक विशेषता की स्थापना है, क्योंकि कार्यात्मक में उपलब्ध नहीं है, हम एक अपरिवर्तनीय वातावरण में कर रहे हैं। इसलिए, उदाहरण के लिए सत्र में सामान जोड़ते समय, आप 'सत्र' के साथ "एक नया" बनाते हैं। औरRouteRequest के संदर्भ में आप एक नया अनुरोध नहीं बना सकते हैं क्योंकि आप अपनी अंतर्निहित कार्रवाई –

+0

+100, उसी नाव पर यह नया नहीं दे पाएंगे, अनुरोध में इंजेक्ट करने के लिए डेटा स्निपेट है जो सभी मार्गों/क्रियाओं पर लागू होता है -types। मैं एक स्थान पर डेटा गणना करना चाहता हूं, रूट रूट पर, और उसके बाद आवेदन में कहीं भी जहां एक निहित अनुरोध गुंजाइश है, डेटा तक पहुंच है (बनाम पुन: एफ-आईएनजी विभिन्न स्थानों पर इसे कैलकिंग कर रहा है या इसे संभालने के लिए हर क्रिया के लिए बॉयलरप्लेट जोड़ना)। – virtualeyes

+0

@andypetrella scala पूरी तरह कार्यात्मक नहीं है। हम कार्रवाई संरचना और WrappedRequest के माध्यम से अनुरोध में डेटा इंजेक्ट कर सकते हैं, प्रभावी रूप से अनुरोध पोस्ट-रूट को संशोधित कर सकते हैं। मैं रूटआउट रिवेस्ट में सेट करने के लिए प्लेसहोल्डर मानचित्र [स्ट्रिंग, स्ट्रिंग] से बहुत प्यार करता हूं। आप अनुरोध की प्रतिलिपि बना सकते हैं और, उदाहरण के लिए RequestHeader पर "टैग" मानचित्र का मान दें। निश्चित रूप से, रूटिंग परिणामों के लिए टैग मैप का उपयोग करके अपने मूल्यवान डेटा को उड़ाएं (नियंत्रक विधि, प्रकार प्राप्त करें, आदि) – virtualeyes

उत्तर

2

आपकी ज़रूरत के लिए मुझे onRouteRequest का उपयोग करने की कोई बात नहीं है (कम से कम खूबसूरती से)।

लेकिन आइए अवरुद्ध करने के लिए समर्पित संरचना का उपयोग करने का प्रयास करें।

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")) 

} 
:

का तरीका यहां बताया, अनुरोध रोकना कुछ सामान्य सामान की गणना और यह कार्रवाई

सबसे पहले करने के लिए पारित कर सकता है, यहाँ एक Interceptor वस्तु एक विधि intercept और एक सुविधाजनक तरीका username है कि

जैसा कि आप देख सकते हैं, कार्यकर्ता intercept फ़ंक्शन फ़ंक्शन अनुरोध सामग्री के आधार पर कुछ सामानों की गणना करने का अवसर देता है। B प्रकार का कौन सा गणना परिणाम विफल हो सकता है (Option), उस स्थिति में एक हैंडलर यह बताने के लिए है कि क्या करना है।

गणना करने के लिए परिभाषित करने के बाद, आप पर एक फ़ंक्शन का उपयोग करके अपने action को परिभाषित कर सकते हैं और Action[A] देता है।

username विधि केवल एक साधारण पूर्वनिर्धारित इंटरसेप्टर है जो हमें यह निर्धारित करने में सक्षम बनाता है कि लॉग इन उपयोगकर्ता नाम को कैसे पुनर्प्राप्त किया जाए, बस उदाहरण के लिए।

अब यहाँ हम कैसे उन दोनों को अपने 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)) 
    } 
    } 

में अब अगर आप एक सामान्य गणना है यहाँ का उपयोग आप अपने पहले से कॉन्फ़िगर इंटरसेप्टर बना सकते हैं कर सकते हैं (मैं एक मामले वर्ग का उपयोग कर रहा हूँ, लेकिन बस एक निर्णायक है समारोह है कि आंशिक रूप से लागू होता है interceptor पर्याप्त है)

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) 
    } 
    } 

संपादित टिप्पणी से संबंधित:

तदनुसार अपनी टिप्पणी के लिए, आपके द्वारा एक इंटरसेप्टर (ध्यान दें कि मैं मेजबान पुनर्प्राप्ति मज़ाक उड़ाया गया है और जाँच)

hosted और anotherHosted का उपयोग का उपयोग कर, आप में सक्षम हो जाएगा इस कार्यप्रवाह परीक्षण करने के लिए कर सकता है है:

  • /की मेजबानी/गलत? मेजबान = myhost => 404 क्योंकि पहली myhost पर कैश नहीं है और मैं जाँच की mockup को झूठा प्रदान की
  • /मेजबानी/सच? मेजबान = myhost = संचय में नहीं है, लेकिन यह होगा> इसे जोड़ें, और फिर कोई 404
  • /होस्टेड/अन्य होस्टेड/झूठा? होस्ट = myhost => कैश में क्योंकि यह होस्ट किया गया है => नहीं 404
  • /होस्टेड/दूसराहोस्टेड/झूठा?होस्ट = notMyhost => 404

यहाँ कोड

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) 
    } 
} 
+0

से निकाला गया डेटा/धन्यवाद एंडी, मैं आपको बताता हूं सटीक परिदृश्य, मैं एक होस्टेड एप्लिकेशन बना रहा हूं जो उपयोगकर्ता अपने डोमेन के लिए साइन अप और मानचित्र कर सकते हैं। जब उनके उपयोगकर्ता/ग्राहक अपने मैप किए गए डोमेन को हिट करते हैं, तो यह पहले जांचता है कि डोमेन हमारे द्वारा होस्ट किया गया है या नहीं, या फिर 404 त्रुटि लौटाएं। यदि डोमेन होस्ट किया गया है, तो मैं साइट की जानकारी को सभी कार्यों पर भेजना चाहता हूं, ताकि मैं इसे फिर से प्राप्त न कर सकूं। – Aman

संबंधित मुद्दे