Primavera-servlet.xml:Spring AOP con RequestDispatcher provoca chiamate ricorsive
<aop:config>
<aop:advisor advice-ref="interceptor" pointcut="@annotation(Validator)"/>
</aop:config>
<bean id="interceptor" class="org.aopalliance.intercept.MethodInterceptor" />
MethodInterceptor invoke():
if (!valid){
RequestDispatcher rd = request.getRequestDispatcher(errorView);
rd.forward(request, response);
}
Lavorare flusso di controllo:
Il mio intercettore è chiamato prima di ogni primavera metodo del controllore annotato con l'annotazione Validator
. L'intenzione è di convalidare la richiesta, se la convalida fallisce, inoltrare la richiesta a un'altra vista. Questo di solito funziona. Se si verifica un errore (!valid)
, viene chiamato lo RequestDispatcher.forward
. Ciò causa la chiamata di un altro metodo di controllo Spring che alla fine mostra la visualizzazione dell'errore. Questo normalmente funziona.
Problema:
Per alcuni controller di primavera, di mio RequestDispatcher errorView
fa sì che la richiesta da inoltrare di nuovo al metodo stessa causando un ciclo infinito (invoke()
viene chiamato più e più volte). Penso che questo sia dovuto al modo in cui sono configurati i mapping delle richieste del controller Spring (vedi sotto).
vista Errore: @RequestMapping(value = URL, params="error")
vista normale: @RequestMapping(value = URL, params="proceed")
Così, quando la prima richiesta viene indirizzata è ottenuto 'procedere' nei params richiesta. Quindi, quando c'è un errore e il RequestDispatcher inoltra alla vista con il parametro 'error' nella stringa di query, dovrebbe inoltrare al metodo "Error view" sopra, ma non lo fa. Si inoltra sempre al metodo 'proceed' causando un loop infinito su MethodInterceptor invoke()
. Questo sembra essere dovuto al fatto che il parametro 'proceed' è ancora in HttpServletRequest. Tuttavia questo non è facile da risolvere perché l'intero punto dell'intercettatore è che non ha alcuna conoscenza del controller Spring stesso: sa solo se si è verificato un errore e che dovrebbe inoltrare alla vista errori se si è verificato un errore.
Soluzione:
Utilizzando le mappature di richiesta di seguito, si risolve il problema. Ciò è probabilmente dovuto al fatto che il parametro HttpServletRequest
viene sovrascritto quando si utilizza la notazione key = value.
vista Errore: @RequestMapping(value = URL, params="view=error")
vista normale: @RequestMapping(value = URL, params="view=proceed")
Domanda
Come posso "correttamente" risolvere il problema senza ricorrere alla soluzione mostrata in precedenza? Esiste un modo più standard per inoltrare il controller a molla corretto?
Puoi condividere tutti i codici sorgente con github o ** MethodInterceptor invoke() ** maggiori dettagli? – CrawlingKid