การย้ายข้อมูลจาก JSF 1.2 เป็น JSF 2.0


136

ฉันกำลังทำงานร่วมกับแอพพลิเคค่อนข้างใหญ่เขียนในJSF 1.2 JSF 1.2 มีอายุประมาณ 6 ปี ฉันต้องการอัปเกรดเป็น JSF 2.0 จะเจ็บปวดขนาดไหน? ฉันสังเกตเห็นว่ามีการเปลี่ยนแปลงคุณลักษณะบางอย่างในแท็กที่กำหนดเองเป็นต้น

คำตอบ:


246

ความเจ็บปวด

ความเจ็บปวดจากการอัปเกรด 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 ลงใน/WEB-INF/lib(ถ้า JSF 1.2 เป็น servletcontainer ที่ให้มาคุณอาจต้องการเปลี่ยนนโยบายการโหลดคลาสเพื่อโหลดไลบรารี webapp ก่อนก่อนไลบรารี servletcontainer โปรดดูปัญหาการโหลดคลาส 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">
    

    หมายเหตุ: เมื่อคุณใช้ JSF 2.2 หรือใหม่กว่าให้ใช้http://xmlns.jcp.orgโดเมนเนมสเปซแทนhttp://java.sun.comข้อมูลโค้ด XML ด้านบน

  • ตรวจสอบให้แน่ใจว่าการประกาศ root web.xmlเป็นไปตามอย่างน้อย 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">
    

    หมายเหตุ: เมื่อคุณใช้ Servlet 3.0 หรือใหม่กว่าให้ใช้http://xmlns.jcp.orgโดเมนเนมสเปซแทนhttp://java.sun.comข้อมูลโค้ด XML ด้านบน


JSP 2.x ถึง JSP 2.x

หากคุณกำลังใช้JSP 2.xและต้องการที่จะให้ใช้มันแล้วคุณโดยทั่วไปไม่จำเป็นต้องเปลี่ยนแปลงอะไรอื่น

ค่อยๆอัพเกรด

หากคุณใช้คำต่อท้ายurl-patternสำหรับสิ่งที่FacesServletชอบอยู่*.jsfแล้วคุณควรทราบว่าไฟล์FacesServletจะสแกนหา*.xhtmlไฟล์ก่อนและหากไม่มีอยู่ให้สแกนหา*.jspไฟล์ สิ่งนี้ช่วยให้คุณมีพื้นที่ในการค่อยๆแปลงจาก JSP เป็น Facelets เบื้องหลังโดยไม่ต้องเปลี่ยน URL

แต่ถ้าคุณใช้คำนำหน้าurl-patternเช่น/faces/*และคุณต้องการค่อยๆอัปเกรดจาก JSP เป็น Facelets คุณต้องเปลี่ยนเป็น*.jsfและอาจเป็นลิงก์ทั้งหมดในหน้า JSP ที่มีอยู่

คุณเพียงต้องจำไว้ว่า JSF 2.0 ใหม่ที่ให้การนำทางโดยนัยไม่สแกนหาไฟล์ที่มีอยู่ แต่ก็จะไปที่outcome.xhtmlอยู่ดี ดังนั้นหากคุณต้องการมาจากหรือไปที่*.jspคุณยังต้องรวมไว้ใน viewid ด้วยวิธี JSF 1.x


Facelets 1.x ถึง Facelets 2.0

หากคุณใช้Facelets 1.xเป็นเทคโนโลยีมุมมองและต้องการใช้Facelets 2.0 ที่ให้มาด้วย JSF 2.0 คุณต้องทำตามขั้นตอนเพิ่มเติมดังต่อไปนี้:

  • นำ Facelets JAR 1.x /WEB-INF/libจาก
  • นำ Facelets 1.x จากFaceletViewHandlerfaces-config.xml
  • FaceletViewHandlerการใช้งานแบบกำหนดเองใด ๆจำเป็นต้องได้รับการอัปเดตเพื่อขยายViewHandlerWrapperแทน
  • ไม่จำเป็น แต่สำหรับการล้างข้อมูลให้ลบ<context-param>ค่าที่เกี่ยวข้องกับ Facelets 1.x 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เป็นเทคโนโลยีมุมมองและคุณต้องการอัปเกรดเป็น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 หรือใหม่กว่าให้ใช้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 ด้านบน

การเปลี่ยนแปลงองค์ประกอบที่กำหนดเอง

คุณต้องเปลี่ยนไฟล์ JSP TLD เป็นไฟล์ Facelets TLD ตามที่อธิบายไว้ในคู่มือการย้าย Mojarraนี้


ควันหลง

ไม่ว่าจะใช้วิธีการย้ายข้อมูลแบบใดคุณค่อยๆกำจัด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 {}

In this particular example, it will be #{someBean}.

Any <managed-property> can be annotated using @ManagedProperty:

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

Any <validator> can be annotated using @FacesValidator:

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

Any <converter> can be annotated using @FacesConverter

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

Any <renderer> can be annotated using @FacesRenderer

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

Any <navigation-case> which uses the filename of the XHTML page as both <from-outcome> and <to-view-id> can be removed since this will be implicitly done. This can be gradually done by changing all outcome values to match the filename of the target view.

Finally, any session scoped bean which was been put in the session with the sole reason to retain the bean data in subsequent requests in the same tab/window can better be marked @ViewScoped, because this way the bean won't be affected when the enduser opens the same page in different tabs/windows.


Component libraries

Note that I don't take any 3rd party componant libraries like PrimeFaces/RichFaces/IceFaces into account in this answer, it would then be impossible to write a reliable answer since it basically boils down to "it depends". In general it's sufficient to just upgrade the component library to a -by themselves verified- JSF 2.0 compatible version as per their instructions. Best is to just write unit tests, run them before and after the upgrade and fix any issues individually.

Here are at least some useful links with regard to migration of the specific component library:

PrimeFaces has no migration guide for PrimeFaces 1.x to 2.x as PrimeFaces 1.x requires Facelets 1.x already, so you just have to follow Facelets 1.x to 2.x migration steps. However, there's a PrimeFaces 2.x to 3.x (and higher) migration guide which might apply as well on migrating from PrimeFaces 1.x to 3.x (or higher). Tomahawk has also no migration guide. Basically the only which you need to change are the JARs and if necessary get rid of all <t:saveState> references on a request scoped bean by making the bean view scoped.


@ManagedBean(name="managedBeanName") @RequestScoped It is :)
Daniel Szalay

great post, helped me a lot. Something to note: when moving from jsf 1.2 to jsf 2 you can be almost certain people have used a4j from richfaces 3.3.x. I decided to use richfaces 3.3.3 together with jsf 2 since it seemed like a mediocre change to perform to upgrade to richfaces 4.x . So I did your guide (undid all facelets related things in faces-config (activated viewhandler removed taglig annotation), then followed community.jboss.org/wiki/RichFaces333AndJSF20 and finally had to do this stackoverflow.com/questions/85532/…
Toskan

Great answer. In my case I also had to set the javax.faces.VALIDATE_EMPTY_FIELDS parameter to false to get the validation sorted. See also: stackoverflow.com/questions/6113935/…
Jasper de Vries


1
@Cfold: I fixed the link.
BalusC


6

JSF 2.0 have many new features and components and I don't feel migration will be painful. Only area you will find difficult is in using thrid party libraries. If your application is heavily dependant upon libraries like Richfaces then you will face problem. Not all the components from Richfaces 3 is ported to Richfaces 4.

This also might help JSF 1.2 application migration to JSF 2.0

Also check this What is new in JSF 2?


It would have been the same when you use Richfaces with JSF 1.x- you go through all the "pain" to find out how to integrate third party components with JSF. The approach to JSF 2.x is no difference. That's the "joy" of programming isn't it? :)
ChuongPham

4

Web.xml

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

Step 1: Change 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>

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.