Utilizzo di SiteMesh con forward () di RequestDispatcher
Domanda
Sto tentando di integrare SiteMesh in un'applicazione legacy utilizzando Tomcat 5 come mio contenitore. Ho un main.jsp
che sto decorando con un semplice decoratore.
In decorators.xml
, ho appena definito un decoratore:
<decorators defaultdir="/decorators">
<decorator name="layout-main" page="layout-main.jsp">
<pattern>/jsp/main.jsp</pattern>
</decorator>
</decorators>
Questo decoratore funziona se vado manualmente a http://example.com/my-webapp/jsp/main.jsp
. Tuttavia, ci sono alcuni punti in cui un servlet, invece di eseguire un reindirizzamento a un jsp, esegue un forward :
getServletContext().getRequestDispatcher("/jsp/main.jsp").forward(request, response);
Ciò significa che l'URL rimane su qualcosa come http://example.com/my-webapp/servlet/MyServlet
invece del file jsp e quindi non viene decorato, presumo poiché non corrisponde allo schema in <pattern>/*</pattern>
.
Non riesco a fare un layout-main.jsp
perché ci sono altri jps che non devono essere decorati da <pattern>/servlet/MyServlet*</pattern>
. Non riesco a fare un MyServlet
perché error.jsp
può inoltrare a <=> a volte e forse <=> altre volte.
Esiste un modo per aggirare questo problema senza modifiche estese al funzionamento dei servlet? Dal momento che è un'app legacy non ho la stessa libertà di cambiare le cose, quindi spero in qualcosa di configurazione che risolva questo problema.
La documentazione di SiteMesh non è davvero eccezionale. Ho lavorato principalmente sull'applicazione di esempio fornita con la distribuzione. Mi piace molto SiteMesh e spero di riuscire a farlo funzionare in questo caso.
Soluzione
La mia comprensione è che SiteMesh è integrato nell'applicazione come filtro Servlet. Per impostazione predefinita, i filtri servlet vengono invocati solo rispetto alla richiesta in arrivo originale (nel tuo caso, la richiesta al servlet). Le successive richieste di inoltro o inclusione non vengono passate attraverso il filtro e pertanto non verranno trasmesse tramite sitemesh.
Tuttavia, puoi indicare al filtro di essere invocato in avanti, usando qualcosa del genere:
<filter-mapping>
<filter-name>sitemesh</filter-name>
<servlet-name>MyServlet</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Che indica al contenitore di funzionare solo su richieste FORWARD. Le altre opzioni sono INCLUDE e RICHIESTA, puoi avere diversi elementi.
Quindi le opzioni sono o modificare la configurazione del filtro per specificare FORWARD o cambiare la mappatura del filtro in modo che corrisponda al percorso servlet, anziché al percorso JSP. O uno dovrebbe funzionare.