Posts filed under ‘Java Enterprise Edition’

Memanggil web service dari server Java EE di client PHP

Seorang mahasiswa yang sedang membuat skripsi bertanya apakah mungkin membuat sebuah web service dengan Java Enterprise Edition kemudian memanggilnya di client PHP?  Pada kesempatan tatap muka yang singkat, saya menjawab secara ringkas dengan merujuk pada definisi web services. Web services adalah sistem yang dirancang secara khusus untuk mendukung interaksi pertukaran data mesin ke mesin melalui jaringan. Selama berkomunikasi melalui metode yang sama, maka proses komunikasi dapat terjadi tanpa membedakan OS maupun bahasa pemograman yang dipakai.   Saat ini ada dua jenis web services, yaitu yang berbasis REST dan berbasis SOAP. Web services berbasis REST cenderung lebih ringan dan lebih mudah dipelajari dibandingkan dengan SOAP. Hal ini menyebabkan terjadinya peralihan dari web services berbasis SOAP ke REST.

Pada kesempatan tertulis ini, saya akan memberikan sebuah contoh halaman PHP yang memanggil web services yang dibuat dengan Java Enterprise Edition. Metode yang dipergunakan adalah metode berbasis SOAP.

Saya akan membuat dua proyek, yaitu:

  1. Server web service yang menggunakan teknologi Java Enterprise Edition. Saya menggunakan NetBeans IDE dan GlassFish bawaannya.
  2. Sebuah halaman PHP yang mengakses layanan web service yang disediakan oleh server di atas.

Membuat Server Web Service dengan Java EE

Langkah-langkah yang saya lakukan adalah:

  1. Memilih menu File, New Project di NetBeans IDE. Kemudian saya memilih Java Web di Categories, dan Web Application di Projects. Setelah memberi nama proyek dan menentukan lokasi penyimpanan, saya men-klik tombol Finish.
  2. Men-klik kanan nama proyek, kemudian memilih menu New, Other... Pada dialog yang muncul, saya memilih Web Services di bagian Categories, dan Web Service di bagian File Typesseperti yang terlihat di gambar berikut ini:

    Membuat Web Services Baru

    Membuat Web Services Baru

  3.  Pada Web Service Name, saya mengisi dengan nama PerhitunganWS. Pada bagian package, saya mengisi dengan nama package co.id.jocki.ws. Setelah itu, saya men-klik tombol Finish.

NetBeans akan membuat sebuah class baru yang berada di folder Web Services seperti yang terlihat pada gambar berikut ini:

Web Services Di Tampilan Project

Web Services Di Tampilan Project

Bila class PerhitunganWS di-buka, NetBeans memungkinkan pengguna untuk melihat dalam bentuk Source atau Design. Bila tampilan Design dipakai, maka layar editor akan terlihat seperti pada gambar berikut ini:

NetBeans Web Service Editor

NetBeans Web Service Editor

Untuk menambahkan sebuah operasi baru, saya melakukan langkah-langkah seperti berikut ini:

  1. Klik tombol Add Operation… Akan muncul sebuah dialog baru.
  2. Untuk menambah parameter, saya dapat men-klik tombol Add. Saya mengisi dialog tersebut seperti yang terlihat pada gambar berikut ini:

    Menambah Operasi Baru Di Web Service

    Menambah Operasi Baru Di Web Service

  3. Setelah itu, saya men-klik tombol OK.

Setelah ini, saya perlu menambahkan kode program yang berisi proses untuk operasi baru tersebut.   Saya men-klik Source di toolbar untuk beralih ke tampilan kode program.   Kemudian, saya mengubah satu-satunya baris di method tambah() menjadi return angka1 + angka2; seperti yang terlihat di gambar berikut ini:

Kode Program Operasi Di Web Service

Kode Program Operasi Di Web Service

Untuk menguji web service tersebut, klik kanan pada nama class PerhitunganWS, kemudian memilih Test Web Service seperti yang terlihat di gambar berikut ini:

Menguji Web Services

Menguji Web Service

NetBeans akan menjalankan browser yang berisi web service tester. Di halaman ini terdapat sebuah link bertuliskan WSDL File. URL disini nantinya akan dipakai oleh client web service. Di percobaan saya, nilai URL ini adalah http://localhost:8080/ServerWebService/PerhitunganWS?WSDL. Saya akan men-copy lokasi URL ini untuk dipakai di PHP nantinya.

Pada bagian methods, saya mencoba mengisi parameter dengan nilai 10 dan 20, kemudian setelah men-klik tombol tambah (nama method), akan muncul halaman tambah Method invocation. Pastikan pada halaman tersebut, terdapat tulisan Method returned int: “30″.

Sekarang server web service telah selesai dibuat. Saya tidak mematikan GlassFish server di NetBeans karena pada langkah berikutnya, saya akan memanggil web service ini di PHP.

Membuat Client Web Service dengan PHP

Sebelum mulai membuat client web service di PHP, saya memastikan apakah extension SOAP telah diaktifkan di PHP saya. Yang saya lakukan adalah membuat sebuah file PHP dengan nama info.php dimana isinya adalah <?php phpinfo(); ?>. Saat menampilkan halaman tersebut di browser, saya memastikan bahwa terdapat baris Soap Client dengan nilai Enabled.

Untuk membuat client web service, saya perlu membuat sebuah object dari class SoapClient seperti pada baris berikut ini:

$client = new SoapClient("http://localhost:8080/ServerWebService/PerhitunganWS?WSDL");

Nilai dari parameter constructur SoapClient adalah URL yang merujuk ke lokasi file WSDL. URL ini dapat dilihat di halaman web service tester pada saat saya menguji server web service di NetBeans.

Secara utuh, kode program PHP yang saya buat adalah:

