Использование SiteMesh с forwardDespatcher's forward ()
Вопрос
Я пытаюсь интегрировать SiteMesh в устаревшее приложение с использованием Tomcat 5 в качестве моего контейнера. У меня есть main.jsp
, который я украшаю простым декоратором.
В decorators.xml
я только что определил один декоратор:
<decorators defaultdir="/decorators">
<decorator name="layout-main" page="layout-main.jsp">
<pattern>/jsp/main.jsp</pattern>
</decorator>
</decorators>
Этот декоратор работает, если я вручную перехожу на http://example.com/my-webapp/jsp/main.jsp
. Однако есть несколько мест, где сервлет вместо перенаправления на jsp выполняет forward :
getServletContext().getRequestDispatcher("/jsp/main.jsp").forward(request, response);
Это означает, что URL-адрес остается в чем-то вроде http://example.com/my-webapp/servlet/MyServlet
вместо файла jsp и поэтому не оформляется, я полагаю, поскольку он не соответствует шаблону в <pattern>/*</pattern>
.
Я не могу сделать layout-main.jsp
, потому что есть другие jsps, которые не нужно украшать <pattern>/servlet/MyServlet*</pattern>
. Я не могу выполнить MyServlet
, потому что error.jsp
иногда может пересылать <=>, а иногда - <=>.
Есть ли способ обойти это без значительных изменений в работе сервлетов? Поскольку это унаследованное приложение, у меня не так много свободы, чтобы что-то менять, поэтому я надеюсь на что-то в конфигурации, которое это исправит.
Документация SiteMesh действительно не так уж и хороша. Я работал в основном на примере приложения, которое поставляется с дистрибутивом. Мне очень нравится SiteMesh, и я надеюсь, что смогу заставить его работать в этом случае.
Решение
Насколько я понимаю, SiteMesh интегрирован в приложение в качестве фильтра сервлетов. По умолчанию фильтры сервлетов вызываются только против исходного входящего запроса (в вашем случае - запроса к сервлету). Последующие запросы пересылки или включения не передаются через фильтр и, следовательно, не передаются через sitemesh.
Тем не менее, вы можете указать, что фильтр должен быть запущен вперед, используя что-то вроде этого:
<filter-mapping>
<filter-name>sitemesh</filter-name>
<servlet-name>MyServlet</servlet-name>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
Который указывает контейнеру работать только с запросами FORWARD. Другими параметрами являются INCLUDE и REQUEST, вы можете иметь несколько элементов.
Таким образом, вы можете либо изменить конфигурацию фильтра, указав FORWARD, либо изменить сопоставление фильтра, чтобы оно соответствовало пути сервлета, а не пути JSP. Либо один должен работать.