简体   繁体   English

在JSF2项目中混合使用JSP和XHTML(Facelets) - 可能吗?

[英]Mixing JSP and XHTML (Facelets) in JSF2 Project - possible?

I have a client who wants to use JSF2 and they like that XHTML is now the default (Facelets). 我有一个客户想要使用JSF2,他们喜欢XHTML现在是默认的(Facelets)。

However, they have a huge amount of "legacy" JSP from their JSF1.x codebase. 但是,他们的JSF1.x代码库中有大量的“遗留”JSP。

I know it's probably not desirable, but will it be possible to support a mix of both in JSF2, at least for a transition period whilst they port? 我知道这可能不太可取,但是有可能在JSF2中支持两者的混合,至少在他们移植的过渡期间吗?

I know it was possible to mix the two in JSF1.x, but I can't find any information about this in JSF2. 我知道可以在JSF1.x中混合使用两者,但我在JSF2中找不到任何关于此的信息。

I've googled hard but naturally all the JSF2 focus is on Facelets. 我用谷歌搜索过,但自然所有JSF2都集中在Facelets上。 Also my brief attempt at mixing (I'm not an expert at JSF!) has led to failure. 我对混音的简短尝试(我不是JSF的专家!)导致了失败。

This is answered in the Facelets FAQ : use prefix mapping on FacesServlet . 这在Facelets FAQ中得到了解答 :在FacesServlet上使用前缀映射。 You can then access JSP pages by http://example.com/faces/page.jsp and Facelets pages by http://example.com/faces/page.xhtml . 然后,您可以通过http://example.com/faces/page.jsp和Facelets页面访问JSP页面,网址为http://example.com/faces/page.xhtml Here's a cite of relevance: 这是一个相关的引用:

How do I use Facelets and JSP in the same application? 如何在同一个应用程序中使用Facelets和JSP?

You have to use prefix mapping for the Facelets pages in order for this to work. 您必须为Facelets页面使用前缀映射才能使其正常工作。 Leave the DEFAULT_SUFFIX with the JSF default of .jsp . 保留DEFAULT_SUFFIX ,JSF默认为.jsp Configure the Facelet's VIEW_MAPPINGS parameter: 配置Facelet的VIEW_MAPPINGS参数:

 <web-app> <context-param> <param-name>javax.faces.DEFAULT_SUFFIX</param-name> <param-value>.jsp</param-value> </context-param> <!-- Facelets pages will use the .xhtml extension --> <context-param> <param-name>facelets.VIEW_MAPPINGS</param-name> <param-value>*.xhtml</param-value> </context-param> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> </servlet> <!-- Use prefix mapping for Facelets pages, eg http://localhost:8080/webapp/faces/mypage.xhtml --> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> </web-app> 

The wiki section cited by BalusC seems to be indeed out of date. BalusC引用的wiki部分似乎确实已经过时了。 In my extension mapping (*.faces) setup I had the problem with the proposed javax.faces.DEFAULT_SUFFIX set to .jsp that generated action URLs inside form tags of *.xhtml pages got a .jsp extension instead of a .faces extension (and therefore could not be mapped). 在我的扩展映射(* .faces)设置中,我遇到的问题是建议的javax.faces.DEFAULT_SUFFIX设置为.jsp ,它在* .xhtml页面的表单标签内生成了动作URL,扩展名为.jsp而不是.faces扩展名(因此无法映射)。

After I stepped into the corresponding classes of the Apache MyFaces 2.x implementation (see org.apache.myfaces.shared.application.DefaultViewHandlerSupport.calculateActionURL(FacesContext context, String viewId) ) the following setup turned out to work in our parallel use of JSP and Facelets View Handling. 在我进入Apache MyFaces 2.x实现的相应类之后(请参阅org.apache.myfaces.shared.application.DefaultViewHandlerSupport.calculateActionURL(FacesContext context,String viewId) ),以下设置结果可用于我们的并行使用JSP和Facelets视图处理。

How do I use Facelets and JSP in the same application? 如何在同一个应用程序中使用Facelets和JSP?

Besides prefix mapping you may use extension mapping (eg *.faces) for the Facelets pages in order for this to work. 除了前缀映射之外,您还可以使用Facelets页面的扩展映射(例如* .faces)来实现此功能。 Leave the DEFAULT_SUFFIX with the JSF default of .jsp .xhtml . 保留DEFAULT_SUFFIX,JSF默认为.jsp .xhtml Configure the Facelet's VIEW_MAPPINGS parameter: 配置Facelet的VIEW_MAPPINGS参数:

<web-app>
    <context-param>
        <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
        <param-value>.jsp .xhtml</param-value>
    </context-param>

    <!-- Facelets pages will use the .xhtml extension -->
    <context-param>
        <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
        <param-value>*.xhtml</param-value>
    </context-param>     

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
    </servlet>

    <!-- use extension mapping in this sample -->
    <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.faces</url-pattern>
    </servlet-mapping>
</web-app>

For those who are interested in the details of the processing of action urls inside org.apache.myfaces.shared.application.DefaultViewHandlerSupport.calculateActionURL(FacesContext context, String viewId): 对于那些对org.apache.myfaces.shared.application.DefaultViewHandlerSupport.calculateActionURL(FacesContext context,String viewId)中的动作URL处理细节感兴趣的人:

        if ( mapping.isExtensionMapping() ) {
            // See JSF 2.0 section 7.5.2
            String[] contextSuffixes = _initialized ? _contextSuffixes : getContextSuffix( context );
            boolean founded = false;
            for ( String contextSuffix : contextSuffixes ) {
                if ( viewId.endsWith( contextSuffix ) ) {
                    builder.append( viewId.substring( 0, viewId.indexOf( contextSuffix ) ) );
                    builder.append( mapping.getExtension() );
                    founded = true;
                    break;
                }
            }
            if ( !founded ) {
                // See JSF 2.0 section 7.5.2
                // - If the argument viewId has an extension, and this extension is mapping,
                // the result is contextPath + viewId
                //
                // -= Leonardo Uribe =- It is evident that when the page is generated, the
                // derived
                // viewId will end with the
                // right contextSuffix, and a navigation entry on faces-config.xml should use
                // such id,
                // this is just a workaroud
                // for usability. There is a potential risk that change the mapping in a webapp
                // make
                // the same application fail,
                // so use viewIds ending with mapping extensions is not a good practice.
                if ( viewId.endsWith( mapping.getExtension() ) ) {
                    builder.append( viewId );
                } else if ( viewId.lastIndexOf( "." ) != -1 ) {
                    builder.append( viewId.substring( 0, viewId.lastIndexOf( "." ) ) );
                    builder.append( contextSuffixes[0] );
                } else {
                    builder.append( viewId );
                    builder.append( contextSuffixes[0] );
                }
            }
        } else {
            builder.append( mapping.getPrefix() );
            builder.append( viewId );
        }

The above suggestion did not work at all for me. 上述建议对我来说根本不起作用。 The wiki page is probably out of date. 维基页面可能已过期。 From the JSF2 specification I got the following parameter that worked: 从JSF2规范我得到了以下参数:

  <!-- Facelets pages will use the .xhtml extension -->
  <context-param>
    <param-name>javax.faces.FACELETS_VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
  </context-param> 

instead of: 代替:

<context-param>
    <param-name>facelets.VIEW_MAPPINGS</param-name>
    <param-value>*.xhtml</param-value>
</context-param>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM