Java

java

Beginning MyBatis : DataSource, JNDI and Apache DBCP

In this tutorial, im trying to connect a servlet to mysql database using Apache DBCP. Im using mybatis and accessing Apache DBCP’s datasource via JNDI. Btw, im using Netbeans 6.9 and Apache Tomcat 6.

First as always, a table named “contoh” on a database “test”

CREATE
    TABLE contoh
    (
        nama VARCHAR(30) NOT NULL,
        alamat VARCHAR(100),
        PRIMARY KEY (nama)
    )

insert into contoh (nama, alamat) values ('edwin', 'singapore');
insert into contoh (nama, alamat) values ('kamplenk', 'ciledug');
insert into contoh (nama, alamat) values ('nugie', 'pamulang');
insert into contoh (nama, alamat) values ('samsu', 'dago');
insert into contoh (nama, alamat) values ('tebek', 'karawaci');	

and a simple java bean

package com.edw.mybatis.bean;

import java.io.Serializable;

public class Contoh implements Serializable {
    private String nama;
    private String alamat;

	// other setter and getter
	
    @Override
    public String toString(){
        return nama+" : "+alamat;
    }
}

next is creating a simple xml query, ContohMapper.xml.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.edw.mybatis.mapper.ContohMapper" >

    <resultMap id="ContohMap" type="com.edw.mybatis.bean.Contoh" >
        <id column="nama" property="nama" jdbcType="VARCHAR" />
        <result column="alamat" property="alamat" jdbcType="VARCHAR" />
    </resultMap>
    

    <select id="selectAll" resultMap="ContohMap">
        SELECT * FROM contoh
    </select>

</mapper>

and an interface class to map my queries

package com.edw.mybatis.mapper;

import com.edw.mybatis.bean.Contoh;
import java.util.List;

public interface ContohMapper {    
    List<Contoh> selectAll();
}

Dont forget to create a connection pooling configuration on context.xml, which located under META-INF folder.

<?xml version="1.0" encoding="UTF-8"?>
<Context antiJARLocking="true" path="/MyBatisDBCP">
    
    <Resource name="jdbc/test" auth="Container"
            type="javax.sql.DataSource"
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/test"
            username="root"
            password="xxxx"
            maxActive="100" maxIdle="30" maxWait="10000"
            removeAbandoned="true"
            removeAbandonedTimeout="60"
            logAbandoned="true"
            />
            
</Context>

an xml configuration, Configuration.xml. This is where i put my connection properties.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="JNDI">
                <property name="data_source" value="java:/comp/env/jdbc/test"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="com/edw/mybatis/xml/ContohMapper.xml" />
    </mappers>
</configuration>

and a singleton class to load my configuration class,

package com.edw.mybatis.config;

import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


/**
 *
 * @author edw
 */
public class MyBatisSqlSessionFactory {

    protected static final SqlSessionFactory FACTORY;

    static {
        try {
            Reader reader = Resources.getResourceAsReader("com/edw/mybatis/xml/Configuration.xml");
            FACTORY = new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e){
            throw new RuntimeException("Fatal Error.  Cause: " + e, e);
        }
    }

    public static SqlSessionFactory getSqlSessionFactory() {
        return FACTORY;
    }
}

and a simple servlet to call mybatis query

package com.edw.servlet;

import com.edw.mybatis.bean.Contoh;
import com.edw.mybatis.config.MyBatisSqlSessionFactory;
import com.edw.mybatis.mapper.ContohMapper;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;

/**
 *
 * @author edw
 */
public class MainServlet extends HttpServlet {

    private Logger logger = Logger.getLogger(MainServlet.class);

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        try {

            SqlSession session = MyBatisSqlSessionFactory.getSqlSessionFactory().openSession();

            ContohMapper contohMapper = session.getMapper(ContohMapper.class);
            List<Contoh> contohs = contohMapper.selectAll();

            out.println("<html>");
            out.println("<head>");
            out.println("<title>DBCP Example MainServlet</title>");
            out.println("</head>");
            out.println("<body>");
            
            for (Contoh contoh : contohs) {
                out.println(contoh.getNama()+" "+contoh.getAlamat()+"<br />");
                logger.debug(contoh.getNama()+" "+contoh.getAlamat());
            }

            out.println("</body>");
            out.println("</html>");

        }catch(Exception ex){
            logger.error(ex.getMessage(), ex);
            out.println(ex.getMessage());
        } finally {
            out.close();
        }
    } 

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    } 

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        processRequest(request, response);
    }
}

