要访问文件夹xhtml
内的页面,WEB-INF/jsf
您可以执行以下操作:
- 将
xhtml
pages 文件夹从移动webapp root
到WEB-INF
- 在项目中引入“ Dispatcher View ”模式
- 将“前端控制器”servlet映射到
url
基于应用程序的页面
- 将Faces Servlet映射到“
.xhtml
”
- 在“ Dispatcher ”内部将请求转发到来自“
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 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);
}
}
- 将 Front Controller servlet 映射
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>
- 将Faces 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
那么Dispatcher会将其转发到myapp/WEB-INF/jsf/home.xhtml
. Faces Servlet 将处理“ .xhtml
”请求。但是,如果在页面上使用了jsf
诸如h:form, h:link, h:button
etc 之类的组件,它们会生成,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>