I want to put my JSF 2.0 xhtml files under WEB-INF\\jsf. How do I access them then? I know that anything inside WEB-INF isn\'t exposed to the outside, so I need a controller
To access xhtml pages inside WEB-INF/jsf folder you may do next:
xhtml pages folder from webapp root to WEB-INFurl based to pages from application.xhtml"WEB-INF/jsf/.xhtml "jsf ViewHandler getActionUrl to exclude "WEB-INF" from generated action url (of form, link, button)For example, xhtml pages are in webapp root folder "jsf". All url between pages are like jsf/. So we do next:
move to
create FrontController servlet:
``
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 to url based for pages:Front Controller controllers.FrontController Front Controller /jsf/*
web.xml to .xhtml Faces Servlet javax.faces.webapp.FacesServlet 1 Faces Servlet *.xhtml
request to correct 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);
}
}
So if url for page was /myapp/jsf/home.xhtml then Dispatcher will forward it to myapp/WEB-INF/jsf/home.xhtml. And Faces Servlet will handle ".xhtml" request. But if on a page are used jsf components like h:form, h:link, h:button etc which generate action or url then the url will be really including "/WEB-INF". So to exclude it we need next step.
Exclude "/WEB-INF" from jsf generated url (for jsf form, link, button).
For that:
6.1 create subclass of jsf ViewHandler and override 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 to use the specified ViewHandler. In faces-config.xml add next:
... controllers.HiddenPageViewHandler