12

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

我可以通过 web.xml/faces-config.xml 中的参数来实现这一点吗?我认为 FacesServlet 是我的 webapp 的控制器,所以它应该服务于这个目的?

另一个理解模型 2 模式的问题。是否每个操作都必须首先进入一个 servlet,然后由该 servlet 处理下一个可能的步骤?所以<a href="anotherPage.html" />在这种模式中禁止简单,因为它不去控制 servlet?

4

2 回答 2

21

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

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

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

  1. 映射FacesServleton*.xhtml而不是*.jsf.

  2. *.xhtml或者,通过<security-constraint>in限制直接访问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,然后由该 servlet 处理下一个可能的步骤?

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

也可以看看:


所以<a href="anotherPage.html" />在这种模式中禁止简单,因为它不去控制 servlet?

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


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

于 2010-08-18T13:20:07.393 回答
1

要访问文件夹xhtml内的页面,WEB-INF/jsf您可以执行以下操作:

  1. xhtmlpages 文件夹从移动webapp rootWEB-INF
  2. 在项目中引入“ Dispatcher View ”模式
  3. 将“前端控制器”servlet映射到url基于应用程序的页面
  4. 将Faces Servlet映射到“ .xhtml
  5. 在“ Dispatcher ”内部将请求转发到来自“ WEB-INF/jsf/<name>.xhtml”的页面
  6. 覆盖以从生成的(的)jsf ViewHandler getActionUrl中排除“ ”WEB-INFaction urlform, link, button

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

  1. 搬到<webapp root>/jsf_<webapp root>/WEB-INF/jsf

  2. 创建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);
        }
}
  1. 将 Front Controller servlet 映射web.xmlurl基于页面:
<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. Faces Servletweb.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>
  1. 创建转发到正确页面的调度程序:requestxhtml

``

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:buttonetc 之类的组件,它们会生成,action否则urlurl真正包含“ /WEB-INF”。所以要排除它,我们需要下一步。

  1. /WEB-INFjsf生成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>
于 2015-05-06T12:38:37.617 回答