2012-12-24 6 views
12

Come ottenere in modo riflessivo l'elenco di tutti i controller (i migliori se non solo annotati, ma anche specificati in xml), corrispondenti ad alcuni URL specifici nell'applicazione Spring MVC?Ottenere in modo riflessivo l'elenco dei controller MVC primaverili che corrispondono all'URL specifico

In caso di annotato solo,

@Autowired 
private ListableBeanFactory listableBeanFactory; 
... 
whatever() { 
    Map<String,Object> beans = listableBeanFactory.getBeansWithAnnotation(RequestMapping.class); 

    // iterate beans and compare RequestMapping.value() annotation parameters 
    // to produce list of matching controllers 
} 

potrebbe essere utilizzato, ma che cosa fare in caso più generale, quando i controllori possono essere precisate spring.xml config? E cosa fare con i parametri del percorso di richiesta?

+0

Come pensate di utilizzare queste informazioni? Spring Tool Suite ti fornirà queste informazioni all'interno dell'IDE. Altrimenti, ecco un'utilità che ho scritto: https://github.com/kdgregory/pathfinder (mi unirò ad alcuni aggiornamenti questa settimana) – kdgregory

+0

Sto cercando di implementare il sistema di menu dinamico per la mia applicazione web.Non ho bisogno di analizzare staticamente i codici sorgente (la mia Idea lo fa già bene), ho bisogno di analizzarlo in modo razionale, in modo riflessivo. –

+0

Come pensate di trovare i controller rilevanti nella configurazione XML? Forse potresti accedere a 'org.springframework.web.bind.annotation.support.HandlerMethodResolver.getHandlerMethods()' in fase di runtime ed elaborare i metodi restituiti. –

risposta

23

Dalla primavera 3.1, è presente la classe RequestMappingHandlerMapping, fornisce informazioni sulla mappatura (RequestMappingInfo) delle classi @Controller.

@Autowired 
private RequestMappingHandlerMapping requestMappingHandlerMapping; 

@PostConstruct 
public void init() { 
    Map<RequestMappingInfo, HandlerMethod> handlerMethods = 
           this.requestMappingHandlerMapping.getHandlerMethods(); 

    for(Entry<RequestMappingInfo, HandlerMethod> item : handlerMethods.entrySet()) { 
     RequestMappingInfo mapping = item.getKey(); 
     HandlerMethod method = item.getValue(); 

     for (String urlPattern : mapping.getPatternsCondition().getPatterns()) { 
      System.out.println(
       method.getBeanType().getName() + "#" + method.getMethod().getName() + 
       " <-- " + urlPattern); 

      if (urlPattern.equals("some specific url")) { 
       //add to list of matching METHODS 
      } 
     } 
    }  
} 

È importante che questo fagiolo è definita nel contesto sorgente dove sono definiti i controllori.

+0

Non ho nessun bean di tipo RequestMappingHandlerMapping. Chi cetterà questo fagiolo prima dell'autowiring ... puoi aiutarmi qui? –

3

È possibile provare a utilizzare l'interfaccia ListableBeanFactory per recuperare tutti i nomi di bean.

private @Autowired ListableBeanFactory beanFactory; 

public void doStuff() { 
    for (String beanName : beanFactory.getBeanDefinitionNames()) { 
     if (beanName.startsWith("env")) { // or whatever check you want to do 
      Object bean = beanFactory.getBean(beanName) 
      // .. do something with it 
     } 
    } 
} 

Vedere la documentazione di ListableBeanFactory here. Questa interfaccia fornisce diversi metodi come getBeansOfType(), getBeanDefinitionCount() ecc

Se questo approccio non elenca @Controller fagioli annotati visit this pagina per vedere come ciò possa essere fatto.

5

Si ottiene un controller mappato chiamando HandlerMapping.getHandler(HTTPServletRequest).getHandler(). Un'istanza di HandlerMapping può essere acquisita da IoC. Se non si dispone di un HTTPServletRequest è possibile creare la richiesta con un MockHttpServletRequest .

@Autowired 
private HandlerMapping mapping; 

public Object getController(String uri) { 
    MockHttpServletRequest request = new MockHttpServletRequest("GET", uri); 
    // configure your request to some mapping 
    HandlerExecutionChain chain = mapping.getHandler(request); 
    return chain.getHandler(); 
} 

Siamo spiacenti, ho letto ora che si desidera tutti i controller per un URL. Questo ti mostrerà solo un controller esattamente corrispondente. Ovviamente non vuoi che tu ne abbia bisogno.

1

è necessario fare una voce per RequestMappingHandlerMapping nel servlet dispatcher

<bean name="requestHandlerMapping" class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"> 
     <property name="useTrailingSlashMatch" value="true"></property> 
    </bean> 

il servlet dispatcher esaminerà questa mappatura e un'istanza di un RequestMappingHandlerMapping fagioli nell'applicazione

ora in qualsiasi del controller/classe che è possibile utilizzare

@Autowired 
private HandlerMapping mapping; 

e dovrebbe funzionare correttamente.

Nota: è necessario occuparsi dell'aggiunta del bean, se uno qualsiasi dei dispatcherservlet (nel caso di una grande applicazione) contiene questo bean, si verificherà l'eccezione noUniqueBean e l'applicazione non verrà avviata.

Problemi correlati