从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.xFaceletViewHandler
。 - 任何自定义的
FaceletViewHandler
实现都需要更新来扩展ViewHandlerWrapper
。 - 不是必需的,但只是为了清理,从
web.xml
删除Facelets 1.x中与Facelets 2.0相关的<context-param>
值,例如值为*.xhtml
的javax.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
可用。 如果您省略@ManagedBean
的name
属性,那么它将默认为第一个字符小写的类名。
@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时,你应该改变命名空间:
至:
在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。 黑客的瓦尔哈拉有更多的信息。