JSF-файлы в каталоге WEB-INF, как мне получить к ним доступ?
Я хочу поместить мои файлы JSF 2.0 xhtml в WEB-INF\jsf. Как мне получить к ним доступ? Я знаю, что что-то внутри WEB-INF не подвергается воздействию извне, поэтому мне нужен контроллер, чтобы перенаправить меня на соответствующую JSP, верно? (Это также модель 2 модели IIRC).
Могу ли я добиться этого с помощью параметра внутри web.xml/face-config.xml? Я думаю, что FacesServlet является контроллером моего веб-приложения, поэтому он должен служить этой цели?
И еще один вопрос для понимания модели Model 2. Каждое действие должно идти сначала к сервлету, который затем обрабатывает следующий возможный шаг? Так просто <a href="anotherPage.html" />
запрещено в этом шаблоне, так как он не идет в управляющий сервлет?
2 ответа
Я хочу поместить мои файлы JSF 2.0 xhtml в 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>
Смотрите также:
- Какие файлы XHTML мне нужно поместить в /WEB-INF, а какие нет?
- JSF Facelets: иногда я вижу URL-адрес.jsf, а иногда и.xhtml. Зачем?
И еще один вопрос для понимания модели Model 2. Каждое действие должно идти сначала к сервлету, который затем обрабатывает следующий возможный шаг?
FacesServlet
уже делает это. Это контроллер. С JSF вы уже получаете простой javabean как модель и файл JSP/Facelets как представление. FacesServlet
Контроллер уже взял на себя всю грязную работу по сбору, проверке, преобразованию, обновлению модели и навигации параметров запроса.
Смотрите также:
Так просто
<a href="anotherPage.html" />
запрещено в этом шаблоне, так как он не идет в управляющий сервлет?
Нет, все отлично. Контроллер сработает при необходимости. Если ресурсу не нужен контроллер (то есть статический ресурс), вам также не нужно пропускать его через некоторый контроллер.
В будущем задайте несколько вопросов в отдельных вопросах переполнения стека.
Чтобы получить доступ xhtml
страницы внутри WEB-INF/jsf
Папка, которую вы можете сделать дальше:
- Переехать
xhtml
папка страниц изwebapp root
вWEB-INF
- Ввести шаблон " Диспетчерский вид " в проект
- Отобразить сервлет " Front Controller " в
url
на основе страниц из приложения - Карта Faces Servlet для "
.xhtml
" - Внутри " Диспетчер " жду запроса на страницу от "
WEB-INF/jsf/<name>.xhtml
" - Override
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>
- карта Лица Сервлет в
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
, И Лиц Сервлет справится .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>
Ограничение безопасности - это только обходной путь для отсутствующего JSF. Как сопоставить URL-адрес, например home.jsf, с файлом, отличным от home.xhtml, помещенным в WebContent? Таким образом, у меня высокая связь между навигацией и структурой проекта. Как я могу избежать этого в JSF?