Файлы JSF внутри каталога WEB-INF, как к ним получить доступ?
Я хочу поместить мои файлы JSF 2.0 xhtml в WEB-INFjsf. Как же мне тогда получить к ним доступ? Я знаю, что все, что находится внутри WEB-INF, не подвергается воздействию извне, поэтому мне нужен контроллер, чтобы перенаправить меня на соответствующий JSP, верно? (Это также модель 2 pattern iirc).
Могу ли я достичь этого с помощью параметра inside web.XML для лица-конфиг.в XML? Я думаю, что FacesServlet является контроллером моего веб-приложения, поэтому он должен служить этой цели?
И еще один вопрос для понимания Образец Модели 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. Почему?
и еще один вопрос для понимания модели 2. Должно ли каждое действие сначала идти к сервлету, который затем обрабатывает следующий возможный шаг?
FacesServlet
уже делает это. Это контроллер. С JSF вы уже заканчиваете с простой javabean как модель и файл JSP / Facelets как представление.FacesServlet
как контроллер уже взял всю неприятную работу по сбору параметров запроса, проверке, преобразованию, обновлению модели и навигации из ваших рук.См. также:
Нет, все в полном порядке. Контроллер будет работать в любое время, когда это необходимо. Если ресурс не нуждается в контроллере (то есть статическом ресурсе), то вам также не нужно пропускать его через какой-то контроллер.таким образом, простой
<a href="anotherPage.html" />
запрещен в этом шаблоне, так как он не идет к управляющему сервлету?
В будущем, пожалуйста, задавайте несколько вопросов в отдельных вопросах переполнения стека.
Для доступа к страницам
xhtml
внутри папкиWEB-INF/jsf
Вы можете сделать следующее:
- переместить папку
xhtml
pages изwebapp root
вWEB-INF
- ввести шаблон "диспетчерский вид " в проект
- Map "Front Controller " servlet to
url
на основе страниц из приложения- Map Faces Servlet to "
.xhtml
"- внутри "диспетчер " переадресация запроса на страницу из "
WEB-INF/jsf/<name>.xhtml
"- переопределить
jsf ViewHandler getActionUrl
, чтобы исключить "WEB-INF
" из генерируетсяaction
url
(изform, link, button
)Например, страницы
xhtml
находятся в корневой папке webapp "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); } }
- отображение переднего сервлета контроллера в
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
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>
- создайте диспетчер , который перенаправляет
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 будет обрабатывать запрос ".xhtml
". Но если на странице используютсяjsf
компоненты типаh:form, h:link, h:button
и т. д., которые генерируютaction
илиurl
, тоurl
будет действительно включать "/WEB-INF
". Поэтому, чтобы исключить его, нам нужно следующее шаг.
Исключить "
6.1 создать подкласс/WEB-INF
" изjsf
сгенерированногоurl
(для формы jsf, ссылки, кнопки). Для этого:jsf ViewHandler
и переопределитьgetActionUrl
:"
6.2 сконфигурируйте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; } }
jsf
для использования указанногоViewHandler
. Вfaces-config.xml
добавить следующее:<application> ... <view-handler> controllers.HiddenPageViewHandler </view-handler> </application>