WEB-INF目录内的JSF文件,我如何访问它们?

我想把我的JSF 2.0 xhtml文件放在WEB-INF \ jsf下。 那么我如何访问它们呢? 我知道WEB-INF中的任何东西都不会暴露在外面,所以我需要一个控制器来将我redirect到相应的JSP,对吧? (这也是模式2的模式iirc)。

我可以用web.xml / faces-config.xml中的参数来实现吗? 我认为FacesServlet是我的web应用程序的控制器,所以它应该为此目的?

另一个问题是理解模型2模式。 每个动作都必须先到达一个servlet,然后处理下一个可能的步骤? 那么一个简单的<a href="anotherPage.html" />在这种模式下是被禁止的,因为它不会去控制servlet?

我想把我的JSF 2.0 xhtml文件放在WEB-INF \ jsf下。 那么我如何访问它们呢?

你不能。 /WEB-INF文件夹中的文件不能直接访问。

有两个选项可以解决公共可访问的JSF源文件的问题。

  1. FacesServlet映射到*.xhtml而不是*.jsf

  2. 或者,通过web.xml<security-constraint>来限制对*.xhtml的直接访问。

     <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模式。 每个动作都必须先到达一个servlet,然后处理下一个可能的步骤?

FacesServlet已经做到了。 这是控制器。 使用JSF,您已经以一个简单的javabean模型和JSP / Facelets文件作为视图。 作为控制器的FacesServlet已经从您的手中完成了所有请求参数收集,validation,转换,模型更新和导航的恶意工作。

也可以看看:

  • JSF MVC框架中的MVC是什么组件?
  • JSF控制器,服务和DAO

那么一个简单的<a href="anotherPage.html" />在这种模式下是被禁止的,因为它不会去控制servlet?

不,这很好。 控制器将在需要时启动。 如果资源不需要控制器(即静态资源),那么你也不需要让它通过某个控制器。


将来,请在单独的堆栈溢出问题中提出多个问题。

安全约束只是JSF缺失的一种解决方法。 我如何能像home.jsf映射到不同于home.xhtml放在WebContent下的文件? 以这种方式,我在导航和项目结构之间有很高的耦合度。 我如何避免在JSF中?

要访问WEB-INF/jsf文件夹内的xhtml页面,请执行下一步:

  1. xhtml页面文件夹从webapp root移到WEB-INF
  2. 向项目介绍“ 调度员视图 ”模式
  3. 将“ Front Controller ”servlet映射到基于应用程序页面的url
  4. Faces Servlet映射到“ .xhtml
  5. 在“ Dispatcher ”里向“ WEB-INF/jsf/<name>.xhtml ”页面转发请求
  6. 重写jsf ViewHandler getActionUrl从生成的action urlform, link, button )中排除“ WEB-INF

例如, xhtml页面位于webapp根文件夹“ jsf ”中。 页面之间的所有url都像jsf/<pageName>.xhtml 。 所以我们接下来做:

  1. <webapp root>/jsf移动到<webapp root>/WEB-INF/jsf

  2. 创buildFrontController 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); } } 
  1. 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> 
  1. 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> 
  1. 创build调度器 ,转发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等等,那么这些url就会包含“ /WEB-INF ”。 所以要排除它,我们需要下一步。

  1. jsf生成的url排除“ /WEB-INF ”(对于jsf表单,链接,button)。 为了那个原因:

    6.1创buildjsf 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.2configurationjsf使用指定的ViewHandler 。 在faces-config.xml添加next:

  <application> ... <view-handler> controllers.HiddenPageViewHandler </view-handler> </application>