我想将我的JSF 2.0 xhtml文件放在WEB-INF \ jsf下。我如何访问它们呢?我知道WEB-INF内部的任何内容都没有暴露在外面,所以我需要一个控制器来将我重定向到相应的JSP,对吧? (这也是模型2模式iirc)。
我可以使用web.xml / faces-config.xml中的参数实现此目的吗?我认为FacesServlet是我的webapp的控制器所以它应该用于此目的吗?
另一个理解模型2模式的问题。是否每个操作都必须首先进入servlet,然后处理下一个可能的步骤?因此,在这种模式中禁止使用简单的<a href="anotherPage.html" />
,因为它不会转到控制servlet?
答案 0 :(得分:19)
我想将我的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>
另一个理解模型2模式的问题。是否每个操作都必须首先进入servlet,然后处理下一个可能的步骤?
FacesServlet
已经这样做了。这是控制器。使用JSF,您最终会得到一个简单的javabean作为模型,JSP / Facelets文件作为视图。作为控制器的FacesServlet
已经从你手中接受了请求参数收集,验证,转换,模型更新和导航的所有令人讨厌的工作。
所以这个模式中禁止使用简单的
<a href="anotherPage.html" />
,因为它不会转到控制servlet吗?
不,这很好。控制器将在需要时启动。如果资源不需要控制器(即静态资源),那么您也不需要让它通过某个控制器。
将来,请在单独的Stack Overflow问题中提出多个问题。
答案 1 :(得分:0)
要访问xhtml
文件夹中的WEB-INF/jsf
页面,您可以执行下一步:
xhtml
个网页文件夹从webapp root
移至WEB-INF
url
servlet .xhtml
&#34; WEB-INF/jsf/<name>.xhtml
&#34; jsf ViewHandler getActionUrl
以排除&#34; WEB-INF
&#34;来自生成的action
url
(form, link, button
)例如,xhtml
页面位于webapp根文件夹&#34; jsf
&#34;中。页面之间的所有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);
}
}
web.xml
中的Front Controller servlet映射到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
中的 Faces Servlet 映射到.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);
}
}
因此,如果网页的网址为/myapp/jsf/home.xhtml
,则调度程序会将其转发至myapp/WEB-INF/jsf/home.xhtml
。而Faces Servlet将处理&#34; .xhtml
&#34;请求。但是,如果在页面上使用生成jsf
或h:form, h:link, h:button
的{{1}}等action
组件,则url
将真正包含&#34; {{ 1}}&#34 ;.所以要排除它,我们需要下一步。
排除&#34; url
&#34;来自/WEB-INF
生成/WEB-INF
(对于jsf表单,链接,按钮)。
为此:
6.1创建jsf
的子类并覆盖url
:
``
jsf ViewHandler
6.2配置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;
}
}
。在jsf
添加下一个:
ViewHandler