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

时间:2010-08-18 12:50:58

标签: java model-view-controller jsf-2 web-inf

我想将我的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?

2 个答案:

答案 0 :(得分:19)

  

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

你做不到。 /WEB-INF文件夹中的文件无法直接访问。

有两种方法可以解决JSF源文件可公开访问的问题。

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

  2. 或者,限制*.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> 
    
  3. 另见:


      

    另一个理解模型2模式的问题。是否每个操作都必须首先进入servlet,然后处理下一个可能的步骤?

    FacesServlet已经这样做了。这是控制器。使用JSF,您最终会得到一个简单的javabean作为模型,JSP / Facelets文件作为视图。作为控制器的FacesServlet已经从你手中接受了请求参数收集,验证,转换,模型更新和导航的所有令人讨厌的工作。

    另见:


      

    所以这个模式中禁止使用简单的<a href="anotherPage.html" />,因为它不会转到控制servlet吗?

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


    将来,请在单独的Stack Overflow问题中提出多个问题。

答案 1 :(得分:0)

要访问xhtml文件夹中的WEB-INF/jsf页面,您可以执行下一步:

  1. xhtml个网页文件夹从webapp root移至WEB-INF
  2. 介绍&#34; 调度程序视图&#34;模式到项目
  3. 地图&#34; 前端控制器&#34;基于应用程序页面的url servlet
  4. Faces Servlet 映射到&#34; .xhtml&#34;
  5. 内部&#34; 调度员&#34;转发来自&#34; WEB-INF/jsf/<name>.xhtml&#34;
  6. 的页面请求
  7. 覆盖jsf ViewHandler getActionUrl以排除&#34; WEB-INF&#34;来自生成的action urlform, link, button
  8. 例如,xhtml页面位于webapp根文件夹&#34; jsf&#34;中。页面之间的所有url都与jsf/<pageName>.xhtml类似。我们接下来会这样做:

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

    2. 创建 FrontController servlet:

    3. ``

      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
      2. <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
        2. <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. 创建调度程序,转发request以更正xhtml页面:
          2. ``

            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;请求。但是,如果在页面上使用生成jsfh:form, h:link, h:button的{​​{1}}等action组件,则url将真正包含&#34; {{ 1}}&#34 ;.所以要排除它,我们需要下一步。

            1. 排除&#34; url&#34;来自/WEB-INF生成/WEB-INF(对于jsf表单,链接,按钮)。 为此:

              6.1创建jsf的子类并覆盖url

            2. ``

              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