Total Tayangan Halaman

Jumat, 08 April 2011

MVC, duet: Ubuntu, MySQL, Java, Netbeans, Tomcat, ZK, iReport (Bagian 4)

Membuat proyek baru
1. Buka Netbeans
2. Buat proyek baru dengan membuka menu "File" > "New Project..." ("ctrl + shift + n"), maka akan muncul jendela "New Project".
3. Pada "Categories", pilih "Java Web". Pada "Projects", pilih "ZK363 Application". Klik tombol "Next >".
4. Beri nama proyek "pfm" dan tentukan lokasi penyimpanan. Klik tombol "Finish".
5. Pada jendela "Project" muncul proyek baru dengan nama pfm. Klik kanan, kemudian pilih "Properties", maka akan muncul jendela "Project Properties - pfm".
6. Pada kategori "Sources", ubah "Sources/Binary Format" ke dalam JDK versi yang tertinggi (kali ini JDK6).
7. Pada kategori "Libraries", tambahkan beberapa library dengan cara menekan tombol "Add Library...". Pilih "EclipseLink" dan "Mysql JDBC Driver". Tekan tombol "Add JAR/Folder", temukan "dao-persistence-pfm.jar" dan "objek-pfm".jar. Hapus selain kedua library itu, kecuali "ZK3.6.3".
8. Pada kategori "Run", pilih "Server" dengan Tomcat versi tertinggi. Ubah "Contect Path" menjadi "/pfm"
9. Buka folder di mana proyek pfm disimpan, buka folder nbproject dan buka berkas "project.properties". Ubah "war.ear.name=pfm.war" dan "war.name=pfm.war"
10. Klik kanan pada "Sources Packages", pilih "New" > "Java Packages...". Muncul jendela "New Java Packages", beri nama dengan "control", kemudian klik tombol "Finish".


Halaman Login
View: [ Web Pages/index.zul ]
    <?xml version="1.0" encoding="UTF-8"?>
    <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="win" ?>
    <zk xmlns="http://www.zkoss.org/2005/zul">
    <div align="center">
        <window id="win" border="normal" style="margin-top:0px;border-bottom:4px solid gray;border-right:4px solid gray" title="Login" width="400px" apply="control.index">
        <panel>
            <panelchildren>
                <grid>
                    <columns>
                        <column width="150px"/>
                        <column/>
                    </columns>
                    <rows>
                        <row spans="2" align="center">
                           <vbox align="center">
                               <label value="Personal Finance Management" style="font-size:18px;font-weight:bold;color:#1184d4;" />
                               <image src="gambar/pfm.png"/>
                           </vbox>
                        </row>
                        <row>
                            <label value="Nama Login"/>
                            <textbox id="txtboxUserID" width="150px" maxlength="15"/>
                        </row>
                        <row>
                            <label value="Kata Sandi"/>
                            <textbox id="txtboxPassword" width="150px" maxlength="15" type="password"/>
                        </row>
                        <row>
                             <captcha id="cLogin" length="3" width="160px" />
                             <vbox>
                                 <label value="Ketik teks yang muncul di samping" />
                                 <textbox id="txtCaptcha" width="200px" maxlength="3" />
                             </vbox>
                        </row>
                        <row spans="2" align="center">
                            <button id="btnLogin" label="Login" width="120px" image="gambar/login.png" />
                        </row>
                    </rows>
                </grid>
            </panelchildren>
        </panel>
        </window>
    </div>
    </zk>
Controller: [ Sources Package/control/index.java ]
package control;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import objek.md5;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Captcha;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;

public class index extends GenericForwardComposer
{
    static EntityManagerFactory emf = Persistence.createEntityManagerFactory("dao-persistence-pfmPU");
    static EntityManager emTabel    = emf.createEntityManager();

    private Textbox     txtboxUserID,txtboxPassword;
    private Captcha     cLogin;
    private Textbox     txtCaptcha;

    public void onCreate$win()
    {
        txtboxUserID.setFocus(true);
    }

