2016-04-21 13 views
1

Ich habe zwei Controller A und B. Ich möchte A create-Methode von B anrufen. Wie mache ich das?Play 2.5.x java - Wie ruft man eine Controller-Methode von einem anderen Controller?

public class A extends Controller { 

    public Result create() { 
     ... 
    } 

} 

public class B extends Controller { 

    public Result create() { 
     // How to call A.create() ?? 
    } 

} 
+0

Nein @Idos, Sie können das nicht tun. Wir sollten die Controller nicht initialisieren, Framework muss das tun. Darüber hinaus, obwohl wir versuchen, können wir Anfrage Parameter an diese Methode übergeben. – prakash

Antwort

2

In Play 2.5, seit DI (Google Guice) eingebaut ist, können wir den gewünschten Controller injizieren und seine Methoden sofort aufrufen!

public class A extends Controller { 

    public Result create(String param) { 
     ... 
    } 

} 

public class B extends Controller { 

    @Inject 
    private A a; 

    public Result create() { 
     a.create("param"); 
     // do other stuff and return result 
    } 

} 
0

Erstellen Sie einfach statische Methode, die die Logik teilt und es verwenden, die Result für beide Aktionen bauen es request() automatisch enthalten, einfachste Beispiel:

public class A extends Controller { 

    public Result create(String param) { 
     return shared("A role", param); 
    } 

    public static Result shared(String role, String param) { 

     String msg = "Path: " + request().path(); 

     msg += ", role is: `" + role + "`"; 

     msg += (param == null) 
       ? " and has no param" 
       : ", with param: " + param; 

     return ok(msg); 
    } 

} 

public class B extends Controller { 

    public Result create() { 
     return controllers.A.shared("B role", null); 
    } 

} 

Über params

Hinweis dass die einzigen Parameter, die Sie in A.create(...) und B.create(...) auflösen müssen, sind die Route Teile (String param in der A Route) oder vielleicht einige optionale Parameter im Beispiel hardcoded role in dem Beispiel.

Andere Dinge, wie request, session, cache, DB-Daten usw. können (sollten) innerhalb des shared() Verfahren extrahiert werden.

TIPP: Wenn die Anzahl der params an die shared() Methode zu übergeben erforderlich ist groß und Sie wollen nicht Monster wie

controllers.A.shared(null, null, null, null, null, null, null, null, "foo"); 

nur erstellen Map<String, Object> Sammlung erstellen und auf einmal passieren oder dedizierte transiente erstellen Modell, das alle Werte in richtigen Feldern enthält. Die zweite Option ist auch mein Favorit, wenn viele Werte an die üblichen Twirl-Vorlagen übergeben werden.

+0

Danke! Aber wie gebe ich die erforderlichen Parameter an diese Controller-Methode weiter? Ich meine, dass die "create()" Methode des "A" Controllers versucht, die Daten von den Anforderungsparametern zu lesen, die unterschiedlich sein können, da der http Aufruf für "B" Controller ist. – prakash

+0

Sie können alles, was Sie wollen, an die gemeinsame Methode übergeben :) check my edit. – biesior

0

Ich glaube, dass Sie eine andere Methode definieren müssen, um Ihre Logik zu enthalten, und rufen Sie dann diese Methode von der Methode Ihres Controllers auf. etwas wie das:

public class SampleController extends Controller{ 
    @BodyParser.Of(BodyParser.Json.class) 
    public Result createMessage(){ 
     JsonNode json = request().body().asJson(); 
     return ok(createMessageLogic(json.get("id").asLong())); 
    } 

    public String createMessageLogic(long id){ 
     return "the id is " + id; 
    } 
} 

Auf diese Weise können Sie einfach Ihren Controller in den anderen Controller injizieren und die Logik-Methoden aufrufen. Sie können jedoch überlegen, eine Service-Schicht neben Ihren Controller-Klassen zu haben, die viel sauberer ist.