Migracja z JSF 1.2 do JSF 2.0

136

Pracuję z dość dużą aplikacją napisaną w JSF 1.2 . JSF 1.2 ma już około 6 lat. Muszę zaktualizować do JSF 2.0. Jak bolesne to będzie? Zauważyłem, że niektóre atrybuty w tagach niestandardowych zostały zmienione itp.

mkoryak
źródło

Odpowiedzi:

245

Bolesność

Uciążliwość aktualizacji JSF 1.2 do 2.0 zależy od technologii widoku, której aktualnie używasz i której chcesz użyć.

  • JSP 2.x do JSP 2.x = prawie bez wysiłku.
  • Facelets 1.x do Facelets 2.0 = Mały wysiłek.
  • JSP 2.x do Facelets 2.0 = Dużo wysiłku. Podwój tę wartość, jeśli masz również niestandardowe komponenty.

Podstawowe zmiany

Niezależnie od zmiany technologii wyświetlania należy wykonać przynajmniej następujące czynności:

  • Usuń pliki JSF 1.2 JAR z /WEB-INF/lib(jeśli istnieją).
  • Upuść pliki JAR JSF 2.0 /WEB-INF/lib(jeśli JSF 1.2 był dostarczony przez servletcontainer, możesz chcieć zmienić zasady ładowania klas, aby najpierw ładować biblioteki webapp, a nie biblioteki servletcontainer, zobacz także problemy z ładowaniem klas JSF2 na serwerach aplikacji ).
  • Zaktualizuj deklarację główną, faces-config.xmlaby była zgodna ze specyfikacją 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">
    

    Uwaga: jeśli używasz formatu JSF 2.2 lub nowszego, użyj http://xmlns.jcp.orgdomeny przestrzeni nazw zamiast http://java.sun.compowyższego fragmentu XML.

  • Upewnij się, że deklaracja root web.xmljest już zgodna co najmniej z serwletem 2.5. JSF 2.0 nie będzie działać na 2.4 lub niższym ( chociaż można go zhakować ).

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

    Uwaga: jeśli używasz Servlet 3.0 lub nowszego, użyj http://xmlns.jcp.orgdomeny przestrzeni nazw zamiast http://java.sun.compowyższego fragmentu XML.


JSP 2.x do JSP 2.x

Jeśli używasz JSP 2.xi chcesz nadal go używać, to w zasadzie nie musisz niczego zmieniać.

Stopniowa aktualizacja

Jeśli używasz już sufiksu url-patterndla FacesServlet, like *.jsf, dobrze jest wiedzieć, że FacesServletnajpierw przeskanuje *.xhtmlplik, a jeśli go nie ma, następnie skanuje w poszukiwaniu *.jsppliku. Zapewnia to miejsce na stopniową konwersję z JSP do Facelets za kulisami bez zmiany adresów URL.

