从JSF 1.2迁移到JSF 2.0

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

困苦

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

  • JSP 2.x到JSP 2.x =几乎没有任何努力。
  • Facelets 1.x到Facelets 2.0 =很less的努力。
  • JSP 2.x到Facelets 2.0 =很多努力。 如果您还有自定义组件,请将其加倍。

基本的变化

无论查看技术切换, 至less应该执行以下步骤:

  • /WEB-INF/lib删除JSF 1.2 JAR(如果有的话)。
  • /WEB-INF/lib放置JSF 2.0 JAR(如果JSF 1.2是servlet容器提供的,您可能需要将servlet容器库之前的类加载策略更改为首先加载webapp库,另请参阅JSF2类加载应用程序服务器中的类 )。
  • 更新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"> 
  • 确保web.xml根目录已经至less符合Servlet 2.5。 JSF 2.0不能在2.4或更低的版本上工作( 虽然它是可破解的 )。

     <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"> 

JSP 2.x到JSP 2.x

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

逐步升级

如果您已经为FacesServlet使用后缀url-pattern (例如*.jsf ,那么最好知道FacesServlet将首先扫描*.xhtml文件,如果它不存在,则扫描*.jsp文件。 这为您提供了在不改变URL的情况下逐渐从JSP转换到Facelets的空间。

但是,如果您使用前缀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作为视图技术,并且想要使用JSF 2.0提供的Facelets 2.0 ,那么您需要执行以下附加步骤:

  • /WEB-INF/lib删除Facelets 1.x JAR。
  • faces-config.xml删除Facelets 1.x FaceletViewHandler
  • 任何自定义的FaceletViewHandler实现都需要更新来扩展ViewHandlerWrapper
  • 不是必需的,但只是为了清理,从web.xml删除Facelets 1.x中与Facelets 2.0相关的<context-param>值,例如值为*.xhtmljavax.faces.DEFAULT_SUFFIX
  • 更新现有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"> 

这基本上应该是这样。


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> 

..to以下基本的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> 

包含页面更改

如果您现有的JSP页面devise良好,则不应有任何scriptlet代码行,并且应该只有<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> 

自定义组件更改

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


后果

无论迁移方法如何,您都可以通过新的JSF 2.0注释逐渐消除 faces-config.xml 。 任何<managed-bean>可以由@ManagedBean注释:

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

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

 @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 {} 

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

最后,任何会话范围的bean被放在会话中,唯一的原因是在同一个标​​签/窗口中的后续请求中保留bean数据可以更好地标记为@ViewScoped ,因为这样的话bean不会受到影响enduser在不同的标签页/窗口中打开相同的页面。


组件库

请注意,在这个答案中,我没有将PrimeFaces / RichFaces / IceFaces等第三方组件考虑在内,因此不可能写出可靠的答案,因为它基本归结为“取决于”。 一般来说,只要将组件库升级到一个 – 通过validation – JSF 2.0兼容版本就足够了。 最好的办法就是写unit testing,在升级之前和之后运行它们,并单独解决任何问题。

这里至less有一些有关特定组件库迁移的有用链接:

  • RichFaces迁移指南 – 3.3.x至4.x迁移
  • IceFaces 2 Wiki – IceFaces 1.x兼容性指南

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>引用。

有一件事要提的是,如果有人在JSF 1.2中使用JSTL,那么当升级到JSF2时,你应该改变命名空间:

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

至:

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

在web.xml

  Add the jars 1. jsf-api-2.0.jar 2. jsf-impl.2.0.2.jar 

第1步:更改web.xml

 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <servlet> <servlet-name>facesServlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.jsf</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.faces</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>facesServlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping> 

第2步:webmvc-config.xml

 <!-- Handles requests mapped to the Spring Web Flow system --> <bean id="flowController" class="org.springframework.webflow.mvc.servlet.FlowController"> <property name="flowExecutor" ref="flowExecutor" /> <property name="ajaxHandler"> <bean class="org.springframework.faces.webflow.JsfAjaxHandler" /> </property> </bean> 

第三步:facess-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.0有许多新的function和组件,我不觉得迁移将是痛苦的。 只有你会发现使用第三方图书馆很困难。 如果您的应用程序严重依赖像Richfaces这样的库,那么您将面临问题。 并非所有来自Richfaces 3的组件都移植到Richfaces 4。

这也可能有助于将JSF 1.2应用程序迁移到JSF 2.0

另外检查这是什么JSF 2中的新function?

如果您正在使用Apache Trinidad,则还必须将其升级到版本2.0,以便它将支持JSF 2.0。 黑客的瓦尔哈拉有更多的信息。