java - 从 JSF 1.2 迁移到 JSF 2.0

标签 java jsf migration jsf-2

我正在使用一个用 编写的相当大的应用程序JSF 1.2 .
JSF 1.2 现在大约 6 岁了。我需要升级到 JSF 2.0。这会有多痛苦?我注意到自定义标签中的某些属性已更改等。

最佳答案

痛苦

将 JSF 1.2 升级到 2.0 的痛苦取决于您当前使用的 View 技术以及您想要使用的 View 技术。

  • JSP 2.x 到 JSP 2.x = 几乎不费吹灰之力。
  • Facelets 1.x 到 Facelets 2.0 = 很少努力。
  • JSP 2.x 到 Facelets 2.0 = 很多努力。如果您还有自定义组件,则加倍。


  • 基本变化

    不管 View 技术切换,至少要做到以下几个步骤:
  • /WEB-INF/lib 中删除 JSF 1.2 JAR (如果有的话)。
  • 将 JSF 2.0 JAR 放入 /WEB-INF/lib (如果 JSF 1.2 是由 servletcontainer 提供的,您可能希望更改类加载策略以在 servletcontainer 库之前先加载 webapp 库,另见 JSF2 classloading issues in application servers )。
  • 更新 faces-config.xml 的根声明遵守 JSF 2.0 规范。

    <faces-config
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd"
        version="2.0">
    

    注意:当您使用 JSF 2.2 或更新版本时,请使用 http://xmlns.jcp.org命名空间域而不是 http://java.sun.com贯穿上述 XML 片段。
  • 确保 web.xml 的根声明已经至少符合 Servlet 2.5。 JSF 2.0 不适用于 2.4 或更低版本 ( although it's hackable )。

    <web-app 
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="YourWebappID"
        version="2.5">
    

    注意:当您使用 Servlet 3.0 或更新版本时,请使用 http://xmlns.jcp.org命名空间域而不是 http://java.sun.com贯穿上述 XML 片段。


  • JSP 2.x 到 JSP 2.x

    如果您使用的是 JSP 2.x 并想保留 使用它,那么您基本上不需要更改任何其他内容。

    逐步升级

    如果您已经在使用后缀 url-patternFacesServlet , 喜欢 *.jsf ,那么很高兴知道 FacesServlet将首先扫描 *.xhtml文件,如果它不存在,则扫描 *.jsp文件。这为您提供了在幕后逐步从 JSP 转换为 Facelets 的空间,而无需更改 URL。

    但是如果你使用前缀 url-pattern , 喜欢 /faces/*并且想要逐步从JSP升级到Facelets,那你真的要改成*.jsf可能还有现有 JSP 页面中的所有链接。

    您只需要记住,新的 JSF 2.0 提供的隐式导航不会扫描文件是否存在,它会转到 outcome.xhtml反正。所以如果你想来自或去*.jsp ,那么您仍然需要将其包含在 JSF 1.x 方式的 viewid 中。

    Facelets 1.x 到 Facelets 2.0

    如果您使用的是 Facelets 1.x 作为 View 技术并希望使用提供的 JSF 2.0 Facelets 2.0 ,那么您需要执行以下附加步骤:
  • /WEB-INF/lib 中删除 Facelets 1.x JAR .
  • 删除 Facelets 1.x FaceletViewHandler来自 faces-config.xml .
  • 任意定制 FaceletViewHandler实现需要更新以扩展 ViewHandlerWrapper 相反。
  • 没有必要,但只是为了清理,删除任何与 Facelets 1.x 相关的 <context-param>来自 web.xml 的值在 Facelets 2.0 中已经是默认的,比如 javax.faces.DEFAULT_SUFFIX值为 *.xhtml .
  • 更新现有 Facelet taglib XML 的根声明以符合 Facelets 2.0。

    <facelet-taglib 
        xmlns="http://java.sun.com/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facelettaglibrary_2_0.xsd"
        version="2.0">
    

    注意:当您使用 JSF 2.2 或更新版本时,请使用 http://xmlns.jcp.org命名空间域而不是 http://java.sun.com贯穿上述 XML 片段。

  • 基本上应该是这样。

    JSP 2.x 到 Facelets 2.0

    如果您使用的是 JSP 2.x 作为 View 技术,您想升级到 Facelets 2.0 立即,那么您需要在网站上线之前进行大量更改。你基本上改变了这里的 View 技术。

    母版页更改

    在每个母版页上,您需要更改以下基本 JSP 模板..

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
    <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
    <!DOCTYPE html>
    <f:view>
        <html lang="en">
            <head>
                <title>JSP page</title>
            </head>
            <body>
                <h:outputText value="JSF components here." />
            </body>
        </html>
    </f:view>
    

    ..到以下基本 Facelets 模板:

    <!DOCTYPE html>
    <html lang="en"
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets">
        <h:head>
            <title>XHTML page</title>
        </h:head>
        <h:body>
            <h:outputText value="JSF components here." />
        </h:body>  
    </html>
    

    注意:当您使用 JSF 2.2 或更新版本时,请使用 http://xmlns.jcp.org命名空间域而不是 http://java.sun.com贯穿上述 XHTML 片段。

    包括页面更改

    如果您现有的 JSP 页面设计良好,那么您不应该有任何脚本代码行,并且您还应该只有 <jsp:include>作为唯一的 JSP 特定标记。其中任何一个都需要从:

    <jsp:include page="include.jsp" />
    



    <ui:include src="include.xhtml" />
    

    基本的 JSP 包括页面模板...

    <%@page contentType="text/html" pageEncoding="UTF-8"%>
    <%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
    <%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>
    <f:subview id="include">
        <h:outputText value="JSF components here." />
    </f:subview>
    

    .. 应该改为以下基本的 Facelets 包含页面模板:

    <ui:composition
        xmlns="http://www.w3.org/1999/xhtml"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:ui="http://java.sun.com/jsf/facelets">
        <h:outputText value="JSF components here." />
    </ui:composition>
    

    注意:当您使用 JSF 2.2 或更新版本时,请使用 http://xmlns.jcp.org命名空间域而不是 http://java.sun.com贯穿上述 XHTML 片段。

    自定义组件更改

    您需要按照此 Mojarra Migration Guide 中的描述将 JSP TLD 文件更改为 Facelets TLD 文件。 .

    后果

    无论采用何种迁移方式,都可以逐渐消除 faces-config.xml通过新的 JSF 2.0 注释甚至 CDI .任意 <managed-bean>可以通过 @ManagedBean 注释:
    @ManagedBean(name="managedBeanName")
    @RequestScoped
    public class SomeBean {}
    

    旁边 @RequestScoped ,还有 @ViewScoped , @SessionScoped @ApplicationScoped 可用。如果省略 name @ManagedBean 的属性,那么它将默认为第一个字符小写的类名。
    @ManagedBean
    @RequestScoped
    public class SomeBean {}
    

    在这个特定的例子中,它将是 #{someBean} .

    任意 <managed-property>可以使用 @ManagedProperty 注释:
    @ManagedProperty("#{otherBean}")
    private OtherBean otherBean;
    

    任意 <validator>可以使用 @FacesValidator 注释:
    @FacesValidator("someValidator")
    public class SomeValidator implements Validator {}
    

    任意 <converter>可以使用 @FacesConverter 注释
    @FacesConverter("someConverter")
    public class SomeConverter implements Converter {}
    

    任意 <renderer>可以使用 @FacesRenderer 注释
    @FacesRenderer(componentFamily="someComponentFamily", rendererType="someRendererType")
    public class SomeRenderer extends Renderer {}
    

    任意 <navigation-case>它使用 XHTML 页面的文件名作为两者 <from-outcome><to-view-id>可以删除,因为这将是 implicitly完成。这可以通过更改所有结果值以匹配目标 View 的文件名来逐步完成。

    最后,为了在同一选项卡/窗口中的后续请求中保留 bean 数据的唯一原因而放入 session 中的任何 session 范围 bean 最好标记为 @ViewScoped ,因为这样当最终用户在不同的选项卡/窗口中打开同一页面时 bean 不会受到影响。

    组件库

    请注意,在此答案中,我没有考虑任何 3rd 方组件库,例如 PrimeFaces/RichFaces/IceFaces,因此不可能写出可靠的答案,因为它基本上归结为“视情况而定”。一般来说,只需按照他们的说明将组件库升级到一个由他们自己验证的 JSF 2.0 兼容版本就足够了。最好是编写单元测试,在升级前后运行它们并单独修复任何问题。

    这里至少有一些关于特定组件库迁移的有用链接:
  • RichFaces Migration Guide - 3.3.x to 4.x migration
  • IceFaces 2 Wiki - IceFaces 1.x Compatibility Guide

  • PrimeFaces 没有 PrimeFaces 1.x 到 2.x 的迁移指南,因为 PrimeFaces 1.x 已经需要 Facelets 1.x,所以您只需要遵循 Facelets 1.x 到 2.x 的迁移步骤。但是,有一个 PrimeFaces 2.x to 3.x (and higher) migration guide这也可能适用于从 PrimeFaces 1.x 迁移到 3.x(或更高版本)。 Tomahawk 也没有迁移指南。基本上,您唯一需要更改的是 JAR,如有必要,请删除所有 <t:saveState>通过使 bean View 具有作用域来引用请求作用域 bean。

    关于java - 从 JSF 1.2 迁移到 JSF 2.0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4441713/

    相关文章:

    java - 如何在 Java 中移动数组中的位置?

    java - 当我运行这个应用程序时,致命异常显示错误无法启动 Activity 组件

    java - WebClient 未解析

    swift - 从 Swift 2.3 迁移到 Swift 3 错误消息

    reference - 删除的迁移文件 - Laravel

    java - php 值 Java 字节数组

    jsf - 如何从 JSF 中的 managedBean 重新加载同一页面?

    jsf - p :dataTable 中的自定义过滤器和转换器

    postgresql - 列 "migrations.id"具有不受支持的类型 "serial"

    JSF 和容器管理的安全性