Nis 01

Jsf 2.0 ile gelen yenilikler ve jsf 1.2 ile karsilastirilmasi

Prş 01 Nis 2010 01:33:37 | 6 yorum

  
Merhaba, bu makalemizde jsf 2.0 ile gelen yeniklerden ve Jsf 1.2 ile farklarindan, jsf 1.2 ile uyguladigimiz kodlari jsf 2.0 ile nasil
yaptigimizdan bahsetmeye calisacagim. Oncelikle jsf 2.0`in bize cok buyuk kolayliklar sagladigini belirtmek isterim, mesala artik applicatin.xml
dedigimiz diger bi adiyla faces-config.xml dosyasini jsf 2.0 ile kullanmamiza gerek kalmiyor, herseyi annotation`lar yardimi ile
kolaylikla yapiyoruz, ve bize xml ayar dosyalari ile ugrasmak degil, rahat rahat kod olusturmak kaliyor. Ilk karsilastirmamizdan baslayalim isterseniz.

Diyelim ki, birtane Backing Bean`imin olsun.

 

jsf 1.2 ile asagidaki sekilde kullaniyorduk.

 

UserBean.java

public class UserBean{
 
 private String name;
 
 getter / setter;
}

 

faces-config.xml

 

<managed-bean>
        <managed-bean-name>userBean</managed-bean-name>
        <managed-bean-class>net.aslan.UserBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
</managed-bean>

 

bu sekilde kullaniyorduk, ama jsf 2.0 ile yapacagimiz sey cok basit, tek yapmamiz gereken classimiz uzerinde annotation olarak gostermek :)

 

Jsf 2.0 ile

 

import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;

 

@ManagedBean(name="userBean")
@RequestScoped
public class UserBean{
 
 @ManagedProperty("Ertugrul")
 private String name;
 
 getter / setter;
}


hepsi bukadar. Artik UserBean backing beanimiz hazir. normal bi sekilde kullanabiliriz. Ve tabiki istenildi
durumda projede faces-config.xml dosyasi kullanilabilinir.

 

 

Bu sekilde annotationlar yardimi ile converter`larimizi, validator`larimizi olusturabiliriz, bunlarida karsilastiracak olursak

Jsf 1.2 ile kullanimi

 

<converter>
        <converter-id>DateConverter</converter-id>
        <converter-class>net.aslan.jsf.converters.DateConverter</converter-class>
</converter>

<!-- =========== Validators ================================== -->
    <validator>
        <validator-id>emailValidator</validator-id>
        <validator-class>net.aslan.jsf.validators.EmailValidator</validator-class>
    </validator>

 

bu sekilde faces-config.xml icinde olusturuyorduk ve, kullanirken
 
<h:inputText  value="#{userBean.user.date}">
        <f:converter converterId="DateConverter"/>
</h:inputText>

 

ve validatorlarida ayni sekilde kullaniyorduk. simdi jsf 2.0 ile ne kadar kolay yapilidigina bakalim.

 

import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;

 

@FacesConverter(value = "dateConverter")
public class DateConverter implements Converter {

}

 

bu sekilde classimizi converter olarak gosteriyoruz ve,

 

<h:inputText converter="dateConverter" value=""/>

 

yapmamiz gereken bukadar. validatorlarimizida ayni sekilde kullaniyoruz

 

import javax.faces.validator.FacesValidator;

 

@FacesValidator(value = "emailValidator")
public class EmailValidator implements Validator {

}

 

bu sekilde,

 

Kendi olusturdugumuz custom componentlerimizide, diger http://www.jtpd.org/wiki/257311 makalemizde oldugu gibi yine annotation ile belirtiyoruz ve kullanabiliyoruz.


Gordugunuz gibi faces-config.xml ayar dosyasina hic bi sekilde ihtiyacimiz kalmadi..

 

Peki jsf 1.2 ile jsf 2.0 farklar bu kadar, elbetteki hayir. Simdi tek tek inceleyelim.
Oncelikle benimde daha once cok sorun yasadigim, url`nin diger sayfaya gittiginde degismeden kalmasi, diger sayfaya giderken url`nin
degismesi icin <redirect /> yapiyorduk, bu defada diger sayfaya giderken veriyi koruyamiyorduk.
Jsf 2.0 ile birlikte cok guzel bi cozum yolunu bulunmus ve benimde cok hosuma gitti :)

kullanimi asagidaki sekilde,

 

 <navigation-rule>
        <navigation-case>
            <from-outcome>edit</from-outcome>
            <to-view-id>/edit.xhtml</to-view-id>
            <redirect include-view-params="true"/>
        </navigation-case>
    </navigation-rule>
 
 tek yapmamiz gereken <redirect include-view-params="true"/> bu satiri kullanmamiz, bu sekilde kullaninca artik url`i istedigimizde sekilde
 degistirebiliyoruz ve en guzelide verileri kaybetmiyoruz :).
 Bu kismi ayrintili bi sekilde incelemek icin, asagidaki linkden faydalanabilirsiniz.
 
 
http://blogs.sun.com/enterprisetechtips/entry/post_redirect_get_and_jsf
 
 Ve bu ozelliklerden daha dogrusunu soylemek gerekirse, J2EE 6 ile gelen yeniklerden ve JSP page`inin yerine facelets`lar gibi cok hizli calisan ve cok cok kullanisli olan bi teknolojilenin J2ee specification`a eklemesi.

 

 facelets`larin bize ne gibi yararlar saglandigi baska bir makalede genis
 ve uygulamali bir sekilde gorecez. burada facelets`lar ile gelen template ozelliginden biraz bahsetmek istiyorum. Uygulamamiz icin sablaon olusturmak ve bunu jsp`de oldugu gibi her sayfada tekrar tekrar kullanmak gibi cok buyuk bi zahmetten kurtariyor bizi, butun bunlari diger bi makelede uyuglamali
 bi sekilde gorecegiz. faceletsler ile jsf 2.0 asagidaki gibi kullaniyoruz.
 
 template.xhtml sayfamiz.
 
 <?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml"
      xmlns:ui="
http://java.sun.com/jsf/facelets"
      xmlns:h="
http://java.sun.com/jsf/html">
  <h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Facelets - Template Example</title>
  </h:head>
  <h:outputStylesheet library="css" name="default.css"/>
  <body>
    <h1>
      <ui:insert name="title">Howto Samples</ui:insert>
    </h1>
    <h:link outcome="home" value="Back to Home Page"/>
      <p>
        <ui:insert name="body">Welcome</ui:insert>
      </p>
  </body>
</html>

 

 ve bu template`i
 
 <?xml version='1.0' encoding='UTF-8' ?>
<body xmlns="
http://www.w3.org/1999/xhtml"
      xmlns:ui="
http://java.sun.com/jsf/facelets"
      xmlns:h="
http://java.sun.com/jsf/html"
      xmlns:f="
http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
  <ui:define name="title">
    Sayfa ust Kismi
  </ui:define>
  <ui:define name="body">
    <div>#{userBean.name}</div>
  </ui:define>
</ui:composition>
</body>

 

bu sekilde cok cok rahat bi sekilde kullaniyoruz. dedigim gibi diger makalede cok genis bi sekilde kullanacaz.
Burada dikkat ettiyseniz,
<h:outputStylesheet library="css" name="default.css"/>

bu sekilde bi satirimiz var, burada <h:outputStylesheet bu component jsf 2.0 ile birlikte gelmekte ve css, image, js, dosyalarimizi yukaridaki gibi kullanarak cok rahat bi sekilde istedigimiz sayfada kullanabiliyoruz ve bize cok buyuk kolayliklar saglaniyorlar. Buradan sunu anliyoruz ki bize dusen tek sey ayar dosyalariyla falan ugrasmak degil java ile uygulama gelistirmenin zevkini cikarmak :).

 

Diger bi yenilikden bahsedecek olursak, jsf 1.2`de metodlarin parametre degerlerini kullanamiyorduk, yani parametre alan bi metodu cagrip parametre veremiyorduk. Jsf 2.0 ile parametre alan metodlara parametre gonderip kullanabiliyoruz, hemen basit ve bizim icin cok faydali olacak bi ornek uzeriden gosterirsek.


