Для доступа к xhtml
страницам внутри папки WEB-INF/jsf
вы можете сделать следующее:
- Переместить папку
xhtml
страниц из webapp root
в WEB-INF
- Ввести " Шаблон диспетчера"шаблон для проекта
- Карта" Front Controller"сервлет для
url
на основе страниц из приложения - Карта Servlet Faces в "
.xhtml
" - Внутри " Диспетчер " перенаправить запрос на страницу из "
WEB-INF/jsf/<name>.xhtml
" - Переопределить
jsf ViewHandler getActionUrl
для исключения "WEB-INF
"из сгенерированного action
url
(из form, link, button
)
Например, xhtml
страницы находятся в корневой папке веб-приложения" jsf
".Все url
между страницами похожи на jsf/<pageName>.xhtml
.Итак, мы делаем следующее:
переместить <webapp root>/jsf
в <webapp root>/WEB-INF/jsf
создать FrontController сервлет:
``
public class FrontController extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
process(req, resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
process(req, resp);
}
private void process(HttpServletRequest request, HttpServletResponse response) {
Dispatcher dispatcher = Dispatcher.getInstance();
dispatcher.dispatch(request, response);
}
}
отображение сервлета Front Controller в
web.xml
-
url
для страниц:
<servlet>
<servlet-name>Front Controller</servlet-name>
<servlet-class>controllers.FrontController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Front Controller</servlet-name>
<url-pattern>/jsf/*</url-pattern>
</servlet-mapping>
map
Faces Servlet in
web.xml
to
.xhtml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
create
Dispatcher , который перенаправляет
request
для исправления
xhtml
page:
``
public class Dispatcher {
public void dispatch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String pageBase = "/WEB-INF/jsf/";
String pagePath = null;
String errorPage = "/WEB-INF/jsf/error.xthml";
//here could be complicated logic to analyze if the page should be visible for security reasons, authorisation etc, business logic
//requested page could be taken from parsing requested URI
//pageName = findPageNameFromURI(request.getRequestURI());
pagePath = pageBase + pageName;
//if page should not be visible
pagePath = errorPage;
//forward to page inside WEB-INF/jsf
request.getServletContext().getRequestDispatcher(pagePath).
forward(request, response);
}
}
Так что, если URL для страницы был /myapp/jsf/home.xhtml
затем Диспетчер перенаправит его на myapp/WEB-INF/jsf/home.xhtml
.И Faces Servlet обработает запрос ".xhtml
".Но если на странице используются jsf
компоненты, такие как h:form, h:link, h:button
и т. Д., Которые генерируют action
или url
, тогда url
будет действительно включать "/WEB-INF
".Поэтому, чтобы исключить это, нам нужен следующий шаг.
Исключить "/WEB-INF
" из jsf
сгенерированного url
(для формы jsf, ссылки, кнопки).Для этого:
6.1 создайте подкласс jsf ViewHandler
и переопределите getActionUrl
:
``
public class HiddenPageViewHandler extends ViewHandlerWrapper {
private static final String WEB_INF = "/WEB-INF";
private ViewHandler parent;
public HiddenPageViewHandler(ViewHandler parent) {
this.parent = parent;
}
@Override
public String getActionURL(FacesContext context, String viewId) {
String actionUrl = super.getActionURL(context, viewId);
if (actionUrl != null && actionUrl.contains(WEB_INF)) {
actionUrl = actionUrl.replace(WEB_INF, "");
}
return actionUrl;
}
@Override
public ViewHandler getWrapped() {
return parent;
}
}
6.2 configure jsf
использовать указанный ViewHandler
.В faces-config.xml
добавить следующее:
<application>
...
<view-handler>
controllers.HiddenPageViewHandler
</view-handler>
</application>