and dont forget to register your jndi and servlet to web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">

    <!-- Session -->
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>

    <!-- Welcome file -->
    <welcome-file-list>
        <welcome-file>mainServlet</welcome-file>
    </welcome-file-list>

    <!--  Servlet -->
    <servlet>
        <servlet-name>mainServlet</servlet-name>
        <servlet-class>com.edw.servlet.MainServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>mainServlet</servlet-name>
        <url-pattern>/mainServlet</url-pattern>
    </servlet-mapping>

    <!-- JNDI -->
    <resource-ref>
        <description>DB Connection</description>
        <res-ref-name>jdbc/test</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
    
</web-app>

And also, dont forget to put your mysql-connector.jar to tomcat lib. And if you see this error, Cannot create JDBC driver of class '' for connect URL 'null', it means there’s something wrong with your JNDI configuration on context.xml.

This is my netbeans project screenshot

and this is what the result will look like

Have fun, cheers. (B)

Clustering and Session Replication Using Glassfish 3.1

Sometimes we need to replicate sessions between clustered environment to make sure session failovers. In this tutorial im trying to clustered 2 Glassfish instances located in the same computer, create a simple webapps and try to see whether session in instance 1 replicated to instance 2. I dont know why but Glassfish 3.0 seems doesnt support clustering so im using Glassfish version 3.1 instead.

Lets start by starting Glassfish, go to /bin and start it from command promt by typing asadmin start-domain domain1.

After it started, go to Glassfish console from your browser. Glassfish console URL will be http://localhost:4848/. Login and start creating a cluster from Clusters menu.

Start your cluster,

congratulation, you have started your cluster. Lets see details from each instances,

it shows your instance’s http port.

To test our session replication, i create a simple web application using Netbeans 6.9.
First is a simple jsp file, index.jsp

<%@page import="java.util.Enumeration"%>
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Session Form</h1>

        <%
                    if (request.getParameter("sessionName") != null && request.getParameter("sessionValue") != null) {
                        HttpSession httpSession = request.getSession();
                        httpSession.setAttribute(request.getParameter("sessionName"), request.getParameter("sessionValue"));
                    }
        %>

        <form action="index.jsp" method="POST">

            your session name : <input type="text" name="sessionName" /> <br />
            your session value : <input type="text" name="sessionValue" /> <br />
            <input type="submit" />

        </form>

        <h1>Your Sessions</h1>

        <%
                    Enumeration sessionNames = session.getAttributeNames();
                    while (sessionNames.hasMoreElements()) {
                        String mySessionName = sessionNames.nextElement().toString();
                        String mySession = request.getSession().getAttribute(mySessionName).toString();
                        out.print(mySessionName+ " --> "+mySession + " <br />");
                    }
        %>

    </body>
</html>

And the most important is the web.xml configuration,

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <distributable id="sessionDistribute" />
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Build it into a war app and deploy it to our clustered environment, always make sure the Availability option checked as enabled.

After you launch it, input some value to jsp page in instance1 and save it. It will save your values to a session.

open instance2’s jsp page and check whether your instance1’s session is there.

As you can see, your sessions from instance 1 is replicated and available from instance 2.

Have fun using Glassfish. 🙂

How To Encrypt Properties File

Sometime i had to put sensitive informations such as database’s username and password on a properties file. In order make it safer, i had to encrypted all the information i had on these properties files. In this simple example, im trying to encrypt database username, password and connection url for iBatis connection, and i use Jasypt library for encryption.

As usual, a simple database,

CREATE DATABASE 'test'
USE 'test'

CREATE TABLE `contoh` (
  `nama` varchar(30) NOT NULL DEFAULT '',
  `alamat` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`nama`)
)

insert into contoh (nama, alamat) values ('edwin', 'singapore');
insert into contoh (nama, alamat) values ('kamplenk', 'ciledug');
insert into contoh (nama, alamat) values ('nugie', 'pamulang');
insert into contoh (nama, alamat) values ('samsu', 'dago');
insert into contoh (nama, alamat) values ('tebek', 'karawaci');

and a POJO

package com.edw.bean;

public class Contoh {
    private String nama;
    private String alamat;

    // other setter and getter