    public void onClick$btnLogin()throws InterruptedException, NoSuchAlgorithmException, NoSuchAlgorithmException, UnsupportedEncodingException
    {
        if ((txtboxUserID.getValue().equals("")) || (txtboxPassword.getValue().equals("")))
        {
            Messagebox.show("User ID dan password tidak boleh kosong.", "Informasi", Messagebox.OK, Messagebox.INFORMATION);
            txtboxUserID.setFocus(true);
            return;
        }
        else if(!cLogin.getValue().equalsIgnoreCase(txtCaptcha.getValue()))
        {
            Messagebox.show("Captcha harus sama dengan yang muncul pada gambar di sebelah kiri", "Informasi", Messagebox.OK, Messagebox.INFORMATION);
            txtCaptcha.setFocus(true);
            txtCaptcha.setSelectionRange(0, 3);
            return;
        }
        else
        {
            listUser        = emTabel.createNamedQuery("Pengguna.findByNamaloginKatasandi")
                                .setHint("eclipselink.refresh", "true")
                                .setParameter("namalogin", txtboxUserID.getValue())
                                .setParameter("katasandi", md5.decode(txtboxPassword.getValue()))
                                .getResultList();
            if (listUser.isEmpty())
            {
                Messagebox.show("Pengguna " + txtboxUserID.getValue() + " belum terdaftar atau kata sandi salah", "Informasi", Messagebox.OK, Messagebox.INFORMATION);
                txtboxUserID.setFocus(true);
                return;
            }
        }
        session.setAttribute("userid", txtboxUserID.getValue());
        session.setAttribute("id", ((Pengguna) listUser.get(0)).getIdpengguna());

        Executions.sendRedirect("utama.zul");
    }

    //Zul Object
    protected List  listUser;
}
Tambahan:
1. Tambahkan skrip 
@NamedQuery (name = "Pengguna.findByNamaloginKatasandi", query = "SELECT p FROM Pengguna p WHERE p.katasandi = :katasandi and p.namalogin = :namalogin")
pada "dao-persistence-pfm/dao/Pengguna.java", kemudian simpan.
2. Klik kanan proyek "dao-persistence-pfm", kemudian pilih "Clean and Build". Klik kanan proyek "pfm", kemudian pilih "Clean", sehingga library pada proyek "pfm" akan memakai "
dao-persistence-pfm" yang baru.
3. Buat sebuah folder pada "Web Pages" dengan nama "gambar". Kopi gambar "login.png" dan "pfm.png" ke dalam folder "gambar"
Penjelasan:
1. Pada "Web Pages/index.zul" terdapat baris

<?xml version="1.0" encoding="UTF-8"?>
yang menyatakan versi struktur xml yang dipakai dalam pembuatan "index.zul". Baris berikutnya
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="win" ?>
adalah kode yang diperlukan untuk mengijinkan anotasi dan menghubungkan/memetakan dengan "Sources Package/control/index.java", yaitu yang tertulis pada atribut "apply" dalam "window". Atribut "arg0" berisi "win", sehingga atribut "id" pada "window" berisi "win" seperti di bawah ini
<window id="win" border="normal" style="margin-top:0px;border-bottom:4px solid gray;border-right:4px solid gray" title="Login" width="400px" apply="control.index">
Baris 1 sampai 3 tidak boleh dihapus.
2. Pada "Sources Package/control/index.java" terdapat

public class index extends GenericForwardComposer
yang mempermudah dalam penulisan kode di dalam "index.java", karena pengembang tidak perlu menuliskan cara menghubungkan/memetakan dengan kontrol-kontrol yang ada di dalam "Web Pages/index.zul", tetapi cukup dengan menuliskan
private Textbox     txtboxUserID, txtboxPassword;
karena di dalam "Web Pages/index.zul" terdapat "textbox" yang memiliki id "txtboxUserID" dan "txtboxPassword". Namun, tidak ada kewajiban untuk mendeklarasikan semua kontrol yang ada, cukup kontrol-kontrol yang diperlukan saja. Bisa jadi, tidak ada kontrol yang dideklarasikan.
3. Pada "Sources Package/control/index.java" terdapat
static EntityManagerFactory emf = Persistence.createEntityManagerFactory("dao-persistence-pfmPU");
static EntityManager emTabel    = emf.createEntityManager();