<?php
function errorHandler($errno, $errstr, $errfile, $errline, array $errcontext) {
print "<h3>Terjadi kesalahan/peringatan:</h3>";
print "Baris $errline [$errstr]";
exit;
}

set_error_handler('errorHandler');

$client = new SoapClient("http://localhost:8080/ServerWebService/PerhitunganWS?WSDL");
$daftarOperasi = $client->__getFunctions();
print "<h3>Daftar Operasi Yang Tersedia Di Server WS:</h3>";
foreach ($daftarOperasi as $operasi) {
print "<p>$operasi</p>";
}
$hasil = $client->tambah(array('angka1'=>20, 'angka2'=>10));
print "<h3>Hasil operasi hitung(10,20): " . $hasil->return . "</h3>";
?>

<!--?php 

Pada kode program tersebut, saya menyertakan pemeriksaan kesalahan dengan set_error_handler(). Bagian tersebut dapat digantikan dengan menggunakan try/catch. Akan tetapi bila menggunakan try/catch, hanya pesan kesalahan yang ditampilkan, sementara pesan warning tidak akan ditampilkan. Bila pengaturan penampilan pesan kesalahan & warning secara otomatis tidak dimatikan (nilai display_errors di file konfigurasi adalah stdout), maka bagian ini tidak diperlukan.

Karena server web service di GlassFish menyediakan file WSDL, maka saya dapat menggunakan method __getFunctions() untuk melihat operasi apa saja yang disediakan oleh server web service tersebut.

Untuk memanggil salah satu operasi yang ada, saya cukup memanggil method dengan nama yang bersesuaian, diikuti dengan parameter yang diletakkan dalam associative array. Sebagai contoh, di kode program di atas, saya memanggil operasi tambah dengan nilai parameter angka1 berupa 20 dan nilai angka2 berupa 10. Hasil yang dikembalikan dari server web service adalah angka 30.

26 Mei 2012 at 2:54 PM Tinggalkan Komentar

Membuat Album Foto Dengan PrimeFace Di NetBeans 7

PrimeFaces adalah salah satu framework ‘tampilan’ yang kompatibel dengan Java Server Faces 2.0.  Framework ini sudah di-bundle di NetBeans 7 sehingga pengguna NetBeans tidak perlu lagi men-download sendiri.  Artikel ini akan menunjukkan bagaimana memakai PrimeFaces di NetBeans 7.  Artikel ini hanya menunjukkan pemakaian komponen <galleria>.  Seluruh komponen yang disediakan oleh PrimeFaces dapat dilihat di show case yang berada di http://www.primefaces.org/showcase/ui

Langkah pertama yang dilakukan adalah membuat sebuah project baru di NetBeans 7, dengan memilih menu File, New Project.  Kemudian pilih Java Web, Web Application, seperti yang terlihat di gambar berikut:

Klik tombol Next, isi informasi project seperti Project Name dan Project Location.  Klik tombol Next lagi untuk membuka halaman Server and Settings.  Pada halaman ini, pilih Server yang akan dipakai.

Setelah itu, klik tombol Next, halaman Frameworks akan muncul.  Beri tanda centang pada JavaServer Faces.  Kemudian pada tab Components, pilih PrimeFaces 2.2.1 di Components Suite seperti yang terlihat pada gambar berikut:

Memilih PrimeFaces Pada Saat Membuat Project Web Baru
Setelah itu, klik tombol Finish.  Sebuah facelet dengan nama index.xhtml akan dibuat.  Kalau diperhatikan, facelet tersebut secara otomatis akan menyertakan namespace PrimeFaces, seperti yang terlihat di bagian berikut:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:h="http://java.sun.com/jsf/html">

Web site yang akan dibuat pada artikel ini tidak menyediakan fungsi upload, sehingga diasumsikan gambar sudah berada di lokasi yang ditentukan.  Sebagai informasi, folder yang dipakai adalah folder dengan nama gambar.  Buat sebuah folder baru di Web Pages dengan klik kanan dan memilih New, Other… Pada dialog yang muncul, pilih Other, Folder. Pada Folder Name, isi dengan nama gambar.  Masukkan beberapa file gambar pada folder ini dengan cara copy-paste.

Langkah berikutnya, buat sebuah Managed Bean dengan memilih menu File, New File.  Kemudian pilih JavaServer Faces pada bagian Categories, dan pilih JSF Managed Bean pada bagian File Types.  Klik tombol Next.  Isi Class Name dengan FileAlbum.  Pada combobox Scope, isi dengan session.  Kemudian klik tombol Finish.

Kemudian ganti kode program pada FileAlbum.java yang dihasilkan oleh NetBeans menjadi seperti berikut:

package co.id.snake.mbean;

import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.faces.application.Resource;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;

@ManagedBean
@SessionScoped
public class FileAlbum {

  private List<String> fileLocations;

  public FileAlbum() {
    fileLocations = new ArrayList<>();
    try {
      ServletContext sc = (ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext();
      Path dirGambar = Paths.get(sc.getRealPath("/gambar"));
      try (DirectoryStream<Path> dir = Files.newDirectoryStream(dirGambar)) {
        Iterator<Path> iter = dir.iterator();
        while (iter.hasNext()) {
          Path file = iter.next();
          fileLocations.add("/gambar/" + file.getFileName());
        }
      }
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  public List<String> getFileLocations() {
    return fileLocations;
  }
}

Kode program di atas memanfaatkan fitur baru di Java 7, sehingga hanya bisa dijalankan bila menggunakan JDK 7 ke atas.  Bila fitur baru belum dikenali oleh editor, klik kanan pada nama project, kemudian pilih Properties.  Pada bagian Source/Binary Format, pastikan JDK 7 sudah dipilih.

Setelah itu, lakukan modifikasi pada index.xhtml menjadi seperti berikut ini:

<?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"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
   <title>Latihan PrimeFaces</title>
</h:head>
<h:body>
   <p:growl id="label" showDetail="true"/>
   <p:panel header="Album Foto">
     <p:galleria effect="slide" effectSpeed="1000">
       <ui:repeat value="#{fileAlbum.fileLocations}" var="fileLocation" >
         <p:graphicImage value="#{fileLocation}" />
       </ui:repeat>
     </p:galleria>
   </p:panel>
</h:body>
</html>

Tampilkan facelet tersebut di browser dengan memilih menu Run, Run File.  Berikut ini adalah contoh tampilan di browser:

Contoh Tampilan PrimeFaces

Video yang mempertunjukkan langkah demi langkah dari artikel ini dapat dilihat di http://www.screencast.com/t/C6KdmBmLCMn.

31 Oktober 2011 at 2:07 AM 2 komentar

JavaServer Faces: Melihat Wajah Java

Hari ini aku akan mencoba mempelajari bagaimana menggunakan JSF bersama dengan JSP. JSF masih merupakan bagian dari JEE, dan dibuat berdasarkan projek Apache Struts. Yup! JSF memakai design pattern MVC layaknya Struts. Sayangnya, Tomcat tidak menyertakan JSF dalam paket-nya, sehingga aku harus men-download JAR tambahan di situs Sun. Tapi ada ide yang lebih baik: hari ini aku akan memakai NetBeans IDE 6.5 dan application server GlassFish, soalnya mereka sudah punya JSF sehingga aku tidak perlu repot men-download lagi.

Aku memilih Web Application (Java Web) dari New Project di NetBeans. Setelah itu, pada langkah ke-4, aku men-centang pilihan framework JavaServer Faces. Setelah project dibuat, aku memastikan libraries JSF 1.2 telah disertakan di bagian Libraries, yang terdiri atas commons-beanutils.jar, commons-collections.jar, common-digester.jar, commons-logging.jar, jsf-api.jar, dan jsf-impl.jar.

Pada MVC di JSF, Model diwakili oleh class JavaBean, View diwakili oleh JSP, dan Controller diwakili oleh facet servlet (javax.faces.webapp.FacesServlet) yang dapat di-customize melalui file /WEB-INF/faces-config.xml.

Sebagai latihan, aku akan memakai Model ini:

package com.latihan;

public class User {
    private String firstName;
    private String lastName;
    private String password;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Aku harus mendaftarkan Model tersebut pada file konfigurasi faces-config.xml terlebih dahulu. File konfigurasi ini dapat ditemukan di bagian “Configuration Files” dari project. Saat pertama kali membukanya, NetBeans akan menampilkan PageFlow, sebuah fitur yang sangat berguna untuk melihat hubungan antar View dalam bentuk diagram. Untuk meng-edit file ini, klik pada bagian “XML“, lalu aku menambahkan baris berikut:

<managed-bean>
  <managed-bean-name>user</managed-bean-name>
  <managed-bean-class>com.latihan.User</managed-bean-class>

  <managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Sekarang aku dapat memakai Model tersebut di View melalui managed-bean-name, yaitu user. Sebagai latihan, berikut ini adalah View yang aku beri nama registrasi.jsp:

<%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
    <head>
        <title>Latihan JSF</title>

    </head>
    <f:view>
        <body>
            <h1>User Registration</h1>
            <h:form>

                <table>
                    <tr>
                        <td>First Name:</td>
                        <td><h:inputText value="#{user.firstName}" size="30"/></td>
                    </tr>

                    <tr>
                        <td>Last Name:</td>
                        <td><h:inputText value="#{user.lastName}" size="30"/></td>
                    </tr>
                    <tr>

                        <td>Password:</td>
                        <td><h:inputSecret value="#{user.password}" size="30"/></td>
                    </tr>
                </table>
                <h:commandButton value="Register" action="submit"/>

            </h:form>
        </body>
    </f:view>
</html>

Secara default, View di atas dapat di-akses dengan alamat http://localhost:8080/nama_context/faces/registrasi.jsp. Berikutnya, aku membuat sebuah View lagi, yang aku beri nama userinfo.jsp:

<%@taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@taglib uri="http://java.sun.com/jsf/html" prefix="h" %>

<html>
    <head>
        <title>Latihan JSF</title>
    </head>
    <f:view>
        <body>

            Welcome, <h:outputText value="#{user.firstName}"/>
            <h:outputText value="#{user.lastName}"/>.
            <p/>
            Your password is <h:outputText value="#{user.password}"/>.
        </body>
    </f:view>

</html>

Sebagai langkah terakhir, aku akan menentukan navigasi View di dalam Controller dengan menambahkan baris berikut di file faces-config.xml:

<navigation-rule>
   <from-view-id>registrasi.jsp</from-view-id>
   <navigation-case>
      <from-outcome>submit</from-outcome>

      <to-view-id>userinfo.jsp</to-view-id>
   </navigation-case>
</navigation-rule>

Sekarang, jika aku membuka halaman registrasi.jsp dan aku menekan tombol Submit, aku akan dibawa ke halaman userinfo.jsp. Tampilan diagram PageFlow di NetBeans saat membuka faces-config.xml akan memperjelas flow navigasi antar-view.

21 September 2009 at 1:37 AM Tinggalkan Komentar

JBoss: Mengakrabkan Diri Dengan Bos

JBoss 5 punya kelebihan di arsitektur microcontainer-nya. Jika aku tidak membutuhkan komponen tertentu, misalnya clustering, aku dapat memilih untuk menjalankan server JBoss tanpa menyertakan komponen tersebut. Pada instalasi standard JBoss, aku dapat menemukan lima konfigurasi server bawaan di lokasi direktori %JBOSS_HOME%\server. Di direktori tersebut terdapat lima subdirektori, yaitu: all, default, minimal, standard, dan web. Seperti yang dapat ditebak dari namanya, minimal adalah konfigurasi yang paling sederhana untuk menjalankan JBoss tanpa dukungan web container, EJB dan JMS. Ini adalah konfigurasi yang paling ringan dan start-up yang paling cepat. Sebaliknya, all adalah konfigurasi yang menjalankan seluruh komponen yang tersedia, termasuk RMI/IIOP dan clustering. Secara default, konfigurasi yang dipakai adalah default yang menyediakan komponen yang umum dipakai oleh aplikasi JEE, dan tidak menyertakan dukungan seperti IIOP dan clustering.

Di dalam masing-masing direktori server configuration, terdapat beberapa direktori seperti direktori conf yang berisi file konfigurasi, direktori deploy yang berisi aplikasi JEE yang ingin aku jalankan, dan direktori lib yang berisi library JAR untuk aplikasi di server configuration ini.

Untuk menjalankan JBoss dengan konfigurasi tertentu, aku dapat menggunakan argument “-c” saat memanggil run.bat (atau run.sh untuk Linux). Misalnya, untuk menjalankan server configuration minimal, aku mengetikkan perintah berikut di command prompt:

run -c minimal

Setelah JBoss menyelesaikan bootstrap-nya, aku akan mendapatkan baris informasi seperti:

Started in 8s:406ms

Sebagai perbandingan, jika aku menjalankan server configuration all, JBoss menampilkan baris ini:

Started in 1m:8s:453ms

Selisih waktu untuk startup-nya lumayan terasa, tapi aku rasa aku tidak akan pernah memakai server configuration all, selain untuk mencoba seluruh kemampuan JBoss.

Untuk membuat konfigurasi server sesuai kebutuhanku, aku harus mengerti bagaimana cara kerja file konfigurasi JBoss yang terdapat di folder conf. File jboss-service.xml akan dijalankan setelah server menjalankan microcontainer. File ini dibutuhkan untuk core services lama yang belum dalam bentuk microcontainer bean atau mbean. Sisanya, service non-core yang hot-deployable terdapat di folder deploy. Cara yang paling mudah untuk membuat server configuration sesuai kebutuhan adalah dengan men-copy dari salah satu folder bawaan JBoss, kemudian meng-edit jboss-service.xml serta menghapus/menambahkan services di folder deploy.

O ya, instalasi JBoss menyertakan database Hypersonic, dimana descriptornya berupa file hsqldb-ds.xml di folder deploy. Umumnya, untuk program dengan kualitas produksi, orang-orang akan memakai database dengan yang lebih baik seperti Oracle. Aku akan mengganti database default Hypersonic dengan database Oracle yang terinstall di komputerku. Aku mulai dengan menghapus hsqldb-ds.xml dari folder deploy. Lalu, aku mencopy library jdbc milik Oracle ke folder lib di folder server configuration yang aku pakai. Kemudian, pada direktori deploy, aku membuat file baru bernama oracle-ds.xml. Isinya seperti berikut:

<?xml version="1.0" encoding="UTF-8"?>
<datasources>
  <local-tx-datasource>
    <jndi-name>DefaultDS</jndi-name>
    <connection-url>jdbc:oracle:thin:@localhost:1521:latihan</connection-url>
    <driver-class>oracle.jdbc.driver.OracleDriver</driver-class>
    <user-name>scott</user-name>
    <password>tiger</password>
    <valid-connection-checker-classname>
       org.jboss.resource.adapter.jdbc.vendor.OracleValidConnectionChecker
    </valid-connection-checker-classname>
    <metadata>
      <type-mapping>Oracle10g</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>

Pada konfigurasi di atas, aku memakai Oracle Database dengan SID latihan yang ter-install di komputer yang sama. User name yang aku pakai adalah user name bawaan database Oracle, yaitu scott dan default password-nya tiger.

Aku kemudian me-restart JBoss, dan melihat banyak pesan kesalahan. Untuk sekarang aku akan mengabaikannya dulu. Yang perlu aku lakukan adalah memeriksa apakah koneksi database berlangsung dengan lancar. Caranya adalah dengan membuat direktori baru di direktori deploy dengan nama test.war (ini nama direktori, bukan nama file). Di dalam direktori ini, aku membuat sebuah file baru, dengan nama index.jsp yang isinya:

<%@page contentType="text/html"
  import="java.util.*,javax.naming.*,javax.sql.DataSource,java.sql.*"
%>
<%
DataSource ds = null;
Connection con = null;
PreparedStatement pr = null;
InitialContext ic;
try {
  ic = new InitialContext();
  ds = (DataSource)ic.lookup( "java:/DefaultDS" );
  con = ds.getConnection();
  pr = con.prepareStatement("SELECT ENAME FROM EMP");
  ResultSet rs = pr.executeQuery();
  while (rs.next()) {
    out.println("<br> " +rs.getString("ENAME"));
  }
  rs.close();
  pr.close();
}catch(Exception e){
  out.println("Exception thrown " +e);
}finally{
  if(con != null){
    con.close();
  }
} %>

Program di atas akan menampilkan kolom ENAME dari tabel EMP milik schema SCOTT. Untuk menjalankannya, aku membuka browser dan mengetikkan alamat ini: http://localhost:8080/test/index.jsp. Jika halaman yang muncul adalah nama-nama yang tercantum di tabel EMP, berarti database Oracle telah ter-setup dengan baik dan siap dipakai.

Lalu kenapa banyak pesan kesalahan saat menjalankan JBoss? Itu karena beberapa services mengharapkan tabel-tabel tertentu di database, dan aku belum membuatnya. Database Hypersonic bawaan JBoss menyimpan informasi tabel di file data\hypersonic\localDB.script.

15 Agustus 2009 at 2:47 AM Tinggalkan Komentar

JSTL: Merapikan Halaman JSP

Tujuan utama JavaServer Pages Template Library (JSTL) adalah mempermudah kehidupan perancang halaman JSP. Bagi developer, JSTL membantu menciptakan halaman JSP yang rapi, tidak banyak berbaur antara kode HTML dan kode Java, sehingga halaman JSP lebih mudah dimengerti dan dikelola. Salah satu bagian JSTL (JSR-52), Expression Language (EL), telah menjadi bagian dari spesifikasi JSP 2.1 (JSR-152).

Tag dalam JSTL bisa dikategorikan menjadi empat bagian, yaitu core (http://java.sun.com/jsp/jstl/core, prefix c), XML processing (http://java.sun.com/jsp/jstl/xml, prefix x), I18N formatting (http://java.sun.com/jsp/jstl/fmt, prefix fmt), SQL (http://java.sun.com/jsp/jstl/sql, prefix sql) dan functions (http://java.sun.com/jsp/jstl/functions, prefix fn).

Instalasi Apache Tomcat 6 tidak menyertakan dukungan JSTL, sehingga aku harus mendownload implementasi JSTL secara terpisah, seperti dari Apache Jakarta. Lalu aku juga harus memiliki jar yang berisi API JSTL. Jika mendownload implementasi dari Apache Jakarta, aku dapat menemukan API JSTL di file jstl.jar dan implementasinya di file standard.jar.

Sebagai latihan, aku membuat sebuah halaman yang men-query data dari database dan menampilkannya beserta pilihan untuk menambah/mengedit/menghapus setiap baris data:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<html>
<head>
<title>Data Individu</title>
</head>

<body>
<sql:query var="individu" dataSource="jdbc/databaseDevelopment">
  SELECT * FROM TBL_INDIVIDU
</sql:query> 
<h1>Daftar Individu</h1>
<c:choose>
  <c:when test="${individu.rowCount==0}">

    <p>Saat ini tidak ada data individu yang terdaftar.</p>
  </c:when>
  <c:otherwise>
    <p>Berikut ini adalah ${individu.rowCount} individu yang terdaftar:</p>
    <table cellspacing="5px">

      <thead>
      <c:forEach var="columnName" items="${individu.columnNames}">
        <th>${columnName}</th>
      </c:forEach>
      </thead>

      <tbody>
      
      <c:forEach var="record" items="${individu.rows}">
        <tr>
        <td>${record.id}</td>
        <td>${record.nama}</td>

        <td>${record.alamat}</td>
        <td>${record.telepon}</td>
        <c:url value="modify.jsp" var="urlUpdate">
          <c:param name="id" value="${record.id}" />
          <c:param name="nama" value="${record.nama}" />

          <c:param name="alamat" value="${record.alamat}" />
          <c:param name="telepon" value="${record.telepon}" />
        </c:url>
        <c:url value="modify.jsp" var="urlHapus">
          <c:param name="id" value="${record.id}" />
          <c:param name="action" value="hapus" />

        </c:url>
        <td><a href="${urlUpdate}">Update</a> <a href="${urlHapus}">Hapus</a></td>
        </tr>

      </c:forEach>
      </tbody>
    </table>
  </c:otherwise>
</c:choose>
<p><a href='modify.jsp'>Tambah Data Baru</a></p>

</body>
</html>
    

Pada halaman JSP di atas, aku tidak menggunakan kode Java sedikitpun, sehingga halaman JSP terlihat lebih mudah dimengerti. Untuk melakukan query, aku menggunakan <sql:query>dengan data source yang telah aku definisikan sebagai JNDI resource di Apache Tomcat. Aku juga menggunakan <c:url> untuk membentuk string URL beserta parameter-parameter-nya secara otomatis. Untuk mencetak setiap baris data sesuai hasil query, aku menggunakan <c:forEach>.

Untuk halaman modify.jsp yang berguna untuk tambah data, update data dan hapus, aku membuat halaman seperti berikut:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %>
<html>
<head>
<title>Modifikasi Data Individu</title>
</head>
<body>
<h1>Modifikasi Data Individu</h1>

<c:choose>
  <c:when test="${empty param.action}">
    <form method="post" action="modify.jsp">
    <pre>
 Nama   : <input name="nama" type="text" maxlength="20" value="${param.nama}" />
 Alamat : <input name="alamat" type="text" maxlength="20" value="${param.alamat}" />

 Telepon: <input name="telepon" type="text" maxlength="20" value="${param.telepon}" />
 
 <input type="submit" value="Simpan" />
 <input type="hidden" name="id" value="${param.id}" />
 <input type="hidden" name="action" value="${empty param.id?'tambah':'edit'}" />
    </pre>  
    </form>

  </c:when>
  <c:when test="${param.action=='tambah'}">
    <sql:update dataSource="jdbc/databaseDevelopment">
      INSERT INTO TBL_INDIVIDU VALUES (?, ?, ?, ?)
      <sql:param value="<%= java.util.UUID.randomUUID().toString() %>"/>
      <sql:param value="${param.nama}" />

      <sql:param value="${param.alamat}" />
      <sql:param value="${param.telepon}" />
    </sql:update>
    <p>Data berhasil ditambahkan ke database. <a href='latihan1.jsp'>Klik disini untuk kembali.</a></p>

  </c:when>
  <c:when test="${param.action=='edit'}">
    <sql:update dataSource="jdbc/databaseDevelopment">
      UPDATE TBL_INDIVIDU SET NAMA = ?, ALAMAT = ?, TELEPON = ?
      WHERE ID = ?
      <sql:param value="${param.nama}" />
      <sql:param value="${param.alamat}" />
      <sql:param value="${param.telepon}" />

      <sql:param value="${param.id}" />
    </sql:update>
    <p>Data berhasil diupdate. <a href='latihan1.jsp'>Klik disini untuk kembali.</a></p>
  </c:when>

  <c:when test="${param.action=='hapus'}">
    <sql:update dataSource="jdbc/databaseDevelopment">
      DELETE FROM TBL_INDIVIDU WHERE ID = ?
      <sql:param value="${param.id}" />
    </sql:update>
    <p>Data berhasil dihapus. <a href='latihan1.jsp'>Klik disini untuk kembali.</a></p>

  </c:when>
</c:choose>
</body>
</html>
    

Pada halaman ini, aku memakai tag <c:choose> dan<c:when> untuk membuat struktur logika kondisi, yang melakukan aksi tertentu berdasarkan nilai param.action. Object param adalah object implicit dalam EL yang hampir sama seperti session.getParameter(). Satu-satunya kode Java yang aku pakai disini adalah pemanggilan class UUID untuk menghasilkan nilai ID unik setiap kali penambahan data baru.

25 Juni 2009 at 8:57 PM 2 komentar

Tomcat Native Library: Bagaimanapun Asli Tetap Lebih Cepat

Sebagai seorang programmer yang mencintai kebebasan, dari awal saya tidak berharap terlalu banyak pada Java. Program yang dibuat dengan Java berjalan pada lapisan virtual, sehingga saya tidak dapat memprogram mesin komputer secara leluasa. Maklum, lapisan virtual ini dirancang untuk tetap sama diberbagai platform yang berbeda. Pertanyaannya adalah, jika ingin menyamakan semua platform, lalu bagaimana dengan kelebihan masing-masing platform yang tidak dimiliki platform lainnya? Itu sebabnya sebagai programmer di platform Windows, saya masih menghabiskan waktu bersama Visual C++. Sementara Java cukup mempan dipakai untuk mencari duit (baca: bekerja). Java memungkinkan programmer bekerja dengan cepat dan meningkatkan learning curve; sesuatu yang sangat dibutuhkan oleh industri software.

Kembali ke laptop: Untuk meningkatkan kinerja Apache Tomcat pada production, saya dapat memanfaatkan Tomcat Native Library. Untuk versi Windows, Tomcat Native Library tersedia dalam bentuk file dll (dynamic linking library), dengan nama tcnative-1.dll jika mendownload versi binary-nya. O ya, Tomcat Native Library menggunakan Apache Portable Runtime (APR). Ini adalah static library yang berisi sekumpulan API untuk hal-hal yang platform-dependent (spesifik pada platform tertentu). Source APR terdapat dalam bentuk C/C++, tersedia untuk platform Windows, Linux/Unix, OS2, Netware, dsb. Pada distribusi Windows, source tersebut dapat di-build dengan menggunakan Visual C++. Aku perlu mendownload APR hanya jika aku men-build Tomcat Native Library dari source. Jika aku men-download versi binary, satu-satunya yang aku butuhkan hanya file tcnative-1.dll.

Pada saat menjalankan Tomcat tanpa native library, aku akan mendapatkan salah satu baris berikut di output logger/console-nya:

INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments
was not found on the java.library.path: ...

Untuk mengaktifkan native library, aku hanya perlu meletakkan lokasi folder yang mengandung tcnative-1.dll ke dalam environment variable PATH. Atau, jika aku memakai Eclipse misalnya, aku dapat men-set property java.library.path. Pada perspektif Java EE di Eclipse, aku dapat men-double click nama server, lalu men-klik Open Launch Configuration pada halaman Overview yang muncul. Lalu aku muncul kotak dialog Edit Configuration. Disini aku memilih tab Arguments, lalu pada bagian VM Arguments, aku menambahkan baris seperti berikut ini:

-Djava.library.path="C:\lokasi_folder_dll_native"

Sekarang, jika aku menjalankan server Apache Tomcat, aku akan mendapatkan baris seperti ini:

INFO: Loaded APR based Apache Tomcat Native library 1.1.16.

22 Juni 2009 at 9:17 PM Tinggalkan Komentar

Apache Tomcat: Konfigurasi JNDI

Tomcat juga mendukung JNDI layaknya application server JEE lainnya, hanya saja konfigurasinya lebih tidak user-friendly. Kali ini aku akan mencoba membuat JNDI Resource yang berupa JDBC Data Sources sehingga aku dapat meng-akses database di kode program melalui nama JNDI. Keuntungannya, jika aku mengganti database, aku hanya perlu merubah konfigurasi JNDI Resource tanpa harus mengubah kode program sedikitpun.

Karena aku memakai Oracle Database 10g, aku men-copy file %ORACLE_HOME%\jdbc\lib\ojdbc14.jar (driver JDBC) ke lokasi %CATALINA_HOME%\lib (lokasi yang berisi library yang berlaku untuk seluruh aplikasi web). Lalu aku menambahkan baris berikut pada web.xml milik aplikasi web:

<resource-ref>
	<res-ref-name>jdbc/databaseDevelopment</res-ref-name>
	<res-type>javax.sql.DataSource</res-type>
	<res-auth>Container</res-auth>
</resource-ref>

Lalu, aku menambahkan baris berikut pada %CATALINA_HOME%\conf\context.xml:

 <Resource name="jdbc/databaseDevelopment"
 	auth="Container"
 	type="javax.sql.DataSource"
 	username="scott"
 	password="tiger"
 	driverClassName="oracle.jdbc.OracleDriver"
 	url="jdbc:oracle:oci:@latihan"
 	maxActive="1"
 	maxIdle="10"
 />

Pada konfigurasi di atas, aku memakai data source standard dari Tomcat yang berdasarkan pada DBCP connection pool (salah satu bagian dari Apache Common project). Setelah itu, aku dapat memulai kode di servlet, misalnya:

Context initialContext = new InitialContext();
Context envContext = (Context) initialContext.lookup("java:comp/env");
DataSource ds = (DataSource) envContext.lookup("jdbc/databaseDevelopment");

cn = ds.getConnection();
Statement st = cn.createStatement();
ResultSet rs = st.executeQuery("SELECT ENAME FROM EMP");
while (rs.next()) {
	output.print(rs.getString(1) + "<br>");
}

Jika tidak ingin mengatur konfigurasi JNDI dengan cara manual, melainkan dengan interface berbasis web layaknya application server lain, aku dapat menggunakan AMS dari SpringSource tc Server.  Tentu saja kenyamanan ini diperoleh dengan biaya tertentu (tidak lagi gratis).

11 Mei 2009 at 9:52 AM 2 komentar

Sekedar Info: SpringSource tc Server

Menurut hasil survei, Spring cointainer merupakan 70% penyebab Tomcat banyak dipakai. Oleh sebab itu, tidak heran jika SpringSource memiliki produk SpringSource tc Server yang merupakan versi enterprise dari Apache Tomcat.

Spring tc Server mendukung semua fitur yang dimiliki oleh Apache Tomcat, serta menambahkan beberapa fitur baru. Salah satu fitur yang ditambahkan adalah dukungan AMS (Application Management Suite). Dengan adanya AMS, administrator bisa mengatur dan memonitor aplikasi web melalui dashboard grafis berbasis web ataupun command-line. Beberapa hal yang bisa dimonitor misalnya: application deadlock, garbage collection metric, dan SQL query time. tc Server juga dilengkapi dengan high concurrency JDBC connection pool, yang disebut tc Server Datasource. Default DBCP datasource masih ada, hanya saja karena bersifat single-threaded, ia tidak sesuai dengan aplikasi yang sering melayani banyak permintaan dalam waktu bersamaan.

tc Server mendukung clustering untuk high-availability melalui session replication dan context-attribute replication. Dengan session replication, setiap object session akan direplikasi ke seluruh anggota cluster, dan di-update jika mengalami perubahan. Jika salah satu server mengalami masalah, maka server lain dapat langsung mengambil alih session secara otomatis. Begitu dengan context-attribute replication, dimana yang di-replikasi adalah web application context.

Fitur lain yang ditawarkan adalah update perbaikan bug secara langsung, tanpa harus menunggu rilis versi baru dari Apache Tomcat. Hal ini karena lebih dari 80% commit source code Apache Tomcat selama dua tahun terakhir dilakukan oleh karyawan SpringSource. Mereka siap mendukung pengguna yang membeli SpringSource tc Server.

11 Mei 2009 at 9:46 AM Tinggalkan Komentar

Ant Task: Mempermudah Penggunaan Tomcat Manager

Tulisan kali ini masih berhubungan dengan sebelumnya. Aku sudah mencoba menggunakan
Tomcat Manager dengan cara mengakses langsung melalui URL-nya. Kali ini, aku akan menggunakan cara yang
lebih praktis, yaitu melakukan reloading melalui Ant.

Pada paket standar-nya, Ant menyediakan cukup banyak task, mulai dari yang umum dipakai hingga yang unik seperti
JspC untuk men-compile JSP (agar saat dipakai nanti, tidak perlu compile lagi) dan Telnet untuk membuka session
telnet. Bila task-task yang ada dirasa belum cukup, programmer boleh membuat sendiri task baru. Sebagai contoh,
Tomcat menyediakan task tambahan sehingga proses reloading dapat dilakukan melalui Ant.

Aku akan mencoba latihan membuat task baru di Ant. Misalnya, sebuah task sederhana yang akan menampilkan kotak
dialog ke user. Aku mulai dengan membuat class berikut:

import javax.swing.JOptionPane;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;

public class Latihan extends Task {

	private String pesan;
	
	public void setPesan(String pesan) {
		this.pesan = pesan;
	}
	
	public void execute() throws BuildException {
		JOptionPane.showMessageDialog(null, pesan);
	}
}

Setiap task harus merupakan turunan dari class Task atau sejenisnya. Fungsi setPesan
akan dipanggil oleh Ant saat mem-proses atribut dengan nama pesan. Kode utama untuk Task terletak
di execute().

Langkah berikutnya, aku men-jar class tersebut kemudian meletakkan di folder %ANT_HOME%\lib, dimana
%ANT_HOME% adalah lokasi yang berisi instalasi Ant.

Berikutnya, aku bisa menguji task buatanku dengan membuat build.xml yang isinya sebagai berikut:

<?xml version="1.0" ?>

<project name="Latihan" default="main">
  
  <taskdef name="latihanTask" classname="Latihan" />

  <target name="main">
     <latihanTask pesan="Hi, apa kabar?" />
  </target>

</project>

Aku menggunakan taskdef untuk mendefinisikan task baru. Saat dijalankan, Ant akan memunculkan
kotak dialog yang berisi tulisan “Hi, apa kabar?” dan sebuah tombol “OK”.

Sekarang, kembali ke topik, Tomcat menyediakan file catalina-ant.jar di folder lib yang
berisi tambahan task untuk Ant. Beberapa task dalam catalina-ant.jar yang berhubungan dengan Tomcat
Manager antara lain:

org.apache.catalina.ant.DeployTask
org.apache.catalina.ant.ListTask
org.apache.catalina.ant.ReloadTask
org.apache.catalina.ant.ResourcesTask
org.apache.catalina.ant.RolesTask
org.apache.catalina.ant.StartTask
org.apache.catalina.ant.StopTask
org.apache.catalina.ant.UndeployTask

Berikut ini adalah contoh build.xml yang memanfaatkan task tambahan dari Tomcat:

<property name="url" value="http://localhost:8080/manager"/>
<property name="username" value="snake"/>
<property name="password" value="solidsnake"/>

<property name="task" value="/LatihanApacheTomcat-0.1" />
...
<taskdef name="deploy"    classname="org.apache.catalina.ant.DeployTask"/>
<taskdef name="reload"    classname="org.apache.catalina.ant.ReloadTask"/>
<taskdef name="undeploy"  classname="org.apache.catalina.ant.UndeployTask"/>
...
<target name="deploy" description="Install web application"
        depends="compile">
  <deploy url="${url}" username="${username}" password="${password}"
          path="${path}" localWar="file:\${build.home}" />
</target>

<target name="reload" description="Reload web application"
        depends="compile">
  <reload  url="${url}" username="${username}" password="${password}"
          path="${path}"/>
</target>

<target name="undeploy" description="Remove web application">
  <undeploy url="${url}" username="${username}" password="${password}"
          path="${path}"/>
</target>

Pada build.xml di atas, target deploy akan men-deploy aplikasi web yang berada dalam struktur
exploded directory. Aku meletakkan hasil kompilasi langsung ke lokasi CATALINA_HOME/webapps, sehingga
setiap kali ada class yang aku ubah, aku tidak perlu me-restart server, hanya perlu menjalankan target
reload saja. Task tambahan tersebut pada dasarnya juga akan mengakses URL Tomcat Manager, melalui HttpURLConnection
(dapat dilihat dari source code-nya, jika men-download source Tomcat).

Karena aku menggunakan Eclipse, sebelum aku bisa menjalankan task tambahan, aku harus menambahkan catalina-ant.jar
pada classpath Ant milik Eclipse. Caranya adalah dengan membuka menu Window, Preferences, lalu
memilih Ant, Editor, Runtime. Pada tab Classpath, aku dapat menambahkan jar
tersebut.

07 Mei 2009 at 9:50 PM Tinggalkan Komentar

Apache Tomcat 6: Tidak Mau Sering Restart Server?

Salah satu kendala yang sering ditemui dalam kehidupan sehari-hari saat mengembangkan aplikasi JEE adalah
harus sering restart server untuk melihat hasil perubahan di kode program. Pada aplikasi yang besar,
proses undeploy dan deploy mungkin bisa memakan waktu hingga beberapa menit, belum lagi ditambah waktu
restart server. Bagi yang tidak sabaran,
Tomcat 6 menyediakan Manager yang memungkinkan untuk deploy, undeploy, dan reloading aplikasi web
tanpa harus men-shutdown dan me-restart Tomcat. O ya, karena Tomcat hanya mendukung JSP dan Servlet, sementara
perubahan pada JSP dapat langsung terlihat, fitur ini berguna saat melakukan modifikasi terhadap source
Java seperti servlet. Selain itu, Tomcat juga sudah cukup pintar untuk melakukan reloading secara otomatis pada
kasus-kasus tertentu, misalnya jika file web.xml atau file WAR berubah.

Sebelum memulai memakai Manager, aku harus membuat user terlebih dahulu. Secara default, Tomcat akan
mencari informasi user di file CATALINA_HOME/conf/tomcat-users.xml. Saat aku membuka file ini,
isinya masih kosong. Jadi, aku segera menambahkan baris berikut:

<user name="snake" password="solidsnake" roles="manager" />

Setelah melakukan restart server Tomcat, aku dapat melihat status aplikasi dengan link default sebagai berikut:

http://localhost:8080/manager/html

Browser akan meminta username dan password sebelum dapat melihat informasi aplikasi web yang ada. Dari sini,
aku juga me-reload aplikasi yang ada dengan men-klik link yang tersedia. Tentu saja untuk penggunaan sehari-hari,
akan sangat tidak menyenangkan jika harus membuka halaman ini dan men-klik “reload” setiap kali ada perubahan
class Java di folder “classes” dan libary di folder “lib”.

Cara lain yang paling gampang dan otomatis untuk men-reload aplikasi web adalah dengan memberikan URL tertentu di
browser. Sebagai contoh, untuk mendeploy sebuah aplikasi (dan undeploy terlebih dahulu bila sudah di-deploy sebelumnya),
aku dapat memberikan URL berikut di browser:

http://localhost:8080/manager/deploy?path=/LatihanApacheTomcat&
war=file:C:/LatihanApacheTomcat.war&
update=true

Parameter path menunjukkan context path untuk aplikasi yang akan di-reload; parameter war
berisi lokasi file WAR terbaru (file ini harus berada di host yang sama dengan server Tomcat) atau bisa juga
path yang merujuk ke exploded directory untuk aplikasi web;
dan parameter update bernilai true yang berarti aku ingin melakukan undeploy jika aplikasi sudah
di-deploy sebelumnya. Jika proses berlangsung dengan sukses, aku akan mendapatkan respon berikut:

OK - Undeployed application at
  context path /LatihanApacheTomcat
OK - Deployed application at
  context path /LatihanApacheTomcat

Jika tidak menggunakan WAR melainkan exploded directory, maka aku dapat melakukan reloading dengan
menggunakan URL seperti berikut:

http://localhost:8080/manager/reload?path=/LatihanApacheTomcat

04 Mei 2009 at 8:51 AM 1 komentar

Tulisan Lebih Lama


Arsip


Ikuti

Get every new post delivered to your Inbox.