    @Override
    public String toString() {
        return "Contoh{" + "nama=" + nama + ", alamat=" + alamat + '}';
    }
}

A simple xml query, contoh.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="contoh" >

    <resultMap id="result" class="com.edw.bean.Contoh">
        <result property="nama" column="NAMA" columnIndex="1"/>
        <result property="alamat" column="ALAMAT" columnIndex="2"/>
    </resultMap>
   
    <select id="selectAllContoh" resultMap="result">
        select nama, alamat
        from contoh
    </select>

</sqlMap>

and a simple xml to load all my queries, i named it sqlmapconfig.xml. Please take a look at line 21 to 23, these are parameters from properties file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <settings
        useStatementNamespaces="true"
        lazyLoadingEnabled="true"
        enhancementEnabled="true"
        maxSessions="20"
        />

    <transactionManager type="JDBC" commitRequired="false">
        <dataSource type="SIMPLE">

            <property name="SetAutoCommitAllowed" value="false"/>
            <property name="DefaultAutoCommit" value="false"/>

            <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
            <property name="JDBC.ConnectionURL" value="${JDBC.ConnectionURL}"/>
            <property name="JDBC.Username" value="${JDBC.Username}"/>
            <property name="JDBC.Password" value="${JDBC.Password}"/>
   
        </dataSource>
    </transactionManager>

    <sqlMap resource="com/edw/sqlmap/contoh.xml"/>
</sqlMapConfig>

this is my db.properties file, always make sure you had this “ENC( )” on your encrypted values.

JDBC.ConnectionURL=ENC(Q29EXRzvWOsaXiT3YcYjlEN7W4OBU2YulDTnfrHq8LtVL3nyr7ATpQ==)
JDBC.Username=ENC(sM7XAh9750ZUzguilF6kmw==)
JDBC.Password=ENC(GTr5QT97wgVcLNclT8NjClNYKOLeP6c1)

This is my java file, i use it to load db.properties and connecting it to fit parameters on sqlmapconfig.xml.

package com.edw.config;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.File;
import java.io.FileInputStream;
import java.io.Reader;
import java.util.Properties;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.properties.EncryptableProperties;


/**
 *
 * @author edw
 */
public class SqlMapConfig {

    protected static final SqlMapClient sqlMap;

    private static final String PWD = "SDHLKSHUWEHDKSLKLJKSALJDLKA00IUAY98273492JLKASJDLKASJDKLAJSD";
    

    static {
        try {
            StandardPBEStringEncryptor  encryptor = new StandardPBEStringEncryptor();
            encryptor.setAlgorithm("PBEWithMD5AndDES");
            encryptor.setPassword(PWD);
            Properties properties = new EncryptableProperties(encryptor);
            properties.load(new FileInputStream(new File("db.properties")));

            Reader reader = Resources.getResourceAsReader("com/edw/sqlmap/sqlmapconfig.xml");
            sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader,properties);
        } catch (Exception e){
            throw new RuntimeException("Fatal Error.  Cause: " + e, e);
        }
    }

    public static SqlMapClient getSqlMap() {
        return sqlMap;
    }
}

this is my Main class,

package com.edw.main;

import com.edw.bean.Contoh;
import com.edw.config.SqlMapConfig;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author edw
 */
public class Main {

    private Logger logger = Logger.getLogger(Main.class);

    public Main() {        
    }

    private void execute(){
        try {
            List<Contoh> contohs = SqlMapConfig.getSqlMap().queryForList("contoh.selectAllContoh");
            for (Contoh contoh : contohs) {
                logger.debug(contoh);
            }            
        } catch (Exception ex) {
            logger.error(ex.getMessage(),ex);
        }

    }

    public static void main(String[] args) {
        Main main = new Main();
        main.execute();
    }

}

this is what happen on my log window when im running this app

run:
2011-02-06 00:10:27,808 [SimpleDataSource] DEBUG com.ibatis.common.jdbc.SimpleDataSource:26 - Created connection 29524641.
2011-02-06 00:10:27,812 [Connection] DEBUG java.sql.Connection:26 - {conn-100000} Connection
2011-02-06 00:10:27,815 [Connection] DEBUG java.sql.Connection:26 - {conn-100000} Preparing Statement:          select nama, alamat         from contoh     
2011-02-06 00:10:27,855 [PreparedStatement] DEBUG java.sql.PreparedStatement:26 - {pstm-100001} Executing Statement:          select nama, alamat         from contoh     
2011-02-06 00:10:27,855 [PreparedStatement] DEBUG java.sql.PreparedStatement:26 - {pstm-100001} Parameters: []
2011-02-06 00:10:27,855 [PreparedStatement] DEBUG java.sql.PreparedStatement:26 - {pstm-100001} Types: []
2011-02-06 00:10:27,857 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} ResultSet
2011-02-06 00:10:27,873 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} Header: [NAMA, ALAMAT]
2011-02-06 00:10:27,874 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} Result: [edwin, singapore]
2011-02-06 00:10:27,874 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} Result: [kamplenk, ciledug]
2011-02-06 00:10:27,874 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} Result: [nugie, pamulang]
2011-02-06 00:10:27,874 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} Result: [samsu, dago]
2011-02-06 00:10:27,875 [ResultSet] DEBUG java.sql.ResultSet:26 - {rset-100002} Result: [tebek, karawaci]
2011-02-06 00:10:27,876 [SimpleDataSource] DEBUG com.ibatis.common.jdbc.SimpleDataSource:26 - Returned connection 29524641 to pool.
2011-02-06 00:10:27,876 [Main] DEBUG com.edw.main.Main:27 - Contoh{nama=edwin, alamat=singapore}
2011-02-06 00:10:27,876 [Main] DEBUG com.edw.main.Main:27 - Contoh{nama=kamplenk, alamat=ciledug}
2011-02-06 00:10:27,876 [Main] DEBUG com.edw.main.Main:27 - Contoh{nama=nugie, alamat=pamulang}
2011-02-06 00:10:27,876 [Main] DEBUG com.edw.main.Main:27 - Contoh{nama=samsu, alamat=dago}
2011-02-06 00:10:27,878 [Main] DEBUG com.edw.main.Main:27 - Contoh{nama=tebek, alamat=karawaci}
BUILD SUCCESSFUL (total time: 0 seconds)

Btw, im using this test class to generate my encrypted values,

package com.edw.test;

import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 *
 * @author edw
 */
public class TestEncryption {

    private static final String PWD = "SDHLKSHUWEHDKSLKLJKSALJDLKA00IUAY98273492JLKASJDLKASJDKLAJSD";

    public TestEncryption() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
    }

    @Test
    public void test() {

        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWithMD5AndDES");
        encryptor.setPassword(PWD);

        System.out.println(encryptor.encrypt("jdbc:mysql://localhost/test"));
        System.out.println(encryptor.encrypt("root"));
        System.out.println(encryptor.encrypt("password"));

    }
}

and this is my NetBeans project structure

Well, i hope it can help others. Cheers (B)

[Tutorial] Upload File dan Isi Form Sederhana ke Database dengan JSP

Karena banyak pertanyaan terkait insert isi form ke database dan upload image / file ke server, akhirnya gw memutuskan untuk nulis ini di blog gw, kali aja suatu saat ada yang nanya lagi.

Disini gw bikin aplikasi sederhana dengan 1 input text dan 1 input untuk upload file, semua yang diinput akan masuk ke database. Khusus untuk si file akan masuk path relatifnya (image/NamaImageYangDiUpload). Gw pakek library apache commons fileupload, commons io dan Hibernate framework (pake query sql biasa juga bisa tapi gw males aja, ahhahaaa).

oke langsung aja, gw bikin table sederhana banget,

CREATE TABLE upload
(
    id INT NOT NULL AUTO_INCREMENT,
    uploadBy VARCHAR(20) NOT NULL,
    imagePath VARCHAR(200) NOT NULL,
    PRIMARY KEY (id)
)

java bean ma hbm.xml-nya

package com.baculsoft.bean;

public class Upload  implements java.io.Serializable {


     private Integer id;
     private String uploadBy;
     private String imagePath;

    public Upload() {
    }

    public Upload(String uploadBy, String imagePath) {
       this.uploadBy = uploadBy;
       this.imagePath = imagePath;
    }
   
    // other setter and getter

    @Override
    public String toString() {
        return "Upload{" + "id=" + id + " uploadBy=" + uploadBy + " imagePath=" + imagePath + '}';
    }

}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="com.baculsoft.bean.Upload" table="upload" catalog="test">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="uploadBy" type="string">
            <column name="uploadBy" length="20" not-null="true" />
        </property>
        <property name="imagePath" type="string">
            <column name="imagePath" length="50" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

lalu hibernate.cfg.xml buat handle koneksi ke database

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">password</property>
    <property name="hibernate.connection.autocommit">true</property>
    <mapping resource="com/baculsoft/bean/Upload.hbm.xml"/>
  </session-factory>
</hibernate-configuration>

dan file java buat ngeload hibernate.cfg.xml

package com.baculsoft.hbm;


import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.SessionFactory;

/**
 * Hibernate Utility class with a convenient method to get Session Factory object.
 *
 * @author edw
 */
public class HiberUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory from standard (hibernate.cfg.xml) 
            // config file.
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
        } catch (Throwable ex) {
            // Log the exception. 
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

nah ini adalah JSP gw, coba perhatiin kalo gw punya 2 input type. 1 buat input dengan type text 1 lagi buat input type file.

<%-- 
    Document   : index
    Created on : Jan 2, 2011, 9:34:34 PM
    Author     : edw
--%>

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
   "http://www.w3.org/TR/html4/loose.dtd">

<html>
    <head>        
        <title>JSP Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
        <form action="upload" method="POST" enctype="multipart/form-data">
            Input Your Name : <input type="text" name="uploadBy" />
            <br />
            Select file : <input type="file" name="fileSelect" />
            <br />
            <input type="submit" />
        </form>
    </body>
</html>

nah, yang rada ribet ada disini. Ini adalah servlet yg gw bikin khusus buat handle transfer file dari client ke server dan save path+nama file tersebut ke database. Method yg gw gunakan untuk insert ke database ada di line 90.

package com.baculsoft.servlet;

import com.baculsoft.bean.Upload;
import com.baculsoft.hbm.HiberUtil;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.hibernate.Session;

public class UploadServlet extends HttpServlet {

    private Logger logger = Logger.getLogger(UploadServlet.class);

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        String uploadTo = getServletContext().getRealPath("/") + "image/";

        try {
            boolean isMultipart = ServletFileUpload.isMultipartContent(request);

            // no multipart form
            if (!isMultipart) {
                out.println("<html>");
                out.println("<head>");
                out.println("<title>Servlet UploadServlet</title>");
                out.println("</head>");
                out.println("<body>");
                out.println("<h1>No Multipart Files</h1>");
                out.println("</body>");
                out.println("</html>");
            }
            // multipart form
            else {
                // Create a new file upload handler
                ServletFileUpload servletFileUpload = new ServletFileUpload(new DiskFileItemFactory());

                // parse requests
                List<FileItem> fileItems = servletFileUpload.parseRequest(request);

                // open session factory
                Session session = HiberUtil.getSessionFactory().openSession();

                // prepare upload bean
                Upload upload = new Upload();

                // Process the uploaded items
                for (FileItem fileItem : fileItems) {                    
                    
                    // a regular form field
                    if (fileItem.isFormField()) {

                        // disini sama dengan nama input text field di index.jsp yaitu "uploadBy"
                        if(fileItem.getFieldName().equalsIgnoreCase("uploadBy")){
                            upload.setUploadBy(fileItem.getString());
                        }
                    }
                    // upload field
                    else {
                        String fileName = fileItem.getName();
                        File fileTo = new File(uploadTo + fileName);
                        fileItem.write(fileTo);

                        out.println("<html>");
                        out.println("<head>");
                        out.println("<title>Servlet UploadServlet</title>");
                        out.println("</head>");
                        out.println("<body>");
                        out.println("<h1> success write to " + fileTo.getAbsolutePath() + "</h1>");
                        out.println("</body>");
                        out.println("</html>");

                        // set uploaded file's location
                        upload.setImagePath("image/"+fileName);

                    }
                }

                session.save(upload);

                session.flush();
                session.close();

                logger.debug("success");
            }
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        } finally {
            out.close();
        }
    }
   
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        processRequest(request, response);
    }
}

berikut adalah log4j.properties gw

# Global logging configuration
log4j.rootLogger=DEBUG,stdout

# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d [%c{1}] %-5p %c:%L - %m%n

ini struktur project netbeans gw,

ini lib yg gw pakek

File yang berhasil terupload akan disimpan di folder image/. Disini gw coba upload 2 kali.

dan ini isi database gw

Silahkan dicoba masing-masing yeh, :-[