Mesala list.xhtml sayfamizda, datatable ile listenen satirlarinin birinin uzerine tikladigimizda detay sayfasinda verinin gosterilmesi

 

jsf 1.2 ile bunu,

 

HtlmDataTable`i kullanarak, getRowData metodunu cagrip secilen satirdaki nesneyim bizim Object nesnemiz`e atiyorduk, yani

 


public class UserBean{

User selectedUser;
HtmlDatatable dataTable;


public HtmlDatatable getDataTable(){
 return dataTable;
}

public void setDataTable(HtmlDatatable dataTable){
 this.dataTable = dataTable;
}


public String detail(){
 selectedUser = dataTable.getRowData();
 return "detail";
}
 
 
<h:datatable binding="#{userBean.dataTable}" value="#{userBean.list}" var="user">

<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</facet>
<h:commanLink action="#{userBean.detail}" value="user.name"/>
</column>

.......
......
</h:datatable>

genel itibariyle busekilde kullaniyorduk, yani HtmlDatatable componentinin ozellikleri kullanip, datatable`imizi buna binding yaparak yapmaya calisiyorduk. ve birde bunun faces-config.xml ayar dosyalari falani var :)..

 

Peki ayni ornegi jsf 2.0 nasil yapabiliriz,

 

@ManagedBean
public class UserBean{

User selectedUser;


public String detail(User user){
 selectedUser = user;
 return "detail";
}

 

 


<h:datatable binding="#{userBean.dataTable}" value="#{userBean.list}" var="user">

<h:column>
<f:facet name="header">
<h:outputText value="Name"/>
</facet>
<h:commanLink action="#{userBean.detail(user)}" value="user.name"/>
</column>
......
.....
</h:datatable>

 

gordugunuz gibi bu kadar basit, yani datatable`dan gelen user nesnesini, commandLinki`imizin action`unda parametre olarak giriyoruz ve bunu detail metodumuza parametre olarak gondererek ve esitliyoruz :).

Bu uygulamaya asagidaki sekilde... Netbeans`de kullanimi..

 

 

DataBean.java

 

package net.aslan.jsf.controller;

 

import java.io.Serializable;
import java.util.List;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import net.aslan.beans.Person;
import net.aslan.beans.PersonRemote;

/**
 *
 */
@ManagedBean
@SessionScoped
public class DataBean implements Serializable {

 

    @EJB
    private PersonRemote pr;
    private Person selectedPerson;

 

    public List<Person> getPersons() {
        return pr.findAll();
    }

 

    public String detail(Person person) {
        selectedPerson = person;
        return "detail?faces-redirect=true&amp;includeViewParams=true";
        // bu sekilde kullaninca veriyi kabetmeden url`i oldugu sayfada gosterebiliriz.
        // istenildigi durumda faces-config.xml`de navigation`lardada kullanilabilir
.
    }

 

    public Person getSelectedPerson() {
        return selectedPerson;
    }

 

    public void setSelectedPerson(Person selectedPerson) {
        this.selectedPerson = selectedPerson;
    }

}

 

Person.java

 

package net.aslan.beans;

 

import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

/**
 *
 * @author ertugrul
 */
@Entity
public class Person implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;
    private String lastname;
    private String email;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        // TODO: Warning - this method won't work in the case the id fields are not set
        if (!(object instanceof Person)) {
            return false;
        }
        Person other = (Person) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public String toString() {
        return "accr.beans.Person[id=" + id + "]";
    }
}

 

 

PersonRemote.java

 

package net.aslan.beans;

import java.util.List;

/**
 *
 * @author ertugrul
 */
public interface PersonRemote {

 

    public void create(Person Person);

    public void edit(Person Person);

    public List<Person> findAll();


}

 

PersonEJB.java

 

package net.aslan.beans;

 

import java.util.List;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 *
 * @author ertugrul
 */
@Stateless
public class PersonEJB implements PersonRemote {

 

    @PersistenceContext
    EntityManager em;

 