untuk melakukan koneksi ke dalam basis data. "dao-persistence-pfmPU" adalah nama koneksi yang terdapat pada saat pembuatan koneksi di proyek "dao-persistence-pfm", tetapi apabila tidak ingat namanya, dapat dilihat pada "dao-persistence-pfm/Source Packages/META-INF/persistence.xml".
4. Pada "Sources Package/control/index.java" terdapat
public void onCreate$win()
...
public void onClick$btnLogin()throws InterruptedException
yang merupakan penangkap event yang terjadi pada kontrol. Event yang dapat digunakan tergantung dari kontrol yang digunakan. "onCreate$win" akan dijalankan pada waktu "win" (kontrol: window) dibuat (create). "onClick$btnLogin" dijalankan pada saat "btnLogin" (kontrol: button) diklik. Pada "Sources Package/control/index.java" tidak perlu deklarasi variabel untuk "win" dan "btnLogin", karena memang keduanya hanya dipakai untuk event saja sehingga cukup dipakai pada method. "throws InterruptedException" merupakan bawaan dari "Messagebox".
5. Pada "Sources Package/control/index.java" terdapat
listUser=emTabel.createNamedQuery("Pengguna.findByNamaloginKatasandi")
                .setHint("eclipselink.refresh", "true")
                .setParameter("namalogin", txtboxUserID.getValue())
                .setParameter("katasandi", md.encode(txtboxPassword.getValue().getBytes()))
                .getResultList();
yang merupakan salah satu cara untuk mendapatkan data dari basis data. Baris tersebut memanfaatkan permintaan bernama yang ada pada "dao-persistence-pfm/Source Packages/dao/Pengguna.java"
@NamedQuery(name = "Pengguna.findByNamaloginKatasandi", query = "SELECT p FROM Pengguna p WHERE p.katasandi = :katasandi and p.namalogin = :namalogin")
Parameter "namalogin" akan mengisi ":namalogin", sedangkan parameter "katasandi" akan mengisi ":katasandi". Sebagai catatan, tipe data antar parameter harus sama. Nilai yang dikembalikan oleh "emTabel.createNamedQuery("Pengguna.findByNamaloginKatasandi")" adalah list dari objek "Pengguna".
6. Apabila semua kondisi terpenuhi, maka halaman login menyimpan data ke sesi

session.setAttribute("userid", txtboxUserID.getValue());
dan akan berpindah ke halaman lain sesuai pada baris
Executions.sendRedirect("zul/menuutama.zul");
Halaman Utama
View: [ Web Pages/utama.zul ]
<?xml version="1.0" encoding="UTF-8"?>
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="win" ?>
<zk xmlns="http://www.zkoss.org/2005/zul">
<window id="win" border="normal" width="100%" height="100%" apply="control.utama">
    <div height="45px" style="background-color:teal">
        <vbox>
            <label value="Personal Finance Management" style="font-size:14px;font-weight:bold;color:#ffffff;"/>
            <hbox align="center">
                <label value="Anda Login Sebagai: " />
                <label id="lblUser" value="" />
            </hbox>
        </vbox>
    </div>
    <menubar style="margin-bottom:5px" zindex="0">
        <menuitem label="Home" href="home.html" image="gambar/rumah.png" target="iFrameData" />
        <menu label="Data Induk" image="gambar/proses.png">
            <menupopup>
                <menuitem label="Transaksi" href="transaksi.zul" image="gambar/formulir.png"  target="iFrameData" />
                <menuseparator />
                <menu label="Laporan" image="gambar/folder.png" >
                    <menupopup>
                        <menuitem label="Rekap Transaksi" href="laporan/rekap.zul" target="iFrameData" image="gambar/formulir.png" />
                    </menupopup>
                </menu>
            </menupopup>
        </menu>
        <menuitem id="mnLogout" label="Logout" image="gambar/logout.png" />
    </menubar>
    <iframe name="iFrameData" width="100%" height="88%"/>
</window>
</zk>
Controller: [ Sources Package/control/utama.java ]
package control;

import org.zkoss.zk.ui.Sessions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Label;
import org.zkoss.zul.Window;
public class utama extends GenericForwardComposer
{
    private Label       lblUser;
    private Window      win;
  
    public void onCreate$win()
    {
        if (Sessions.getCurrent().getAttribute("userid") == null)
        {
            win.detach();
            win = null;
            execution.sendRedirect("../index.zul", "_top");
            return;
        }
  lblUser.setValue(session.getAttribute("userid").toString());
    }
  
    public void onClick$mnLogout()
    {
        session.invalidate();
        execution.sendRedirect("index.zul", "_top");
    }
}
Tambahan:
Kopi gambar "rumah.png", "formulir.png", "folder.png", dan "logout.png" ke dalam folder "gambar"
Penjelasan:
1. Pada "Sources Package/control/utama.java" terdapat
if (Sessions.getCurrent().getAttribute("userid") == null)
yang berfungsi untuk melakukan pengecekan apakah halaman tersebut dibuka setelah login atau tidak.
2. Pada "Sources Package/control/utama.java" terdapat
session.invalidate();
yang berfungsi untuk menghapus sesi

Tidak ada komentar: