从 JSF 1.2 迁移到 JSF 2.0疼痛

2022-08-31 08:01:16

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


答案 1

疼痛

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

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

基本更改

无论视图技术切换如何,至少应该完成以下步骤:

  • 从中删除 JSF 1.2 JAR(如果有)。/WEB-INF/lib
  • 删除 JSF 2.0 JAR(如果 JSF 1.2 是 servletcontainer 提供的,您可能希望更改类加载策略,以便在 servletcontainer 库之前先加载 Webapp 库,另请参阅应用程序服务器中的 JSF2 类加载问题)。/WEB-INF/lib
  • 更新 根声明 以符合 JSF 2.0 规范。faces-config.xml

    <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 或更高版本时,请使用命名空间域,而不是贯穿上述 XML 代码段。http://xmlns.jcp.orghttp://java.sun.com

  • 确保 的根声明至少符合 Servlet 2.5。JSF 2.0 在 2.4 或更低版本上不起作用(尽管它是可破解的)。web.xml

    <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 或更高版本时,请使用命名空间域,而不是贯穿上述 XML 代码段。http://xmlns.jcp.orghttp://java.sun.com


JSP 2.x 到 JSP 2.x

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

逐步升级

如果您已经在 使用 后缀 ,如 ,那么最好知道 将首先扫描文件,如果它不存在,则扫描文件。这为您提供了在后台逐步从 JSP 转换为 Facelet 的空间,而无需更改 URL。url-patternFacesServlet*.jsfFacesServlet*.xhtml*.jsp

但是,如果您使用的是前缀 ,例如,并且想要逐渐从 JSP 升级到 Facelets,那么您真的必须将其更改为现有 JSP 页面中的所有链接。url-pattern/faces/**.jsf

您只需要记住,新的 JSF 2.0 提供的隐式导航不会扫描文件是否存在,它无论如何都会转到。因此,如果您想来自或转到 ,那么您仍然需要将其包含在查看JSF 1.x方式中。outcome.xhtml*.jsp


小面 1.x 到小面 2.0

如果您使用 Facelets 1.x 作为视图技术,并希望使用 JSF 2.0 提供的 Facelets 2.0,那么您需要执行以下附加步骤:

  • 从 中删除 Facelets 1.x JAR。/WEB-INF/lib
  • 从 中删除 Facelets 1.x。FaceletViewHandlerfaces-config.xml
  • 任何自定义实现都需要更新以扩展 ViewHandlerWrapperFaceletViewHandler
  • 没有必要,但只是为了清理,请删除任何与 Facelets 1.x 相关的值,这些值在 Facelets 2.0 中已经是默认值,例如 with 值 。<context-param>web.xmljavax.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 或更高版本时,请使用命名空间域,而不是贯穿上述 XML 代码段。http://xmlns.jcp.orghttp://java.sun.com

基本上应该就是这样。


JSP 2.x 到 Facelets 2.0

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

母版页更改

在每个母版页上,您需要更改以下基本 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 或更高版本时,请使用命名空间域,而不是贯穿上述 XHTML 代码段。http://xmlns.jcp.orghttp://java.sun.com

包括页面更改

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

<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 或更高版本时,请使用命名空间域,而不是贯穿上述 XHTML 代码段。http://xmlns.jcp.orghttp://java.sun.com

自定义组件更改

您需要将 JSP TLD 文件更改为 Facelets TLD 文件,如本 Mojarra 迁移指南中所述。


后果

无论采用哪种迁移方法,您都可以逐步消除由新的 JSF 2.0 注释甚至 CDI 添加的注释。任何都可以通过以下方式进行注释:@ManagedBeanfaces-config.xml<managed-bean>

@ManagedBean(name="managedBeanName")
@RequestScoped
public class SomeBean {}

@RequestScoped旁边还有@ViewScoped@SessionScoped@ApplicationScoped。如果省略 的属性,则它将默认为类名,第一个字符小写。name@ManagedBean

@ManagedBean
@RequestScoped
public class SomeBean {}

在此特定示例中,它将是 。#{someBean}

可以使用@ManagedProperty对 Any 进行注释:<managed-property>

@ManagedProperty("#{otherBean}")
private OtherBean otherBean;

可以使用@FacesValidator对 Any 进行注释:<validator>

@FacesValidator("someValidator")
public class SomeValidator implements Validator {}

可以使用任何@FacesConverter<converter>

@FacesConverter("someConverter")
public class SomeConverter implements Converter {}

可以使用@FacesRenderer对任意进行注释<renderer>

@FacesRenderer(componentFamily="someComponentFamily", rendererType="someRendererType")
public class SomeRenderer extends Renderer {}

任何使用XHTML页面文件名作为两者并且可以删除的任何内容,因为这将隐式完成。这可以通过更改所有结果值以匹配目标视图的文件名来逐步完成。<navigation-case><from-outcome><to-view-id>

最后,任何被放置在会话中的会话范围的bean,其唯一原因是在同一选项卡/窗口中的后续请求中保留bean数据,可以更好地标记,因为这样当最终用户在不同的选项卡/窗口中打开同一页面时,Bean不会受到影响。@ViewScoped


组件库

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

以下是至少一些有关特定组件库迁移的有用链接:

PrimeFaces没有PrimeFaces 1.x到2.x的迁移指南,因为PrimeFaces 1.x已经需要Facelets 1.x,所以你只需要按照Facelets 1.x到2.x的迁移步骤。但是,有一个PrimeFaces 2.x到3.x(及更高)的迁移指南,它可能也适用于从PrimeFaces 1.x迁移到3.x(或更高版本)。战斧也没有迁移指南。基本上,您唯一需要更改的是 JAR,如有必要,通过使 Bean 视图限定范围来删除请求作用域 Bean 上的所有引用。<t:saveState>


答案 2

值得一提的是,如果有人将 JSTL 与 JSF 1.2 一起使用,那么在升级到 JSF2 时,您应该从以下位置更改命名空间:

http://java.sun.com/jstl/core

自:

http://java.sun.com/jsp/jstl/core


推荐