    public void create(Person Person) {
        em.persist(Person);
    }

 

    public void edit(Person Person) {
        em.merge(Person);
    }

 

    public List<Person> findAll() {
        return em.createQuery("select object(o) from Person as o").getResultList();
    }
}

 

 

index.xhtml

 

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">

    <h:body>
        <h:outputStylesheet name="css/datatablestyle.css"/>
        <h:form>
            <h:dataTable value="#{dataBean.persons}" var="person" border="1"
                         styleClass="datatable" cellpadding="2"
                         cellspacing="0" rowClasses="row-odd, row-even">
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Name"/>
                    </f:facet>
                    <h:commandLink value="#{person.name}" action="#{dataBean.detail(person)}"/>
                </h:column>
                <h:column>
                    <f:facet name="header">
                        <h:outputText value="Last Name"/>
                    </f:facet>
                    <h:outputText value="#{person.lastname}"/>
                </h:column>
            </h:dataTable>
        </h:form>
    </h:body>
</html>


 

detail.xhtml

 

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml"
      xmlns:h="
http://java.sun.com/jsf/html">

    <h3>Detail Person</h3>
    <h:form>
        <h:panelGrid columns="2">
            <h:outputText value="Name : "/>
            <h:outputText value="#{dataBean.selectedPerson.name}"/>
            <h:outputText value="LastName : "/>
            <h:outputText value="#{dataBean.selectedPerson.lastname}"/>
            <h:outputText value="Email : "/>
            <h:outputText value="#{dataBean.selectedPerson.email}"/>
        </h:panelGrid>
        <h:commandButton value="cancel" action="index" immediate="true"/>
    </h:form>

</html>

 

datatablestyle.css


.datatable{
    border: 1px solid olive;
}

.datatable thead th{
    background-color: #dfdfdf;
    border-bottom: 1px solid olive;
    padding: 4px;
}

.row-odd td{
    padding: 4px;
    background-color: #ddffcc;
}

.row-even td{
    padding: 4px;
    background-color: #cceebb;
}


dataTable tfoot {
    background-color: #999;
}

 

 

uygulamanin netbeans`de dizin yapisinin gorunmesi

 


 

 

 

sonuc olarak...

 

 

 

 

 

 

detail..

 

 

 

 

Yenilikler elbetteki bunlarla sinirli degil, zaman buldukca yine bu blogda karsilastigim yeniliklerden bahsedecegim.

Degiserek gelismeniz dilegiyle..

 

Ertugrul ASLAN..

 

 

Yorum

Bu makale jsf 2.0 ile gelen yeniliklerden bahsetmek icin, bi acilis makalesi niteliginde olmusdur. Diger makalelerimizde yenilikleri orneklerle beraber uygulamali bi sekilde gorecez. Kolay Gelsin...
Ertugrul hocam, eline saglik cok faydali bir makale olmuş. En cok begendigim ozellik actionlara parametre gecebilmek oldu. Bu senin de anlattigin gibi bizi bir suru fazladan kod yazmaktan kurtariyor..tesekkurler.. devamini bekliyoruz...
Bu yazinizda cok super olmus elinize saglik
Tek kelimeyle super dokuman Ertugrul hocam faydasi cok olucak benim icin .... Tesekkurler .. Baska makalelerinizi merakla bekliyorum .
Iyi calismlar ...
Herkese yorumlarindan dolayi cok tesekkur ederim..
Evet Serhat hocam o ozellik gercektence cok mukemmel heryerde cok rahat bi sekilde metodlara parametre gonderip istediklerimizi yapabiliyoruz.
Makalelerin devami gelecektir, cok yakin zamanda yeni makaler yazmaya calisacam. Herkese Kolay Gelsin...
Selam,

guzel yazi olmus. tek bir yorumum var sadece, <h:commanLink action="#{userBean.detail(user)}" ... /> kismindaki metoda parametre gonderme sadece glassfish'de var, tomcat ve jetty'de yok diye biliyorum. ama bunun disinda guzel ve bilgilendirici bir yazi, eline saglik.



ya da
CAPTCHA Images