Java’da JSF ve PrimeFaces kullanarak JSON nesnesi işleme Öğretisi

Bu yazımda döviz kurları bilgi akışı içeren bir JSON nesnesini işleyip, bir web sayfası üzerinde JSF 2.1 framework’ü ve JSF için bir zengin bileşen kütüphanesi olan PrimeFaces 2.2 kullanarak AJAX ve Web 2.0 özellikleri ile nasıl görünteleyebileceğimizi göreceğiz.

Bu öğretiyi uygulamak için nelere ihtiyacınız var

  • Oracle JDK 1.6 veya sonraki bir sürümü
  • Netbeans 7.0 veya daha yeni bir sürümü (farklı bir editör ve geliştirme ortamı kullanmayı tercih ederseniz, Gerekli kütüphane ve bileşenlerin tümünü manuel olarak projeye dahil etmeniz gerekebilir. Bkz. sonraki bölüm)
  • Tomcat 7

Kullanılan teknoloji ve kütüphaneler

  • JSF 2.1 (Mojarra 2 kütüphaneleri yani jsf-api.jar, jsf-impl.jar, jstl.jar ve standard.jar)
  • PrimeFaces 2.2.1
  • JSON (Java için)
  • commons-logging-1.1.1.jar
  • log4j-1.2.16.jar
  • httpcore-4.1.4.jar
  • httpclient-4.1.3.jar

Projeyi JSF 2 ve PrimeFaces desteği dahil olacak şekilde hazırlama

Netbeans’i açın ve aşağıdaki adımları sırayla izleyin:

  1. File menüsünden New Project (Ctrl-Shift-N; Mac’de ⌘-Shift-N) komutunu verin. Java Web kategorisini seçin, sonra Projects tiplerinden Web Application‘ı seçin. Next düğmesine basın.
  2. Project Name alanında projeye ‘dovizkurlariweb’ adını verin (tırnak işareti olmadan), ve Next düğmesine basın. NetBeans'de yeni Java EE 6 web projesi yaratma
  3. Bu adımda Java EE versiyonu (platform) açılır menüden Java EE 6 Web olarak seçin ve ‘Enable contexts and dependency injection’ kutusunun işaretini kaldırın. Ayrıca Server alanında açılır menüden Apache Tomcat 7 i seçin ve Next düğmesine basın.
    NetBeans'de Tomcat 7 için yeni proje oluşturma
  4. Bir sonraki ekranda da Frameworks listesinden Java Server Faces ‘i seçtikten sonra, Libraries sekmesi altında bulunan Java Server Faces Configuration başlıklı bölümde, Registered Libraries seçeneğini işaretleyip açılır menüden JSF 2.1 i seçin.Netbeans > Frmaeworks > JSF
  5. Şimdi Configuration sekmesine gidin, ‘preferred page language’ (tercih edilen sayfa dili) olarak “Facelets”i seçin, JSF Servlet URL pattern için ‘*.go’ gibi bir uzantı belirleyebilirsiniz. (JSF geliştiricileri tarafından en yaygın kullanılan uzantı ‘*.jsf’ olmakla beraber varsayılan (default) olarak Sun standartı ‘/faces/*’ gelmektedir. Ancak bu da uygulama URL’sine fazladan bir “faces/” ekler. )JSF Configuration in Netbeans
  6. Son olarak Components (bileşenler) sekmesini açıp PrimeFaces 2.2.1‘i seçtikten sonra Finish düğmesine basabilirsiniz.
  7. Şimdi bir adet JSF Managed Bean sınıfı hazırlayacağız, bu da tüm proje için bir kontolör (controller) görevini üstlenecek. Projeyi (dovizkurlariweb) sağ-tıklayın ve açılır menüden New > JSF Managed Bean… komutunu verin. (Eğer bu öğe menüde ilk etapta görünmezse, önce Other… seçtikten sonra gelen New File başlıklı pop-up pencerede JavaServer Faces > JSF Managed Bean i seçip devam edebilirsiniz).NetBeans'de yeni JSF Managed Bean oluşturma
  8. Bu ‘managed bean’ sınıfına ‘DovizKurlariBean‘ adını verin (tırnak işaretleri olmadan :), paket ismi olarak da ‘net.ozar.egitim.jsf.kurlar.managed‘ yazabilirsiniz, altta bulunan Name alanına ‘dovizKurlariBean‘ verip Scope için açılır menüden ‘application‘ı seçin. NetBeans'de Managed Bean yaratırken Scope belirleme
    Bu adımları tamamladıktan sonra Finish düğmesine basın .
  9. Bir önceki adımda oluşturduğumuz JSF Managed Bean sınıfının kaynak kodunu aşağıdaki gibi düzenleyin:
    package net.ozar.egitim.jsf.kurlar.managed;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import javax.annotation.PostConstruct;
    import javax.faces.application.FacesMessage;
    import javax.faces.bean.ManagedBean;
    import javax.faces.bean.ApplicationScoped;
    import javax.faces.context.FacesContext;
    import net.ozar.egitim.jsf.kurlar.pojo.DovizKur;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.log4j.Level;
    import org.apache.log4j.Logger;
    import org.json.JSONObject;
    
    /**
     * @author Gökhan Ozar
     * http://gokhan.ozar.net
     */
    @ManagedBean
    @ApplicationScoped
    public class DovizKurlariBean implements java.io.Serializable {
    
        /*
         * Ersin Koç'un örnek döviz kur uygulamasından esinlenilmiştir
         * http://www.ersinkoc.com
         */
    
        private static final String KURURL = "http://www.doviz.gen.tr/doviz_json.asp?version=1.2";
        private static final String HAKKINDA = "     
    Bu uygulama JSF 2, PrimeFaces 2 (Web 2.0 &amp; AJAX) ve JSON nesnesi işleme ile ilgili bir örnek teşkil etmesi için hazırlanmıştır. Daha fazla bilgi için <a href="\&quot;http://gokhan.ozar.net\&quot;">http://gokhan.ozar.net</a> sitesini ziyaret edebilirsiniz...  
    ";
    
        private DovizKur kur = new DovizKur();
        private String msj = HAKKINDA;
    
        public DovizKurlariBean() {
        }
    
        @PostConstruct
        public void kurlariYukle() {
            // System.out.println("Kurlar yükleniyor...");
            HttpClient webIstemci = new DefaultHttpClient();
            HttpGet webdenGetir = new HttpGet(KURURL);
            HttpResponse donenCevap;
    
            try {
                donenCevap = webIstemci.execute(webdenGetir);
                HttpEntity birim = donenCevap.getEntity();
                if (birim != null) {
                    InputStream gelenVeri = birim.getContent();
                    String sonuc = convertStreamToString(gelenVeri);
    
                    JSONObject json = new JSONObject(sonuc);
    
                    msj = json.getString("guncelleme").concat(HAKKINDA);
    
                    kur.setDolarAlis     (json.getString("dolar" ));
                    kur.setDolarSatis    (json.getString("dolar2"));
                    kur.setEuroAlis      (json.getString("euro"  ));
                    kur.setEuroSatis     (json.getString("euro2" ));
                    kur.setSonGuncelleme (json.getString("sonkayit").concat(HAKKINDA).replaceAll("\\", "")); // HTML etiketlerini kaldiriyoruz.
                    kur.setMesaj         (msj); 
    
                    FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_INFO, msj, msj);
                    FacesContext.getCurrentInstance().addMessage("successInfo", facesMsg);
    
                    gelenVeri.close();
                }
            } catch (Exception e) {
                msj= "Kurları almaya çalışırken bir hata oldu!\nSunucu bağlantısında bir problem olabilir!";
                kur.setMesaj(msj);
                Logger.getLogger(DovizKurlariBean.class.getName()).log(Level.ERROR, null, e);
                FacesMessage facesMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, msj, msj);
                FacesContext.getCurrentInstance().addMessage(null, facesMsg);
            }
    
        }
    
        public String convertStreamToString(InputStream is) {
            // Gelen veri akışı bir String değişkeni içine atılır
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line = null;
            try {
                while ((line = reader.readLine()) != null) {
                    sb.append(line).append("\n");
                }
            } catch (IOException e) {
            } finally {
                try {
                    is.close();
                } catch (IOException e) {
                }
            }
            return sb.toString();
        }
    
        public DovizKur getKur() {
            return kur;
        }
    
        public void setKur(DovizKur kur) {
            this.kur = kur;
        }
    }
  10. Şimdi JSON ile alınacak olan döviz kur bilgisini tutacak bir POJO (plain old Java object) nesnesine ihtiyacımız var. Bunun için net.ozar.egitim.jsf.kurlar.pojo paketi içinde adı DovizKur.java adında bir sınıf yaratıp içine aşağıdaki kodu yazalım:
    package net.ozar.egitim.jsf.kurlar.pojo;
    
    /**
     * @author Gökhan Ozar
     * http://gokhan.ozar.net
     */
    public class DovizKur implements java.io.Serializable {
    
        private String dolarAlis;
        private String dolarSatis;
        private String euroAlis;
        private String euroSatis;
        private String sonGuncelleme;
        private String mesaj;
    
        public String getDolarAlis() {
            return dolarAlis;
        }
    
        public void setDolarAlis(String dolarAlis) {
            this.dolarAlis = dolarAlis;
        }
    
        public String getDolarSatis() {
            return dolarSatis;
        }
    
        public void setDolarSatis(String dolarSatis) {
            this.dolarSatis = dolarSatis;
        }
    
        public String getEuroAlis() {
            return euroAlis;
        }
    
        public void setEuroAlis(String euroAlis) {
            this.euroAlis = euroAlis;
        }
    
        public String getEuroSatis() {
            return euroSatis;
        }
    
        public void setEuroSatis(String euroSatis) {
            this.euroSatis = euroSatis;
        }
    
        public String getMesaj() {
            return mesaj;
        }
    
        public void setMesaj(String mesaj) {
            this.mesaj = mesaj;
        }
    
        public String getSonGuncelleme() {
            return sonGuncelleme;
        }
    
        public void setSonGuncelleme(String sonGuncelleme) {
            this.sonGuncelleme = sonGuncelleme;
        }
    }
  11. Şimdi projenin Web Pages klasörüne gidip içindeki index.xhtml ‘i açıyoruz. Bu dosyanın da kaynak kodunu aşağıdaki gibi düzenlemeliyiz:
    <?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:p="http://primefaces.prime.com.tr/ui"
          xmlns:h="http://java.sun.com/jsf/html">
        <h:head>
            <title>Döviz Kurları</title>
        </h:head>
        <h:body>
            <h:form>
                <p:commandButton value="Döviz Kurlarını görüntüle" onclick="dlg1.show();" type="button" />
                <p:commandButton id ="ref" value="Yenile" ajax="true" action="#{dovizKurlariBean.kurlariYukle}" type="submit" update="dovizKurPaneli, dovizKurPaneli2" />
                <p:dialog id="dlg" header="Döviz Kurları" widgetVar="dlg1" width="500">
                    <p:panel id="dovizKurPaneli">
                        <h:panelGrid columns="2">
                            Dolar alış:  <h:outputText value="#{dovizKurlariBean.kur.dolarAlis}  TL" /> 
                            Dolar satış: <h:outputText value="#{dovizKurlariBean.kur.dolarSatis} TL" />
                            Euro alış:   <h:outputText value="#{dovizKurlariBean.kur.euroAlis}   TL" />
                            Euro satış:  <h:outputText value="#{dovizKurlariBean.kur.euroSatis}  TL" />
                        </h:panelGrid>
                        <br />
                        <p:panel>
                            #{dovizKurlariBean.kur.sonGuncelleme}
                        </p:panel>
                    </p:panel>
                </p:dialog>
                <p:messages />
            </h:form>
        </h:body>
    </html>
    
    

     

Projede kullanılan tüm kütüphelere ait jar dosyalarını içeren zip arşivini buradan indirebilirsiniz:
GO JSF2-PrimeFaces2-JSON-HttpClient libraries (2571)
Tamamlanmış uygulamanın bir örneğine de buradan erişebilirsiniz:
http://dovizkurlariweb.gozar.cloudbees.net/index.go

Bitmiş projeye ait bir ekran görüntüsü:
JSF & PrimeFaces ile yapılmış güncel Döviz Kurlarını Gösteren Java Web Uygulaması

Java’da JSF ve PrimeFaces kullanarak JSON nesnesi işleme Öğretisi” üzerine 13 düşünce

    • A Managed Bean is instantiated as soon as a JSF action references a method contained in it, in the case of the ExchangeRatesBean, it’s invoked as index.xhtml is called in the browser.

    • Sure. The main strategy here is pulling the exchange rate data once and providing that very data to all visitors (until someone invokes the Refresh action, which will benefit every new visitor) as there’s a very very little chance that there would be dramatic changes in the rates. You could change to scope of the managed bean to “session” (i.e. @SessionScoped) or even lower the scope as low as to the “request” (@RequestScoped) but I didn’t want to add extra load to the service (data) provider for a free service and therefore chose to avoid pissing them off.

  1. Primefaces action commands does not function on cloudbees, though it is all wirk on local machine with the same server version. What could cause to this?

  2. Change this code:

    into:

    @PostConstruct is automatically called when the bean gets initiated, so you shouldn’t call that method yourself.

    • @Serkan,

      Thanks for your comment. My current WordPress configuration seems to have stripped some of your <code> suggestion, but

      since

       <p:commandButton id ="ref" value="Refresh" ajax="true" action="#{exchangeRatesBean.kurlariYukle}" ... 

      invokes the method

      kurlariYukle()

      for refreshing the exchange rates, and I didn’t want to use extra space for this example, I simply put @PostConstruct above it to have this method called automatically once the bean is initiated.

      But yes, a good practice in a real life application could have been separating this logic elsewhere and a shorter @PostConstruct method to call the method from wherever it is positioned.

      Note: Please use the pre tag instead of <code if you wish to comment further and submit a <code suggestion.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

*