Wednesday, September 29, 2004

JSF jelek?

Matt Raible yang berpengalaman dengan web framework seperti Struts, Spring MVC, Webwork dan Tapestry mencoba JSF 1.1 (dengan menggunakan Sun's Reference Inplementation) dan berkesimpulan bahwa JSF adalah yang terjelek. Pengalamannya dengan JSF dia tuliskan dalam blognya "My JSF Experience"

Sebuah riset yang membandingkan antara beberapa teknologi dan memberikan kesimpulan bahwa yang satu lebih baik dari yang lain selalu menjadi topik yang menarik,
seperti Windows vs Linux, Java vs .NET dan lain-lain. Tulisan Matt pun jadi perdebatan yang menarik, kita bisa baca hasil diskusi topik ini di TSS.

Tulisan dari David Geary "A reply to Matt Raible's article 'My JSF Experience'" muncul menanggapi tulisan tersebut. Satau tulisan yang bagus dan wajib dibaca setelah membaca tulisan Matt.

Buat saya JSF tetap menarik karena model desainnya event-driven dan action diimplementasi dalam bentuk POJO dan tentu saja mudah digunakan hanya jika menggunakan tool IDE.

Struts atau JSF atau Struts+JSF?

Sebagai java web developer, kadang kita dibingungkan dengan banyaknya web MVC framework yang telah ada. Kemudian tiba-tiba Sun membuat spesifikasi framework standar aplikasi web yaitu JSF (JSR-127), ini membuat kita untuk belajar teknologi baru, membandingkannya untuk kemudian memilih mana yang tepat untuk kebutuhan kita.

Craig McClanahan, orang dulu pertama kali membuat Struts dan salah satu lead dari tim spesifikasi JSF, menulis dalam blog-nya tentang kedua teknologi web tersebut: "Struts or JSF? Struts and JSF?." Untuk aplikasi yang sudah menggunakan Struts menurutnya sebaiknya untuk view layer diganti dengan JSF component tags, untuk menambah kemampuan user interface (JSF memang fokus pada view layer dalam terminologi framework MVC).

Untuk aplikasi baru, dia menyarankan mempertimbangkan hal-hal berikut:

  • Evaluate the two technologies individually, to see if they satisfy your requirements.

  • If one or the other technology is sufficient, go ahead and use it (it's easier to learn and use one technology rather than two where possible); keeping in mind, however, the caveats about Struts HTML tags mentioned above.

  • If your requirements include unique features supported only by Struts (such as Tiles or client side validation support), feel free to use the two frameworks together.


Tuesday, September 28, 2004

Standar baru data persistance untuk J2SE dan J2EE

Dalam artikel "A Letter to the Java Technology Community" Sun memberitakan bahwa mereka akan menginisialisasi sebuah spesifikasi baru untuk data persistance object yang merupakan mix antara EJB (JSR-220) dan JDO (JSR-243).

Model data persistance tersebut akan dibuat berbasiskan POJO (Plain Old Java Object) sehingga lebih sederhana. Diharapkan ini akan menjadi sebuah model data persistance standar untuk J2SE dan J2EE.

Monday, September 27, 2004

Web: PRG Pattern

Post/Redirect/Get (PRG) Pattern adalah pattern untuk solusi masalah duplikasi submit. Poin penting pada pattern ini adalah:
  • Jangan pernah menampilkan halaman hasil respon dari POST
  • Tampilan halaman harus selalu respon dari GET
  • Gunakan REDIRECT setelah request POST menjadi request GET
Lebih jelasnya baca di artikel "Redirect After Get" dan diskusi tentang pattern ini di TSS.
Lihat juga contoh implementasi dan source code dengan menggunakan Struts framework di RPG pattern working example

Saturday, September 25, 2004

Java: Hati-hati dengan FileOutputStream

Posting blog "How I hacked Jroller.com" ini menjelaskan bagaimana kita bisa mengupload file yang berbahaya dengan memanfaatkan bug pada kode program. Triknya sebenarnya simple yaitu menggunakan null byte pada nama file yang akan diupload. Dibawah ini contoh sederhana bagaimana nama file trojan.jsp\000.gif dapat berubah menjadi trojan.jsp
public class Test {


public static void main(String[] args) {
String uploadedFileName = "trojan.jsp\000.gif";
byte[] buffer = new byte[8192];
int bytesRead = 0;
try {
InputStream stream = new FileInputStream("C:\\test.log");

// Save a file with strange file name
OutputStream bos = new FileOutputStream("C:\\"+ uploadedFileName);
while ((bytesRead = stream.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Jadi hati-hatilah dengan kode program kita, validasi yang benar akan menghindarkan kita dari lubang keamanan.

Javascript: Avoid duplicate submit

Menghindari duplikasi pengiriman form bisa diatasi dengan menggunakan Synchronizer Token Pattern seperti di posting sebelumnya. Tapi dapat juga dilakukan dengan menggunakan javascript.

[1] Sebelum form dikirum (submit), check dulu dengan fungsi javascript checkSubmit()
<form action="myAction.do" method="post" onsubmit="return checkSubmit();">

Kode javascript :
<script language="javascript">

var checkSubmitFlg = false;
function checkSubmit() {
if (checkSubmitFlg == true) {
return false;
}
checkSubmitFlg = true;
return true;
}
document.ondblclick = function docondblclick() {
window.event.returnValue = false;
}
document.onclick = function doconclick() {
if (checkSubmitFlg) {
window.event.returnValue = false;
}
}
</script>

[2] Cara lain adalah dengan menggunakan bantuan tag input tipe image :
  <form action="myAction.do" method="post"

onsubmit="getElById('submitInput').disabled = true; return true;">

<input type="image" id="submitInput" src="images/buttonOK.gif" border="0" />

</form>

Struts: Synchronizer Token Pattern

Synchronizer Token Pattern digunakan untuk mengatasi masalah multiple/duplicate submit pada suatu halaman yang memiliki form input.

Submit berulang-ulang pada suatu halaman dari form input biasanya terjadi karena sengaja atau tidak sengaja. Dengan sengaja misalnya user mencoba melakukan posting berkali-kali dengan data yang sama atau secara tidak sengaja misalnya user meng-click tombol submit berkali-kali atau melakukan refresh pada halaman setelah dia post/submit dari halaman form input. Kedua kasus tersebut tentu saja tidak diharapkan, untuk itu kita perlu melakukan trik untuk dapat mencegah terjadinya multiple submit tersebut.

Salah satu solusinya adalah dengan menggunakan Synchronizer Token Pattern, caranya dengan memberikan suatu tanda (token) untuk setiap transaksi (aksi submit dari user). Transaksi dimulai ketika web server akan menampilakan halaman form input. Form input tersebut diberi tanda dengan varibel tersembunyi (hidden input) dengan nilai tertentu biasanya nomor random. Nilai tersebut disimpan di server dalam session milik user. Ketika user melakukan submit pada form, server akan mencocokan nilai token yang dikirim dari form dengan yang ada di session user. Jika nilai tersebut sama maka server akan melanjutkan proses dan me-reset kembali nilai token dan menyimpannya kembali di session user. Jika kedua nilai tersebut berbeda berarti user mengirimkan data yang berbeda dari yang diharapkan server, artinya server akan me-reject data yang dikirim oleh user.

Dengan Struts, kita dapat mengimplementasikan Synchonizer Pattern dengan mudah. Sebelum halaman dengan form input dipanggil, pada action panggilah saveToken(request) untuk menbuat nilai token baru dan menyimpannya di session. Halaman form tidak perlu penambahan apa2, hanya pastikan form yang digunakan menggunakan tag <html:form>. Dengan cara seperti itu form akan memiliki input dengan tipe hidden yang otomatis dibuat oleh struts:


<input name="org.apache.struts.taglib.html.TOKEN" value="d3977d02b2490a92e6f8f22e8a0777b4" type="hidden">

Sedangkan pada action pemroses dari form tersebut kita lakukan pengecekan token sbb:

public ActionForward deleteQuotation(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {

ActionErrors errors = new ActionErrors();
ActionMessages messages = new ActionMessages();

// Check if token is valid
if (!isTokenValid(request)) {
errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.transaction"));
saveErrors(request, errors);
return mapping.findForward("transactionError");
}

try {
// Call business proces here
...

// Reset token
resetToken(request);

messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage("msg.FooSuccess"));
saveMessages(request, messages);
} catch (Exception e) {
e.printStackTrace();
errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error", e.getMessage()));
}
if (!errors.isEmpty()) {
saveErrors(request, errors);
}
return mapping.findForward("submitSuccess");
}

Wednesday, September 22, 2004

Struts: Release terbaru 1.2.4 (Cepat amat!)

Setelah Struts release General Availability (GA) 1.2.2 muncul tanggal 31 Agustus, belum sebulan per 20 Sepetember sudah dirilis Struts realease 1.2.4.

Struts memang dalam mode maintenance dalam beberapa bulan terakhir ini, banyak perombakan disana-sini. Versi 1.2.2 sepertinya terlalu cepat untuk dirilis sebagai GA. Versi 1.2.2 hanya support JDK1.4 (misalnya terdapat penggunaan kode Boolean.valueOf(...)), untuk versi 1.2.4 sudah bisa di-build dengan JDK 1.3

Baca saja relese notes untuk detail perubahan dan penambahan pada Struts versi baru.

Websphere vs Visual Studio .Net

MiddlewareREASEACH membuat perbandingan antara J2EE development dengan RDD (Rational Rapid Developer), J2EE developmet dengan Websphere dan .Net development dengan VisualStudio .Net (VS.NET). Hasil lengkap, source code bisa dihat link berikut:

Comparing Microsoft .NET and IBM WebSphere/J2EE: A Productivity, Performance, Reliability and Manageability Analysis

Berita Microsoft: Study Shows Visual Studio .Net Tops WebSphere jelas-jelas mempromosikan VS.NET. Katanya dari hasil studi tersebut VS.NET lebih unggul dibanding yang lainnya baik baik dari segi productivity, performance dan bahkan cost.

Sebelum memberi kesimpulan sendiri, sebaiknya dibaca komentar2 dari berita ini di TSS.com dan TSS.net Dari salah satu komentar diketahui bahwa applikasi J2EE pada perbandingan tersebut menggunakan plain vanilla J2EE (tanpa framework apapun) yang jelas jarang sekali terjadi, tapi... tapi... baca saja sendiri komentar2nya.

Yang jelas, hasil ini tidak merepresentasikan hal sebenarnya apapun hasilnya karena studi yang komprehensip sulit didapat untuk membandingkan dua hal yang jelas-jelas berbeda.

Struts: BlobAction

Sudah jadi hal yang biasa kita melakukan pengambilan binary data (BLOB) baik itu dari database ataupun file system. Di mailing list strust, seseorang mengirimkan email yang menyarankan menambahkan BlobAction (action class untuk mengambil binary data) pada struts, tentu saja sarannya tidak diterima karena fungsi tersebut terlalu spesifik. Tapi kodenya tentu saja baik untuk diliat sebagai best-practice.

Email dan code untuk BlobAction bisa dilihat disini, tapi sebaiknya dilakukan refactoring sesuai saran dari email berikutnya, terutama dua komentar terakhirnya :

* Your approach is not very flexible. You may not always want to

read the data completely into memory before writing it to the
response.
* BTW, it's a good idea to call response.reset() and, if possible,
to set the content length before writing to the OutputStream.

Tuesday, September 21, 2004

Link: #develop : Opersource IDE untuk C# atau VB.Net

#develop (baca: SharpDevelop) adalah IDE opensource (lisensi GPL) yang berjalan pada platform .NET. Saat ini telah dirilis versi 1.0 (9/11/2004), bisa didownload di

http://www.icsharpcode.net/OpenSource/SD/Download/

Kalo belum punya .Net framework, download disini :

Microsoft .NET Framework Version 1.1 Redistributable Package

Saturday, September 18, 2004

Programming: Closures / Blocks

Essentially a closure is a block of code that can be passed as an argument to a function call.

Java punya inner class, C# punya delegate tapi kedunya berbeda, Martin Fowler menjelaskan konsep pemrograman "Closure" ini disini.


Struts: Yet another best practices

Di artikel ini Struts best practices: Build the best performing large applications dibahas beberapa tips solusi yang biasa dihadapi saat memprogram dengan struts diantaranya :
  • Tampilan dengan elemen/komponen html yang dinamis
  • Mengamankan file JSP
  • Pengkategorian error
  • Validation of service requester (authentication)
  • Application security (authorization)
  • Prepopulation
  • Stack maintenance (for bread crumbs)
  • Masalah Context-related
  • Form-bean scope
  • Implementasi Data transfer object
  • Exceptions
  • Action chaining
Tulisan yang bagus sayang kurang contoh code.



Friday, September 17, 2004

Struts: Menghindari error kehilangan list ketika validasi gagal (prepopulation problem)

Seringkali kita membuat object List atau Collection dari data yang tersimpan di database untuk dropdown-list (combo box) pada halaman html dengan cara memanggil method pada business layer. Pemanggilan method yang menghasilkan List tersebut dilakukan oleh struts Action kemudian disimpan pada scope request.
public ActionForward execute(ActionMapping mapping, ... ) {


List currencyList = CurrencyService.getAllCurrency();
request.setAttribute("currencyList ", currencyList);
...

}
Dihalaman jsp kemudian kita membuat script seperti ini:
  <html:select property="currencyId">

<html:options collection="currencyList" property="lookupId" labelproperty="codeAndDescription"/>
</html:select>
Menyimpan list di scope request saat eksekusi Action akan menjadi masalah jika validasi pada struts form-bean menghasilkan error dan input mapping adalah halaman jsp yang sama dimana diperlukan list untuk dropdown combo. Masalahnya adalah list tidak tersedia di scope request karena setelah validasi mengghasilkan error, Action tidak dieksekusi.

Solusi yang biasa saya lakukan adalah dengan meyimpan list di scope request jika method validate() di form-bean menghasilkan error selain juga di Action.
public ActionErrors validate(ActionMapping map, HttpServletRequest req) {

ActionErrors errors = new ActionErrors();
...
if (!errors.empty()) {
//
List currencyList = CurrencyService.getAllCurrency();
request.setAttribute("currencyList ", currencyList);
}
}
Tentu saja ini kurang baik, karena adanya duplikasi code di form-bean dan di Action. Cara lain yang lebih baik adalah meyimpannya di method reset() pada form-bean sehingga tidak terjadi lagi duplikasi, karena method reset() akan dipanggil setiap kali sebelum form dibuat. Cara kedua ini kurang elegan karena melakukan pemanggilan proses bisnis pada form-bean yang menyulitkan maintenance.

Agar lebih baik, buatlah sebuah class facade dengan method-method static untuk melakukan hal tersebut:
public void reset(ActionMapping arg0, HttpServletRequest request) {

LookupUtility.setCurrencyList(request);
...
}
...akhirnya, saya menemukan artikel terkait dengan tulisan ini (ide tulisan ini sudah ada sebelum artikel dibawah ini ditulis, agak aneh kenapa masalah yang biasa terjadi tidak banyak ditulis orang padahal artikel struts begitu banyak di internet):

How to make sure request scoped lists persist when validation fails

Tulisan lain yang membahas masalah ini: Prepopulation - the three action edit

Javascript: Membuat element pada html page on-the-fly

Ini termasuk most wanted script buat saya: membuat element input pada suatu form pada dokument html.
   _form = document.userListForm;

var method = document.createElement('INPUT');
method.setAttribute('name','method');
method.setAttribute('type','hidden');
method.setAttribute('value','Delete');
_form.appendChild(method);
Pada contoh tersebut, kita membuat sebuah element form input dengan type hidden yang sebelumnya tidak ada. Ini seperti kita membuat pada saat runtime. Method createElement() pada dasarnya digunakan untuk membuat element html apa saja (tergantung browser). Element ini memiliki satu paramater yaitu string tag html, misalnya div, button, image atau yang lainnya.

Referensi: W3C DOM Level 1

Tuesday, September 14, 2004

Link: Java open source

Link ini baru saya temukan, bagus untuk mencari open source project berbasis java:

http://java-source.net/

Biasanya saya cari di sini: sourceforge.net, freshmeat.net dan tentu saja google.com

Memanfaatkan CacheRowSet

Jika kita sering JDBC, pasti sudah familiar ResultSet. Jika Connection, atau Statement yang menghasilkan ResultSet kita close() secara otomatis ResultSet akan close dan kita tidak bisa menggunakan objek ResultSet untuk mengambil data. Begitu juga ketika object ResultSet tersebut di-overide. Hal ini terjadi karena sebenarnya suatu ResultSet hanya merupakan suatu pointer (cursor) yang merujuk pada data sebenarnya di memori, jadi ResultSet tidak menyimpan data.

Dengan CachedRowSet permasalahan itu bisa teratasi, kita bisa membawa object CachedRowSet untuk mengambil data dari hasil query walaupun Connection atau Statement telah di-close(). Bahkan kita dapat melakukan update data langsung lewat CachedRowSet. Ini memudahkan perkerjaan kita karena kita tidak perlu lagi data transfer object jika pekerjaan kita ingin lebih se

CachedRowSet adalah interface meng-extends javax.sql.RowSet, ResultSet, Joinable. Jadi jika kita sudah familiar dengan ResultSet akan mudah menggunakan CachedRowSet.

CachedRowSet mendukung event notification, sehingga kita bisa dengan mudah mengetahui jika cursor bergerak (move), atau terjadi perubahan data.

CachedRowSet yang berawal dari JSR 114, merupakan standar di JDBC 2.0 dan telah masuk dalam standar API di Java 1.5 (Tiger). Jika kita menggunakan java versi 1.4.2 kita bisa menggunakan reference implementation.

Tiga subinterface yang juga sangat bermanfaat adalah FilteredRowSet, JoinRowSet, WebRowSet. Dengan FilteredRowSet kita dapat melakukan filtering data pada RowSet yang sudah kita peroleh tanpa perlu melakukan query lagi ke database. Sedangkan JoinRowSet bermanfaat untuk melakukan penggabungan lebih dari satu RowSet dengan tipe-tipe join database yang sudah kita kenal seperti INNER JOIN, LEFT/RIGHT OUTER JOIN, INNER JOIN, FULL JOIN, CROSS JOIN. Yang terakhir WebRowSet mempermudah kita mengeluarkan output database dalam bentuk XML dan memanipulasinya.

Dokumentasi API dari interface ini cukup baik (ada contoh penggunaannya): http://java.sun.com/j2se/1.5.0/docs/api/javax/sql/rowset/CachedRowSet.html

Tutorial JDBC dari Sun bagian CachedRowSet (ada contoh implementasi untuk distributed application/EJB)

Friday, September 10, 2004

Best Practices

Blog ini akan penuh dengan best practices, tip dan trik. Kenapa?

Saat kita melakukan development suatu sistem hanya dengan dasar pemrograman (bisa memprogram) saja tidak cukup. Apalagi jika menggunakan suatu framework baru, kita tidak hanya perlu belajar bagaimana menggunakannya tapi juga bagaimana menggunakan framework tersebut secara baik dalam arti efektif juga efisien. Oleh karena itu best practices sangat diperlukan. Best practice tidak akan didapat ketika kita pertama kali melakukan permrograman.

Best practice sering didaptkan justru karena kita telah sering melakukan hal-hal yang sama, melakukan tes kemudian mendapatkan masalah. Best practices bisa dianalogikan dengan dengan design pattern dan sering ditemukan setelah kita melakukan beberapa kali refactoring kode.

lebih dari itu best practice dalam proses development tidak hanya berlaku pada kode program saja. Tapi lebih dari itu best practices juga menyangkut proses manajement proyek. Karena pentingnya best practices, maka kita perlu mendokumentasikannya. Selain bermanfaat untuk diri sendiri, dokumen best practice akan berguna bagi pemula untuk dapat dengan cepat belajar dari pengalaman orang lain.

Topik yang menarik kan? Saya akan cari sumber bacaan untuk ini, dan mari kita sharing.

Wednesday, September 08, 2004

Servlet tips: Menghentikan rantai Filter? jangan lupa untuk return void

Kalau kita perlu menghentikan rantai (chain) Filter, misalnya dengan forwarding ke JSP, maka jangan lupa untuk return void, sehingga FilterChain.doFilter() tidak dieksekusi. Jika hal ini tidak dilakukan, lihat saja errornya!

Ini contohnya:

public class LoginFilter implements Filter {
public void doFilter(
ServletRequest req,
ServletResponse resp,
FilterChain chain)
throws ServletException, IOException {

LoginSession loginSession = WebUtility.getLogin((HttpServletRequest) req);
if ( loginSession == null) {
req.setAttribute("message","Login Required: Your session is expired or you are not login.");
((HttpServletRequest) req).getRequestDispatcher( "/errorNotLogin.jsp").forward(req, resp);
return;
}
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}

}

Tuesday, September 07, 2004

Servlet tips: set session=false untuk performansi

Servlet tips: Gunakan <%@ page session="false">di halaman JSP

File JSP by-default akan membuat HttpSessions. Jika kita tidak menggunakan HttpSession pada halaman JSP maka dengan memberikan <%@ page session="false"%>kita akan meningkatkan performansi (walaupun kecil). Ini juga tergantung application server-nya ;)

referensi

Servlet tips: Replikasi HttpSession pada lingkungan distributed web application

Dari artikel: Java theory and practice: State replication in the Web tier

Beberapa web application server (servlet container) yang mensupport clustering atau melakukan replikasi data user (yang biasa disimpan pada session) dengan melakukan serializing objek yang berada di HttpSession yang kemudian ditransfer ke node cluster yang bersangkutan sehingga node tersebut dapat melakukan pemrosesan tersendiri terhadap request dari client. Begitu pula pada sistem load balancing.

Ada tiga pendekatan (cara) replikasi objek session yaitu dengan :
- JDBC-based replication
- File-based replication
- Memory-based replication

untuk memilih opsi mana yang akan kita pilih memperhitungkan/membandingkan cost yang dibutuhkan dari ketiga cara tersebut (web application server yang bagus biasanya mensupport 3 cara replikasi tersebut).

Beberapa tips untuk meningkatkan performansi:
  • Buatlah objek yang disimpan di session seminimal mungkin.
  • Jangan mem-by-pass setAttribute(). Jika kita telah merubah objek pada session lakukan setAttibute() untuk menyimpannya kembali di session, kalau tidak data perubahan tidak akan tersimpan.
  • Gunakan fined-grained object (object yang kecil) yang akan disimpan di atribut session. Ini akan mempercepat proses serializing objek saat di replikasi.
  • Jika tidak digunakan lagi segera invalidate objek. Ini akan menghemat memori karena object tidak menunggu dihilangkan saat session timeout.
  • Usahakan session tetap bersih. Buang session jika tidak lagi diperlukan, sehingga tidak ada lagi yagn perlu di replikasi.

Java New I/O API


Java 2 Standard Edition 1.4 memiliki feature baru yaitu New I/O API (package java.nio) yang memberikan kemampuan performasi yang tinggi dan scalable untuk operasi input/output (baca tulis) files dan sockets, regular expressions, decoding/encoding character sets, in-memory mapping, dan locking file.

New I/O api menambahkan SocketAddress dan InetSocketAddress di package java.net, interface java.lang.CharSequence dan 6 package baru yaitu:

java.nio,
java.nio.channels,
java.nio.charset,
java.nio.channels.spi,
java.nio.charset.spi,
java.util.regex

"spi" singkatan dari "service-provider interface.

Jika kita membutuhkan high performance network I/O seperti router/server yang harus menerima koneksi bersamaan yang banyak, maka kita dapat menggunakan fasilitas API tersebut. New I/O juga sering disebut Non-blocking I/O karena kemampuannya dalam menangani koneksi yang banyak tanpa terjadi blocking I/O.

Cara yang biasa untuk mengangani koneksi I/O bersamaan adalah dengan meng-hanlde tiap koneksi oleh thead tersendiri. Hal ini dapat mengakibatkan banyaknya thread yang menghabiskan resource, menimbulkan kompleksitas singkronisasi antar thread hingga menimbulkannya deadlock.

Prinsip kerja New I/O ini adalah multiplexing dari koneksi I/O yang bersamaan. Beberapa koneksi yang direpresentasikan oleh SocketChannel di-handle oleh sebuah Selector, selector akan melakukan mekanisme baca/tulis dari tiap channel secara serial (multiplexing) dengan cara menggambil buffer. Tiap buffer yang diambil Selector yang merupakan bagian dari bagian data yang dikirim oleh client disebut key atau SelectionKey. Key tersebut kemudian dikirim ke pemroses atau server.

Algotitma non-blocking server adalah sebagai berikut:

create SocketChannel;
create Selector
associate the SocketChannel to the Selector
for(;;) {
waiting events from the Selector;
event arrived; create keys;
for each key created by Selector {
check the type of request;
isAcceptable:
get the client SocketChannel;
associate that SocketChannel to the Selector;
record it for read/write operations
continue;
isReadable:
get the client SocketChannel;
read from the socket;
continue;
isWriteable:
get the client SocketChannel;
write on the socket;
continue;
}
}
Untuk lebih detailnya, baca saja artikel-artikel berikut:

Monday, September 06, 2004

HTTP watcher plugin for browser


Tools dibawah ini saya pakai untuk melihat data HTTP yang dikirim atau diterima oleh browser:

1. ieHTTPHEaders plugin yang paling bagus untuk Internet Explorer, karena sederhana (simple) dan gratis. Download!

2.Untuk pengguna mozilla atau firefox, bisa menggunakan LiveHTTPHeaders

Tools seperti ini penting untuk web developer, karena kadang kita tidak teliti sehingga menyebabkan kesalahan pada penamaan komponen form yang menyebabkan kesalahan pada nama parameter yang di-submit. Dengan alat bantu ini kita bisa lihat semua parameter yang dikirim dari browser ke web server.

Friday, September 03, 2004

Struts: Yang baru dan berubah di versi 1.2

Struts sudah merilis versi barunya 1.2 dengan perubahan dan tambahan yang bisa dilihat di release notes-nya.

Beberapa highlight (perubahan yang tidak signifikan karena jarang saya gunakan atau tambahan feature yang tidak menarik, tidak saya tulis):

  • Kita bisa menggunakan wildcards pada action-mappings. Lihat struts user guide bagian action mapping untuk mepelajarinya
  • Penambahan package Struts-Chain yang masih dalam eksperimen untuk menggantikanRequestProcessor dengan commons-chain (base API untuk implemntasi "Chain of Responsibility" pattern)
  • DTD baru untuk file konfigurasi: struts-config_1_2.dtd
  • Penambahan method pada class Action: getErrors, getMessages, addErrors, and AddMessages .
  • Method deprecated perform() pada class Action dan subclass-nya dihilangkan.
  • Perubahan ActionError menjadi ActionMessage, ActionError tidak dihilangkan tapi sebaiknya tidak digunakan.
  • Lihat contoh untuk aplikasi upload dan validator
  • Attribute name, scope, type dihilangkan pada FormTag
  • Penambahan attribute "module" pada IncludeTag, ImgTag, LinkTag, and RewriteTag, untuk memudahkan cross-linking antar modul
  • Penmbahan custructor pada ActionForward untuk membuat instance baru dari instance lain: ActionForward(ActionForward copyMe)
  • saveErrors(HttpServletRequest, ActionErrors) pada class Action diganti dengan saveErrors(HttpServletRequest, ActionMessages)
  • Metod getResources() dihilangkan dari Action, ActionException (Kenapa ya?)
  • Penambahan method cancelled(...) pada DispatchAction, LookupDispatchAction, dan MappingDispatchAction untuk mengangani ketika tombol cancel di-submit
Sudah cukup sepertinya. Waktunya download

Javascript for checked all html checkbox

Kalo kamu web developer pasti sering membuat list (table) yang menampilkan item dalam banyak baris dengan checkbox, dan membuat satu checkbox yang berfungsi untuk memilih semua item tersebut. Contoh halaman seperti itu bisa kita lihat di "Check Mail"-nya yahoo yang berfungsi untuk memilih item email yang akan diproses, misalnya dihapus.

Yang sering terlewat ketika kita membuat halaman seperti itu adalah, pengecekan apakah item dengan checkbok muncul hanya ada satu atau lebih dari satu atau bahkan tidak ada. Kita biasanya membuat satu chekbox yang berfungsi untuk memilih semua item tersebut selalu tampil walaupun tidak ada item/checkbox dalam list. Biasanya yang terjadi adalah script yang kita buat error karena kita lupa untuk mengecek apakah ada atau tidak, atau jika ada jumlahnya satu atau lebih dari satu.

Karena kita tidak tahu berapa record/item data yang akan muncul, maka di script yang kita buat perlu mengecek apakah ada tidaknya checkbox dan jumlah checkbox. Pengecekan jumlah checkbox dilakukan karena pada javascript penanganan satu checkbox dengan array checkbox (lebih dari datu) berbeda.

Dibawah ini contoh suatu form dengan sebuah checker yaitu checkbox yang berfungsi untuk mengmilih semua checkbox yang bernama userIds.

<form name="listUserForm">
<input name="checker" onclick="checkAll(document.listUserForm.userIds, this)" type="checkbox">
<input name="userIds" type="checkbox">
<input name="userIds" type="checkbox">
<input name="userIds" type="checkbox">
</form>
Script untuk form diatas seperti ini:

<script language="javascript">
function checkAll(checklist, checker) {
if (checklist) {
if (checklist.length > 0) {
for (i = 0; i < checklist.length; i++) {
checklist[i].checked = checker.checked;
}
} else {
checklist.checked = checker.checked;
}
}
}
</script>

Dengan pengecekan (checklist.length > 0) script kita aman dari bug.

Thursday, September 02, 2004

UMLGraph: Tools untuk membuat diagram UML berbasis teks


Saat ini UMLGraph hanya bisa membuat class diagram dan sequence diagram. Kita bisa membuat class diagram lewat yang dispesifikasikan di javadoc. Untuk membuat class diagram program ini menggunakan declarative language yang mudah untuk dimengerti, sedangkan untuk sequence diagram-nya menggunakan imperative language seperti ini:


# Define the objects
object(O,"o:Toolkit");
placeholder_object(P);
step();

# Activation and messages
active(O);
message(O,O,"callbackLoop()");
create_message(O,P,"p:Peer");
message(O,P,"handleExpose()");
active(P);
return_message(P,O,"");
inactive(P);
destroy_message(O,P);
inactive(O);

# Complete the lifeline of O
step();
complete(O);


Sulit dibaca kan? Lebih langkapnya lihat saja website UMLGraph

Tool lain untuk membuat sequence diagram SEQUENCE, jAdvice SEQUENCE

Produk kecil tersebut mungkin jauh dibandingkan dengan XDE, RationalRose, Together dll tapi tetap menarik untuk dicoba.

Followers