Menggunakan Type Data BLOB di JavaEE

Tutorial ini secara spesifik digunakan untuk meng-handle image yang akan disimpan pada basis data dengan tipe blob. Agak ribet dibanding di php. Kecuali kalo kita tidak pake database module sebagai perantara. Artinya jika kita menggunakan point connection seperti JDBC sebagai media perantara ke basis data yang kita gunakan. Namun, ketika kita menggunakan JPA/JPQL, terdapat perbedaan yang jauh dibanding ketika kita menggunakan JDBC connection. Dengan JPA/JPQL, biasanya kita akan membuat library sebagai media pengantara antara aplikasi (EJB) dengan basis data. Pada library ini biasanya terdapat class manager/controller aksi ke basis data dan entity class yang merupakan representasi/mapping dari basis data.
Misal ketika kita mempunyai table siswa, dimana pada table ini terdapat kolom photo bertipe blob/longblob. Pada entity class dari table siswa, kolom ini akan direpresentasikan dengan type []byte. Sehingga untuk memasukkan file/gambar ke kolom tersebut, kita harus mengubah file image/file lain menjadi variable bertipe array of byte ([]byte). MultipartRequest hanya bisa mendapatkan file yang di upload. Dengan library default, file hanya bisa diubah ke FileInputStream, dll..namun tidak ke []byte. Sehingga untuk mengubah ke []byte, kita perlu menambah library baru yaitu commons-io.
Meski terlihat sederhana, hal ini membawa efek yang cukup besar kepada Servlet. Pada form yang menghandle masukan dari user, akan terdapat perubahan type form menjadi “multipart/form-data”. Perubahan ini mengakibatkan class PageManager (class umum di MI) yang digunakan untuk menangkap parameter request dari user tidak bisa lagi digunakan karena enctype form berubah. (Hati-hati terhadap hal ini, karena jika tidak diperhatikan, akan membuat kita bingung. Parameter request akan selalu null, padahal ini terjadi karena type form yang digunakan sudah berbeda, bukan salah dicode). Sehingga untuk menangkap parameter request tersebut, kita butuh class baru (dalam hal ini penulis menggunakan class MultipartRequest). Dengan class ini, form dengan enctype “multipart/form-data” dapat ditangani. Ketika membangun project, penulis akhirnya menggunakan 2 servlet untuk menangani request dari user. Hal ini diakibatkan karena penulis sudah menulis banyak code dengan menggunakan PageManager sebagai request handler, sehingga malas untuk mengubah code ketika penulis menemukan request handler baru yaitu MultipartRequest. Sebenarnya manfaat dari kedua class ini sama, hanya saja MultipartRequest jauh lebih handal karena dapat menangani semua type form. Hal ini juga terlihat pada jumlah code, PageManager hanya class helper biasa yang sepertinya hanya memindahkan sedikit code dari servlet ke class tersebut. Sedangkan MultipartRequest, code lumayan ribet la.
Berikut merupakan code implementasi dari tutorial ini :
Pada form :
Selec All Code:
1
2
3
4
5
<forms name="addBarang" action="MultipartHandler" ENCTYPE="multipart/form-data" method="POST" onSubmit="return checkrequired(this)">
..............................
<inputs type="file" name="gambar" value="" width="40" />
..............................
forms => form dan inputs => input
Pada servlet :
Selec All Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
try{  MultipartRequest multi = new MultipartRequest(request, ".", 5 * 1024 * 1024);
byte[] image = null;
Enumeration files = multi.getFileNames();
while (files.hasMoreElements()) {
    String name = (String)files.nextElement();
    File fi = multi.getFile(name);
    FileInputStream fis = new FileInputStream(fi);
    image = IOUtils.toByteArray(fis);
}
......................
barang.setGambar(image);
......................
spaceStoreHandler.insert(barang); <!--?pre-->
File-file yang terkait yang dibutuhkan
Library commons-io-2.0.1.jar ..,wait.,ga bisa upload.
Untuk menampilkan image tersebut, ada juga kerumitan. Hal ini dirasakan penulis karena variable yang diberikan dari database adalah []byte. Jika array[]byte tersebut dituliskan, maka yg tampil adalah karakter-karakter aneh. Sedangkan untuk mengubah []byte menjadi file, penulis belum menemukan bagaimana caranya. Sehingga, alternative yang digunakan penulis adalah dengan membuat point connection ke database hanya untuk mengambil gambar tersebut. Hal ini tentu sangat tidak efisien, karena kita akan melakukan satu koneksi hanya untuk mengambil dan mengubah satu gambar untuk ditampilkan. Bagaimana jika gambar yang ingin ditampilkan sangat banyak? Padahal kita tahu bahwa koneksi ke database memakan resource yang besar, apalagi jika basis data yang digunakan adalah basis data remote. Berikut merupakan implementasi yang dilakukan penulis. Sekali lagi, ini bukan merupakan cara yang paling tepat.
DisplayImage.jsp
Selec All Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ page import="java.sql.*"%>
<%@ page import="java.io.*"%>
<% String idBarang = request.getParameter("idBarang");
   Blob image = null;
   Connection con = null;
   byte[] imgData = null;
   Statement stmt = null;
   ResultSet rs = null;
   try {
      Class.forName("com.mysql.jdbc.Driver");
      con = DriverManager.getConnection("jdbc:mysql://localhost:3306/spacestore", "root", "Jesusall");<code>
      stmt = con.createStatement();
      rs = stmt.executeQuery("select Gambar from barang where barangID = '"+idBarang+"' ");
 
      if (rs.next()) {
         image = rs.getBlob(1);
         imgData = image.getBytes(1, (int) image.length());
      } else {
         out.println("Error");
         return;
      }
 
      // display the image
      response.setContentType("image/gif");
      OutputStream o = response.getOutputStream();
      o.write(imgData);
      o.flush();
      o.close();
   } catch (Exception e) {
      out.println("Error");
      return;
   } finally {
      try {
         rs.close();
         stmt.close();
         con.close();
      } catch (SQLException e) {
         out.println("Err");
      }
   }
%></code>
Jika ingin menampilkan gambar dalam jumlah banyak.,maka file ini akan dipanggil sebanyak gambar tersebut.
Selec All Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<c:choose>
 <c:when test="${listbarang == null}">
 
 </c:when>
 <c:otherwise>
      <c:forEach items="${listbarang}" var="barang">
      <td>
          <table border="0" cellpadding="0" cellspacing="0">
            <tr>
               <td width="86" align="center">
                  <a href="SpaceStoreServlet?action=justImg&idBarang=${barang.barangID}">
                     <<strong>img src="displayImage.jsp?idBarang=${barang.barangID}"</strong> width="79" height="66" />
                  </a>
               </td>
               <td width="120">
                  <div>${barang.namaBarang}</div>
                  <div>${barang.deskripsi}</div>
                  <div>Rp <script language="JavaScript">document.write(Comma(${barang.harga}));</script>,00</div>
                  <div style="padding-bottom: 5px"><a href="SpaceStoreServlet?action=viewDetail&item=${barang.barangID}"></div>
               </td>
            </tr>
         </table>
     </td>
Listbarang merupakan collection yang menampung object barang dimana pada objek barang terdapat []byte yang merupakan representasi dari blob.