Файлы JSF внутри каталога WEB-INF, как мне получить к ним доступ?
Я хочу поместить свои файлы xhtml в JSF 2.0 под WEB-INF\jsf. Как мне получить к ним доступ? Я знаю, что что-либо внутри WEB-INF не подвергается наружу, поэтому мне нужен контроллер, чтобы перенаправить меня на соответствующий JSP, правильно? (Это также образец модели 2).
Могу ли я достичь этого с помощью параметра внутри web.xml/faces-config.xml? Я думаю, что FacesServlet является контроллером моего webapp, поэтому он должен служить этой цели?
И еще один вопрос для понимания Модели 2. Выполняется ли каждое действие сначала на сервлет, который затем обрабатывает следующий возможный шаг? Таким образом, в этом шаблоне запрещен простой <a href="anotherPage.html" />
, поскольку он не переходит к управляющему сервлету?
Ответы
Ответ 1
Я хочу поместить свои файлы xhtml в JSF 2.0 под WEB-INF\jsf. Как мне получить к ним доступ?
Вы не можете. Файлы в папке /WEB-INF
недоступны напрямую.
Существует два способа обхода проблемы исходных файлов JSF, доступных общественности.
-
Сопоставьте FacesServlet
на *.xhtml
вместо *.jsf
.
-
Или ограничьте прямой доступ на *.xhtml
на <security-constraint>
в web.xml
.
<security-constraint>
<display-name>Restrict direct access to XHTML files</display-name>
<web-resource-collection>
<web-resource-name>XHTML files</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
См. также:
И еще один вопрос для понимания Модели 2. Выполняется ли каждое действие сначала на сервлет, который затем обрабатывает следующий возможный шаг?
FacesServlet
уже делает это. Это контроллер. С JSF вы уже получаете простой javabean как модель и JSP/Facelets файл в виде. FacesServlet
как контроллер уже предпринял всю неприятную работу по сбору, проверке, преобразованию модели, навигации и настройке параметров запроса из ваших рук.
См. также:
Итак, простой шаблон <a href="anotherPage.html" />
запрещен в этом шаблоне, так как он не переходит к управляющему сервлету?
Нет, это прекрасно. Контроллер будет запускаться в случае необходимости. Если ресурсу не нужен контроллер (т.е. Статический ресурс), то вам также не нужно пропускать его через какой-либо контроллер.
В будущем задайте несколько вопросов в отдельных вопросах.
Ответ 2
Ограничение безопасности является лишь обходным решением для отсутствия JSF.
Как я могу сопоставить url, например home.jsf, с файлом, отличным от home.xhtml, помещенным под WebContent?
Таким образом, у меня высокая связь между навигацией и проектной структурой.
Как я могу избежать этого в JSF?
Ответ 3
Чтобы получить доступ к xhtml
страницам внутри папки WEB-INF/jsf
, вы можете сделать следующее:
- Переместите папку
xhtml
страниц с webapp root
на WEB-INF
- Представьте шаблон Диспетчерский просмотр "для проекта
- Карта " Front Controller" сервлет
url
на основе страниц из приложения
- Карта Лица Servlet на "
.xhtml
"
- Внутри " Диспетчер" переслать запрос на страницу с "
WEB-INF/jsf/<name>.xhtml
"
- Переопределить
jsf ViewHandler getActionUrl
, чтобы исключить "WEB-INF
" из сгенерированного action
url
(из form, link, button
)
Например, страницы xhtml
находятся в корневой папке webapp "jsf
". Все url
между страницами похожи на jsf/<pageName>.xhtml
. Итак, мы делаем следующее:
``
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);
}
}
- map Сервлет сервоуправления в
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 Лица Servlet в
web.xml
до .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>
- создать Диспетчер, который пересылает
request
для исправления страницы xhtml
:
``
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 настройте jsf
, чтобы использовать указанный ViewHandler
. В faces-config.xml
добавить следующее:
<application>
...
<view-handler>
controllers.HiddenPageViewHandler
</view-handler>
</application>