2009-07-28 5 views
2

Mit Feder DefaultAnnotationHandlerMapping wie kann ich den Controller-Lookup, die eine bestimmte URL letztlich umgehen würde.Wie Sie feststellen, Controller für bestimmte URL (Feder)

Ich habe dies zur Zeit, aber fühlt sich an wie es sollte eine sauberere Art und Weise sein, als über 100s Anfrage Mappings Iterieren:

public static Object getControllerForAction(String actionURL) { 
    ApplicationContext context = getApplicationContext(); 
    AnnotationHandlerMapping mapping = (AnnotationHandlerMapping) context.getBean("annotationMapper"); 
    PathMatcher pathMatcher = mapping.getPathMatcher(); 
    for (Object key: mapping.getHandlerMap().keySet()) { 
     if (pathMatcher.match((String) key, actionURL)){ 
      return mapping.getHandlerMap().get(key); 
     } 
    } 
    return null; 
} 
+0

Ich bin neugierig, warum Sie das herausfinden müssten ..? –

+0

Ich habe ein JSP-Tag, das eine URL-Zeichenfolge aufnimmt, und ich möchte das Tag-Ergebnis basierend auf einigen benutzerdefinierten Anmerkungen im zugeordneten Controller anzeigen oder ausblenden. –

Antwort

2

Für die Zwecke dieser Frage sind alle interessanten Methoden in DefaultAnnotationHandlerMapping und seine Oberklassen geschützt und so für externen Code nicht sichtbar. Es wäre jedoch trivial, eine benutzerdefinierte Unterklasse von DefaultAnnotationHandlerMapping zu schreiben, die diese Methoden überschreibt und sie zu public macht.

Da Sie in der Lage sein, einen Pfad anstelle eines Anfrageobjekts zu liefern, würde ich vorschlagen, lookupHandler von AbstractUrlHandlerMapping wäre ein guter Kandidat dafür. Sie müssen es immer noch mit einem Anforderungsobjekt und dem Pfad versehen, aber dieses Anforderungsobjekt wird nur für die Übergabe an die validateHandler() -Methode verwendet, die nichts tut, sodass Sie dort wahrscheinlich eine Null angeben könnten.

+0

Keine Notwendigkeit für Unterklassen. Wie ich in meiner Antwort gesagt habe, ist getHandler() öffentlich, da es auf der HandlerMapping-Schnittstelle deklariert ist. Es gibt 'HandlerExecutionChain' zurück, aber es ist einfach auszupacken. – ChssPly76

+0

Wie das OP betont, ist getHandler() für seine Bedürfnisse nicht geeignet. Ich habe meine Antwort geändert, um zu empfangen. – skaffman

+0

Um fair zu sein, hat er das nach unseren beiden Antworten darauf hingewiesen :-) validateHandler() wird jedenfalls in 'DefaultAnnotationHandlerMapping' überschrieben und eine Anfrage als null übergeben, ist KEINE Option, weil sie dort sehr oft verwendet wird. – ChssPly76

1

Alle Mapper HandlerMapping-Schnittstelle implementieren, die eine getHandler() Methode hat:

ApplicationContext context = getApplicationContext(); 
AnnotationHandlerMapping mapping = (AnnotationHandlerMapping) context.getBean("annotationMapper"); 
Object controller = mapping.getHandler().getHandler(); 
HandlerExecutionChain

HandlerMapping.getHandler() zurückgibt, ruft getHandler() auf das würde zurückkehren Sie den tatsächlichen Handler, der - für Controller-Mapper - wäre der Controller Sie suchen zum.

+1

Das Problem mit HandlerMapping.getHandler (javax.servlet.http.HttpServletRequest HttpServletRequest) ist, dass es in einer Anfrage dauert und ich brauche eine Situation zu behandeln, bevor sie für die URL der Anforderung (in einem jsp-Tag) erstellt wird. –

+0

Gut genug, obwohl Sie das in Ihrer Frage nicht gesagt haben. In diesem Fall würde ich entweder mit der Art und Weise gehen, wie Sie es jetzt haben, oder sich den Vorschlag von ** skaffman ** ansehen, aber beachten Sie mögliche Probleme mit dem NULL-Anfrageobjekt – ChssPly76

1

Oben funktioniert nicht im Frühling 3.1. Sie können stattdessen Folgendes tun.

Map<String, AbstractHandlerMethodMapping> map = WebApplicationContextUtils.getWebApplicationContext(servletContext).getBeansOfType(AbstractHandlerMethodMapping.class); 
Iterator<AbstractHandlerMethodMapping> iter = map.values().iterator(); 
while (iter.hasNext()) { 
    AbstractHandlerMethodMapping ahmb = iter.next(); 
    Iterator<Object> urls = ahmb.getHandlerMethods().keySet().iterator(); 
    while (urls.hasNext()) { 
     Object url = urls.next(); 
     logger.error("URL mapped: " + url); 
    }   
}