Ale jeśli używasz prefiksu url-pattern, takiego jak /faces/*i chcesz stopniowo przechodzić z JSP do Facelets, to naprawdę musisz zmienić go na, *.jsfa być może także wszystkie łącza na istniejących stronach JSP.

Musisz tylko pamiętać, że nowy JSF 2.0 zapewniający niejawną nawigację nie skanuje pod kątem obecności pliku, i tak przejdzie do outcome.xhtml. Więc jeśli chcesz przyjechać lub udać się do *.jsp, nadal musisz uwzględnić to w viewid sposób JSF 1.x.


Facelets 1.x do Facelets 2.0

Jeśli używasz Facelets 1.x jako technologii widoku i chcesz korzystać z Facelets 2.0 dostarczonego przez JSF 2.0 , musisz wykonać następujące dodatkowe kroki:

  • Usuń Facelets 1.x JAR z /WEB-INF/lib.
  • Usuń Facelets 1.x FaceletViewHandlerz faces-config.xml.
  • Zamiast tego każdą niestandardową FaceletViewHandlerimplementację należy zaktualizować, aby ją rozszerzyć ViewHandlerWrapper.
  • Nie jest to konieczne, ale tylko w celu oczyszczenia, usuń wszystkie <context-param>wartości związane z Facelets 1.x, z web.xmlktórych są już domyślne w Facelets 2.0, takie jak javax.faces.DEFAULT_SUFFIXwartość with *.xhtml.
  • Zaktualizuj główną deklarację istniejących plików XML taglib Facelet, aby były zgodne z 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">
    

    Uwaga: jeśli używasz formatu JSF 2.2 lub nowszego, użyj http://xmlns.jcp.orgdomeny przestrzeni nazw zamiast http://java.sun.compowyższego fragmentu XML.

W zasadzie to powinno być to.


JSP 2.x do Facelets 2.0

Jeśli używasz JSP 2.x jako technologii wyświetlania i chcesz natychmiast zaktualizować do Facelets 2.0 , musisz wprowadzić wiele zmian, zanim witryna zostanie uruchomiona. Zasadniczo zmieniasz tutaj technologię wyświetlania.

Zmiany na stronie wzorcowej

Na każdej stronie wzorcowej należy zmienić następujący podstawowy szablon 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>

..do następującego podstawowego szablonu 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>

Uwaga: jeśli używasz JSF 2.2 lub nowszego, użyj http://xmlns.jcp.orgdomeny przestrzeni nazw zamiast http://java.sun.comwszystkich powyższych fragmentów XHTML.

Uwzględnij zmiany na stronie

Jeśli istniejące strony JSP są dobrze zaprojektowane, nie powinieneś mieć żadnej linii kodu skryptletu, a także powinieneś mieć tylko <jsp:include>jako jedyny znacznik specyficzny dla JSP. Każdy z tych elementów należy zmienić z:

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

do

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

Podstawowy JSP zawiera szablon strony ...

<%@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>

.. należy zmienić na następujące podstawowe Facelety obejmują szablon strony:

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

Uwaga: jeśli używasz JSF 2.2 lub nowszego, użyj http://xmlns.jcp.orgdomeny przestrzeni nazw zamiast http://java.sun.comwszystkich powyższych fragmentów XHTML.

Niestandardowe zmiany komponentów

Musisz zmienić pliki JSP TLD na pliki Facelets TLD zgodnie z opisem w tym przewodniku migracji Mojarra .


Następstwa

Niezależnie od podejścia migracyjnego, możesz stopniowo wyeliminować faces-config.xmlnowe adnotacje JSF 2.0 lub nawet CDI . Każdy <managed-bean>może zostać opatrzony adnotacją @ManagedBean:

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

Obok @RequestScopedznajdują się również @ViewScoped, @SessionScopedi @ApplicationScopeddostępne. Jeśli pominiesz nameatrybut the @ManagedBean, to domyślnie zostanie przyjęta nazwa klasy z pierwszym znakiem małej litery.

@ManagedBean
@RequestScoped
public class SomeBean {}

W tym konkretnym przykładzie tak będzie #{someBean}.

Do każdego <managed-property>można dodać adnotację za pomocą @ManagedProperty:

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

Do każdego <validator>można dodać adnotację za pomocą @FacesValidator:

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

Każdy <converter>może zostać opatrzony adnotacją za pomocą@FacesConverter

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

Każdy <renderer>może zostać opatrzony adnotacją za pomocą@FacesRenderer

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

Każdy, <navigation-case>który używa nazwy pliku strony XHTML jako obu <from-outcome>i <to-view-id>może zostać usunięty, ponieważ zostanie to zrobione niejawnie . Można to zrobić stopniowo, zmieniając wszystkie wartości wyników, aby pasowały do ​​nazwy pliku widoku docelowego.

Wreszcie, każdy komponent bean o zasięgu sesji, który został umieszczony w sesji z jedynym powodem, aby zachować dane fasoli w kolejnych żądaniach w tej samej karcie / oknie, może być lepiej oznaczony @ViewScoped, ponieważ w ten sposób ziarno nie będzie miało wpływu po otwarciu użytkownika końcowego ta sama strona w różnych zakładkach / oknach.


Biblioteki komponentów

Zauważ, że w tej odpowiedzi nie biorę pod uwagę żadnych bibliotek komponentów innych firm, takich jak PrimeFaces / RichFaces / IceFaces, wtedy nie byłoby możliwe napisanie wiarygodnej odpowiedzi, ponieważ w zasadzie sprowadza się ona do „to zależy”. Ogólnie wystarczy zaktualizować bibliotekę komponentów do wersji zgodnej z JSF 2.0 przez samych zweryfikowanych, zgodnie z ich instrukcjami. Najlepiej jest po prostu napisać testy jednostkowe, uruchomić je przed i po uaktualnieniu oraz indywidualnie rozwiązać wszelkie problemy.

Oto co najmniej kilka przydatnych odsyłaczy dotyczących migracji określonej biblioteki komponentów:

PrimeFaces nie ma przewodnika migracji dla PrimeFaces 1.x do 2.x, ponieważ PrimeFaces 1.x wymaga już Facelets 1.x, więc wystarczy wykonać kroki migracji Facelets 1.x do 2.x. Istnieje jednak przewodnik migracji PrimeFaces 2.x do 3.x (i nowszy), który może mieć zastosowanie również w przypadku migracji z PrimeFaces 1.x do 3.x (lub nowszej). Tomahawk nie ma również przewodnika po migracji. Zasadniczo jedyne, co musisz zmienić, to pliki JAR i, jeśli to konieczne, pozbądź się wszystkich <t:saveState>odniesień w fasoli z zakresem żądania, ustawiając zakres widoku fasoli.

BalusC
źródło
@ManagedBean (name = "managedBeanName") @RequestScoped It is :)
Daniel Szalay
świetny post, bardzo mi pomógł. Coś do zapamiętania: po przejściu z jsf 1.2 do jsf 2 można być prawie pewnym, że ludzie używali a4j z richfaces 3.3.x. Zdecydowałem się użyć richfaces 3.3.3 razem z jsf 2, ponieważ wydawało się, że aktualizacja do Richfaces 4.x była przeciętna. Zrobiłem więc twój przewodnik (cofnąłem wszystkie aspekty związane z faceletami w face-config (aktywowany viewhandler usunął adnotację taglig), a następnie podążyłem za community.jboss.org/wiki/RichFaces333AndJSF20 i ostatecznie musiałem to zrobić stackoverflow.com/questions/85532/ ...
Toskan
Świetna odpowiedź. W moim przypadku musiałem również ustawić javax.faces.VALIDATE_EMPTY_FIELDSparametr na, falseaby uzyskać posortowaną walidację. Zobacz też: stackoverflow.com/questions/6113935/…
Jasper de Vries
2
Mogę również polecić wszystkim przeczytanie balusc.blogspot.nl/2011/09/communication-in-jsf-20.html
Jasper de Vries
1
@Cfold: naprawiłem link.
BalusC
7

Należy wspomnieć, że jeśli ktoś używa JSTL z JSF 1.2, to podczas aktualizacji do JSF2 należy zmienić przestrzeń nazw z:

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

do:

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

Rafał G.
źródło
2
Uwaga: dotyczy to tylko migracji z Facelets 1.x do 2.x.
BalusC
A dla wersji 2.2 i
nowszych
6

JSF 2.0 ma wiele nowych funkcji i komponentów i nie czuję, że migracja będzie bolesna. Jedynym obszarem, który będzie trudny, jest korzystanie z bibliotek firmowych. Jeśli Twoja aplikacja jest w dużym stopniu zależna od bibliotek, takich jak Richfaces, napotkasz problem. Nie wszystkie komponenty z Richfaces 3 są przenoszone do Richfaces 4.

Może to również pomóc w migracji aplikacji JSF 1.2 do JSF 2.0

Sprawdź również to. Co nowego w JSF 2?

mvg
źródło
Byłoby tak samo, gdybyś używał Richfaces z JSF 1.x - przechodzisz przez wszystkie "problemy", aby dowiedzieć się, jak zintegrować komponenty stron trzecich z JSF. Podejście do JSF 2.x nie ma różnicy. To jest „radość” programowania, prawda? :)
ChuongPham
4

Web.xml

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

Krok 1: Zmień plik 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>

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

Krok 3: 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">
Pravin
źródło
0

Jeśli używasz Apache Trinidad, musisz również zaktualizować go do wersji 2.0, aby obsługiwał JSF 2.0. Więcej informacji znajdziesz w Hacker's Valhalla .

desygnować void
źródło