Creating Java Download Application

On internet activity, we often do download or upload. Download is an internet activity which takes a file from remote computer to our local computer.

Basically, when we download a file from a remote computer or a server, actually our computer reading byte by byte of a file that we want to download. And after all the byte read then the computer will pack it onto a file that contains perfectly same with the file that we like to download.

With this concept, let’s try to make a little experiment and this experiments will implement all the steps above, we can complete this experiment with another steps that we can gather base on our knowledge that we can find out from the above download process concept.

Let’s try to arrange the steps:

  1. URL identification.

To download a file, we need a valid URL address for sure, and the path location of a file that we want to download. Example: http://www.wayofmuslim.com/ebook-islam/AlQuranDigital.zip. this have a meaning that we want to download a file named AlQuranDigital.zip from a remote computer wayofmuslim.com and the path location of this file at ebook-islam/

  1. The size of file.

Each file that we want to download, have to find out the size of it. The purpose of this are we will be able to compare the bytes length that already read and stored in our local computer with the file that exist on remote computer, so we can find out whether the byte we have downloaded is corrupted or not before we can pack it up onto a file.

  1. The content type of file.

This is optional, we can use this concept or not, it’s an option. But knowing the content type of a file in internet technology is the basic knowledge.

With those concept actually we can create our own application that have ability to download a file from a remote computer, yes we can, because the download concept is that simple.

Now let’s proof it by arrange a scenario based on the concept above to create our own Java Download Application. The scenario is:

  1. Identifying URL.

Checking whether the supplied URL valid or not, we will use URL class that exist on Java.

  1. Valid URL.

If the URL is valid, then go straight to create a HTTP Connection to check whether our computer is connected to the internet or not. And if the URL is not valid then just exit the application and show some screens out telling that the connection is not available.

  1. Identifying the Content Type

If the Http Connection status is good, meaning that the host or remote computer can be contacted, the next step is identifying the content type of a file that we would like to download. In this try-it-out let’s just limit it, if the content type of a file is text/html, then we don’t have to download it. Why? The Http Status 404 (File Not Found) can be occurred on a file that we want to download, and we don’t need this html page to download to our computer rite?

  1. Identifying the byte length (Content Length).

Just because we will to read byte by byte of file that we want to download, so it’s very important to store information of a byte length of the file that we want to download into a variable. And for the next usage this information can be some useful things in order to compare the byte length of downloaded byte with the length of byte that exist on remote computer, to find out whether the downloaded file corrupted or not.

  1. Reading byte by byte.

This is the essential things on our try-it-out. Our application should have an ability to read byte by byte of the file that we want to download and the result of the bytes reading will put on a variable which have byte data-type. The way of bytes reading is using the looping from 0 to the content length that we have store it into a variable before.

  1. Comparing local file to a remote file.

The next step is comparing the length of bytes that already read with the length of byte that stored before on a variable. If the both are not same that’s mean the downloaded file is corrupted and this byte will not be packed onto a file.

  1. Pack the read bytes.

After we knew exactly that the length of read bytes is similar to byte length of remote computer, so it’s time to pack it up onto a file. Let’s just make it easier by naming the file exactly same with the name of file that exist on remote computer.

Using the above scenario, let’s try to code just like the source code below:

package org.mojo.download.agent;

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: May 2, 2009
 * Time: 11:39:49 AM
 * To change this template use File | Settings | File Templates.
 */
public class SingleDownloadAgent {

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage : java SingleDownloadAgent <URL>" );
            return;
        } else {
            SingleDownloadAgent agent = new SingleDownloadAgent();
            try {
                doDownload(args[0]);
            } catch (IOException e) {
                System.err.println("Exception e");
            }
        }
    }
    public static void doDownload(String sURL) throws IOException {
       URL u = null;
        //try URL
        try {
            u = new URL(sURL);
        } catch (MalformedURLException ex) {
            System.err.println("Malformed URL : " + ex);
            return;
        }
        catch (IOException ex) {
            System.err.println("An Error Occured : " + ex);
            return;
        }
       //reading Connection
        URLConnection uc = null;
        try {
            uc = u.openConnection();
            //identifying connection
            uc.connect();
        } catch (IOException e) {
            System.out.println("Cannot Connect: Please Check Connection");
            return;
        }

        String contentType = uc.getContentType();
        System.out.println("contentType :" + contentType);

        int contentLength = uc.getContentLength();
        if (contentType.startsWith("text/html") || contentLength == -1) {
            throw new IOException("This is html file.");
        }

        //collecting byte in var data
        InputStream raw = uc.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] data = new byte[contentLength];
        int bytesRead = 0;
        int offset = 0;
        while (offset < contentLength) {
            bytesRead = in.read(data, offset, data.length - offset);
            if (bytesRead == -1) break;
            offset += bytesRead;
        }
        in.close();

        //file corrupted
        if (offset != contentLength) {
            throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes ? File Corrupted…");
        }

        //writing byte data to a file
        String filename = u.getFile();
        filename = filename.substring(filename.lastIndexOf('/') + 1);
        FileOutputStream fout = new FileOutputStream(filename);
        fout.write(data);
        fout.flush();
        fout.close();

    }
}

On the above source-code we have two methods, which is the main method and the doDownload method with sURL string as it’s parameter. Let’s discuss it line by line the above source-code:

As usual, at the beginning of the code we declare the package where this class is located and the declaration of imported class that we will need later. And then on the main method we check whether the URL parameter supplied when this class is called. Indeed, this application designed has to supply the URL parameter when this application called.

package org.mojo.download.agent;

import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.net.MalformedURLException;
import java.net.URLConnection;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: May 2, 2009
 * Time: 11:39:49 AM
 * To change this template use File | Settings | File Templates.
 */
public class SingleDownloadAgent {

    public static void main(String[] args) {
        if (args.length == 0) {
            System.out.println("Usage : java SingleDownloadAgent <URL>" );
            return;
        } else {
            try {
                doDownload(args[0]);
            } catch (IOException e) {
                System.err.println("Exception e");
            }
        }
    }
………

On this main method, showed that if the URL parameter is not supplied then this application will print out the message of application usage and then directly quit. And if the URL parameter supplied then the application will continuing call the doDownload method with args[0] as it’s parameter.

Now let’s take a look at the second method which is doDownload methods:

   ………
   public static void doDownload(String sURL) throws IOException {
       URL u = null;
        //try URL
        try {
            u = new URL(sURL);
        } catch (MalformedURLException ex) {
            System.err.println("Malformed URL : " + ex);
            return;
        }
        catch (IOException ex) {
            System.err.println("An Error Occured : " + ex);
            return;
        }
    ………

On these lines we run out first scenario which is validating the URL, and we put it on a try-catch block. Why we put it on try-catch block? Because we want to know if the error occurred, where it will be happen.

…………
        //reading Connection
        URLConnection uc = null;
        try {
            uc = u.openConnection();
            //identifying connection
            uc.connect();
        } catch (IOException e) {
            System.out.println("Cannot Connect: Please Check Connection");
            return;
        }

        String contentType = uc.getContentType();
        System.out.println("contentType :" + contentType);

        int contentLength = uc.getContentLength();
        if (contentType.startsWith("text/html") || contentLength == -1) {
            throw new IOException("This is html file.");
        }
…………

And after that, on the lines above code we check the connection to host or remote computer by put it once again on try-catch block, and then the next line we find out the content type of the file that we want to download and put the information on a string variable called contentType. And then we check the content length that we want to download and put in on a integer type variable. And the next lines is continue by the branching to make a decision if the content typeof the file is type/html type, then just quit the application.

    …………
        //collecting byte in var data
        InputStream raw = uc.getInputStream();
        InputStream in = new BufferedInputStream(raw);
        byte[] data = new byte[contentLength];
        int bytesRead = 0;
        int offset = 0;
        while (offset < contentLength) {
            bytesRead = in.read(data, offset, data.length - offset);
            if (bytesRead == -1) break;
            offset += bytesRead;
        }
        in.close();

        //file corrupted
        if (offset != contentLength) {
            throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes ? File Corrupted…");
        }
    …………

On the lines above, we can see the reading of byte by byte do by our application, using the open up the output-stream and then read the output stream by looping byte and using the content length as it limitation, and then put it the read result into a data variable that have byte data-type. And after the read process is finished the output-stream is closed and then we create a statement to compare the length of read bytes that stored on offset variable with the contentLength variable.

…………
        //writing byte data to a file
        String filename = u.getFile();
        filename = filename.substring(filename.lastIndexOf('/') + 1);
        FileOutputStream fout = new FileOutputStream(filename);
        fout.write(data);
        fout.flush();
        fout.close();

    }
…………

And this is the last codes that we have created, on this codes we pack up the bytes that we have read and stored into a data variable before, into a file. To naming the file, we just named as a same filename that we want to download.

That’s it, our try-it-out for this time. There’s still a lot that we can explore more from this little experiments, such as we can build a GUI as its interface, or adding some progress bar animation, etc. Please explore more of this concept to creating more perfect things.

 

 

Hope it will be useful.

Menteng, March 3rd 2009

 

Josescalia.

Advertisements

Using Spring Framework on Creating DAO Layer

On J2EE or J2SE project development, sometimes there’s one block which have a function to manage everything related with the database, result fetching of supplied queries was managed on this block. With this type of design, we’re easier to track if there’s an error on our java application.
For Java Developer which familiar to use database as a part of the application, doesn’t have any difficulty to create a block which have a function as a database access, and then place the block inside the architecture of the application.

When creating this database access block, there’s some way that we can use, one of them is using Spring Framework. Yes, now we will try to use Spring Framework to access database, by creating database access or more familiar as DAO Layer. And for this try-it-out we will use MySQL Database (Again….? Oh God…). First thing we have to do to try-this-out is create a table on a database on MySQL Database and complete this table with the data needed. We will name this table as web_account and containing about 10 or 20 data inside. For the field of this table, let’s just create with our desire. Or maybe we can copy-paste this below SQL Code:

CREATE TABLE `web_account` (
  `USERNAME` varchar(30) NOT NULL DEFAULT '',
  `PASSWORD` varchar(30) NOT NULL DEFAULT '',
  `CREATE_TIME` datetime DEFAULT NULL,
  `CREATE_USER` varchar(30) DEFAULT NULL,
  `UPDATE_TIME` datetime DEFAULT NULL,
  `UPDATE_USER` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`USERNAME`)
);

INSERT INTO `web_account` VALUES ('admin','adminya33','2009-03-15 08:32:21','admin','2009-03-15 08:32:21','admin'),('andre','andre456','2009-03-15 08:34:53','admin','2009-03-15 08:34:53','admin'),('fitri','fitri54','2009-03-15 08:33:22','admin','2009-03-15 08:33:22','admin'),('ganteng','ganteng99','2009-03-15 08:34:21','admin','2009-03-15 08:34:21','admin'),('gerry','gerry87','2009-03-15 08:33:41','admin','2009-03-15 08:33:41','admin'),('gue','guelagi','2009-03-15 08:33:56','admin','2009-03-15 08:33:56','admin'),('hebat','hebatlah','2009-03-15 08:34:36','admin','2009-03-15 08:34:36','admin'),('heru','heur334','2009-03-15 08:32:54','admin','2009-03-15 08:32:54','admin'),('joe','joe77','2009-03-15 08:32:39','admin','2009-03-15 08:32:39','admin'),('kasep','sekap25','2009-03-15 08:33:08','admin','2009-03-15 08:33:08','admin'),('linux','linux09','2009-03-15 08:35:22','admin','2009-03-15 08:35:22','admin'),('mojo','monk123','2009-03-15 08:31:50','admin','2009-03-15 08:31:50','admin');

From the structure of the table above, we have to create a Java Class which has class properties that can represent the fields of the table above. The purpose of this class creation is this class will be the container of the data table. On usage of java code, this class will be an object variable that can be accessed as Array of Object or Single Object.

We will create this class by using simple POJO (Plain Old Java Object), below is the source code of this class:

package org.mojo.spring.entity;

import java.util.Date;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: Mar 15, 2009
 * Time: 8:45:10 AM
 * To change this template use File | Settings | File Templates.
 */
public class WebAccount {
    private String userName;
    private String password;
    private Date createDate;
    private String createUser;
    private Date updateDate;
    private String updateUser;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

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

    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    public String getCreateUser() {
        return createUser;
    }

    public void setCreateUser(String createUser) {
        this.createUser = createUser;
    }

    public Date getUpdateDate() {
        return updateDate;
    }

    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }

    public String getUpdateUser() {
        return updateUser;
    }

    public void setUpdateUser(String updateUser) {
        this.updateUser = updateUser;
    }

    public String toString() {
        return "WebAccount{" +
                "userName='" + userName + '\'' +
                ", password='" + password + '\'' +
                ", createDate=" + createDate +
                ", createUser='" + createUser + '\'' +
                ", updateDate=" + updateDate +
                ", updateUser='" + updateUser + '\'' +
                '}';
    }
}

And now we are ready to create a DAO Layer using Spring Framework, don’t forget to download the needed libraries such as Spring Library, MySQL Connector library, and common-logging library, because these libraries is needed to follow this try-it-out. The common-logging library has to include too in this try-it-out, because the Spring Framework have a very high dependencies to this library. And the MySQL Connector library is needed too, because we use MySQL Database on this try-it-out (Again… :P).

For the DAO Layer that we will create below, we just limit it on fetching how many rows data on the table (SELECT COUNT(1) ) and fetching all data (SELECT *) only. The others method such as insert, update, or delete, we can add it later. For the select count(1) method the run-down scenario is: this method will have a return data type as integer, while the select * method will have a return data type as a list. Let’s see below source code:

package org.mojo.spring.dao.JdbcDao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.mojo.spring.entity.WebAccount;

import javax.sql.DataSource;
import java.util.List;
import java.util.ArrayList;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.ResultSet;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: Mar 15, 2009
 * Time: 8:46:57 AM
 * To change this template use File | Settings | File Templates.
 */
public class WebAccountJDBCDAO extends JdbcDaoSupport {
    private DataSource ds;
    private JdbcTemplate tpl;

    public int getNumOfWebAccount() {
        logger.info("getNumOfWebAccount");
        int iRes = 0;
        ds = getDataSource();
        tpl = new JdbcTemplate(ds);
        String sQuery = "SELECT COUNT(1) from web_account";
        try {
            iRes = tpl.queryForInt(sQuery);
            logger.info("Result of getNumOfWebAccount : " + iRes);
        } catch (Exception e) {
            logger.info("Exception in getNumOfWebAccount()" + e.getMessage());
        }
        return iRes;
    }

    public List<WebAccount> getWebAccountList(boolean flagLimit, int limit) {
        final List<WebAccount> result = new ArrayList();
        final int iLimit = limit;
        ds = getDataSource();
        JdbcTemplate tpl = new JdbcTemplate(ds);
        String sQuery = "SELECT * FROM rss_feeder";

         if (flagLimit) {
            sQuery += " LIMIT ?";
        }

        class PreparedStatementHandler implements PreparedStatementSetter {
            public void setValues(PreparedStatement ps) throws SQLException {
                int n = 0;
                ps.setInt(++n, iLimit);
            }
        }

        class ServiceHandler implements RowCallbackHandler {
            public void processRow(ResultSet rs) throws SQLException {
                WebAccount wa = new WebAccount();
                wa.setUserName(rs.getString("WEB_ACCOUNT"));
                wa.setPassword(rs.getString("PASSWORD"));
                wa.setCreateDate(rs.getDate("CREATE_DATE"));
                wa.setCreateUser(rs.getString("CREATE_USER"));
                wa.setUpdateDate(rs.getDate("UPDATE_DATE"));
                wa.setUpdateUser(rs.getString("UPDATE_USER"));
                result.add(wa);
            }
        }

        if (flagLimit) {
            tpl.query(sQuery, new PreparedStatementHandler(), new ServiceHandler());
        } else {
            tpl.query(sQuery, new ServiceHandler());
        }
        return result;
    }
}

Let’s discuss above codes. On the top of the source code, there’s a declaration where this class is located, and the next lines, we just import the needed class of Spring Framework library and other Java default library.

package org.mojo.spring.dao.JdbcDao;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.mojo.spring.entity.WebAccount;

import javax.sql.DataSource;
import java.util.List;
import java.util.ArrayList;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.ResultSet;
………

We have named this class as WebAccountJDBDDAO class, marked by the class declaration on the next line after comment lines (I’m Using IntelliJidea as my favorite IDE). After the class declaration, we create 2 variables, ds as DataSource type and tpl as JdbcTemplate type.

………
public class WebAccountJDBCDAO extends JdbcDaoSupport {
    private DataSource ds;
    private JdbcTemplate tpl;
………

DataSources is a type of object that we picked up from javax.sql package, while the JdbcTemplate is a type of object that we picked up form Spring package, located on org.springframework.jdbc.core.JdbcTemplate. And then, let’s take look one by one the methods that exist on the codes.

Method getNumOfWebAccount:

……
 public int getNumOfWebAccount() {
        logger.info("getNumOfWebAccount");
        int iRes = 0;
        ds = getDataSource();
        tpl = new JdbcTemplate(ds);
        String sQuery = "SELECT COUNT(1) from web_account";
        try {
            iRes = tpl.queryForInt(sQuery);
            logger.info("Result of getNumOfWebAccount : " + iRes);
        } catch (Exception e) {
            logger.info("Exception in getNumOfWebAccount()" + e.getMessage());
        }
        return iRes;
    }
……

On this method we can see, the query that will be execute is only simple query which is “select count(1) from web_account”. If we execute this query on MySQL Console, the result of this query is the number of how much rows are exists on web_account table. On this method we put the result of the query into a variable iRes, this iRes variable has a integer as it’s data type. If we want to arrange the steps of this method, the steps will be seen as:

  1. Create integer type variable and name it as iRes.

  2. Initialize the ds variable by calling getDataSource interface.

  3. Create new JdbcTemplate object and the parameter is ds.

  4. Create a String variable, named as sQuery and directly fill the string by the MySQL query.

  5. Execute the query on try-catch block and then put the result of the query into iRes variable.

  6. Crate a return statement of the methods.

While the lines containing logger, is our way to mark the process flow, so if there’s any error occurred on the codes we can trace it easily.

And then let’s discuss the 2nd method which is getWebAccountList method. On this method, we create 2 inner class, the purpose of this inner class creation is to make our codes look more orderly:

…….
       class PreparedStatementHandler implements PreparedStatementSetter {
            public void setValues(PreparedStatement ps) throws SQLException {
                int n = 0;
                ps.setInt(++n, iLimit);
            }
        }

     class ServiceHandler implements RowCallbackHandler {
            public void processRow(ResultSet rs) throws SQLException {
                WebAccount wa = new WebAccount();
                wa.setUserName(rs.getString("USERNAME"));
                wa.setPassword(rs.getString("PASSWORD"));
                wa.setCreateDate(rs.getDate("CREATE_TIME"));
                wa.setCreateUser(rs.getString("CREATE_USER"));
                wa.setUpdateDate(rs.getDate("UPDATE_TIME"));
                wa.setUpdateUser(rs.getString("UPDATE_USER"));
                result.add(wa);
            }
        }
…….

If we take a look on the codes of both inner classes, each of this inner class handled two important functions. The function on the first inner class handled PrepareStatement, this class implements PrepareStatementSetter belongs to Spring Framework. And the 2nd inner class handled the localization of query result onto WebAccount object variable, this inner class implements RowcallbackHandler belongs to Spring Framework also.

On the 1st inner class we override setValues methods that owned by the PreparedStatementHandler class as a requirement of implementation. And the 2nd class we also have to override processRow method as a requirement of RowCallBackHandler class implementation. And then let’s take a look at the main code of the getWebAccountList method that we’ve already created before.

……
 public List<WebAccount> getWebAccountList(boolean flagLimit, int limit) {
        final List<WebAccount> result = new ArrayList();
        final int iLimit = limit;
        ds = getDataSource();
        JdbcTemplate tpl = new JdbcTemplate(ds);
        String sQuery = "SELECT * FROM rss_feeder";

         if (flagLimit) {
            sQuery += " LIMIT ?";
        }
……..
……..
……..
        if (flagLimit) {
            tpl.query(sQuery, new PreparedStatementHandler(), new ServiceHandler());
        } else {
            tpl.query(sQuery, new ServiceHandler());
        }
        return result;
    }
……

On the main code of the above method we have return value as a list and 2 parameters which is flagLimit as boolean type and limit as integer type. The steps of this method arrangement is same with the first method that we have created before on getNumOfWebAccount method, just because that we have 2 parameters on this method, so let’s create a little programming logic here, which is on branching lines. On the branching lines we create a logic if the value on flagLimit is true then the query will be added by “LIMIT ?” so the query will be “SELECT * FROM web_account limit ?”, and if the value of flagLimit is false then the query will not be change, but it still same just like the first initialization.

The dots that exist in the middle of the main codes are the codes of inner classes that we have discussed before. And then we have arrived to the code where the lines of query execute. In this lines there’s also a branch that will decide whether the code will use the inner PreparedStatementHandler class of not, the decision of this usage is depends on flagLimit variable value, go head, do your own analyze the branching codes. And the end of this method is the existence of the return statement declared as a list that represented by the result variable. That’s it, that’s how we use Spring Framework on creating DAO Layer. And the next step are we will try to use the DAO Layer in the Java Consol Application.

In order to use this DAO Layer, we have to make a Spring Framework configuration file. Ok, let’s just create this file, let’s name it as “applicationContext.xml” file, just like another article posted before which using Spring Framework also. We will place this configuration file on a config folder which is a line with the src folder on this try-it out project. Below is the source code of Spring Configuration file.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
    <!--Data Source-->
    <bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost/java_spring"/>
        <property name="username" value="root"/>
        <property name="password" value="root99"/>
    </bean>

    <bean id="webAccountDAO" class="org.mojo.spring.dao.JdbcDao.WebAccountJdbcDAO">
        <property name="dataSource" ref="ds"/>
    </bean>
</beans>

Let’s take a look of this configuration file, the first bean that we have to create is ds, this bean is a bean which have a function to access MySQL Database, this bean use the class that belongs to Spring Framework which is DriverManagerDataSource class. And then, just because this is the Spring access block to connect to database, so we have to supply the property that related with the connection to database creation, such as username, url, password, dan driverClassName of the database that we will use and it’s property given is depends on the setting of our MySQL database settings.

And then the 2nd bean is a bean that will represent DAO Layer that we have created above. The property that has to be filled up by this bean is dataSource property, while the reference of this bean property is ds bean that we have cerated before.

And the usage of this DAO Layer on Java Console Application, shown as the codes below:

package org.mojo.spring.application;

import org.mojo.spring.dao.JdbcDao.WebAccountJdbcDAO;
import org.mojo.spring.entity.WebAccount;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: Mar 15, 2009
 * Time: 11:05:55 AM
 * To change this template use File | Settings | File Templates.
 */
public class SpringReadDatabase {

    private WebAccountJdbcDAO dao = null;
    public static void main(String[] args) {
        //call SpringConfiguration File
        ApplicationContext ctx = new FileSystemXmlApplicationContext("config/applicationContext.xml");
        SpringReadDatabase app = new SpringReadDatabase();

        //call Desired bean
        app.dao = (WebAccountJdbcDAO) ctx.getBean("webAccountDAO");

        //declare Variable
        WebAccount[] waList = null;

        //getNumOfWebAccount
        int i = app.dao.getNumOfWebAccount();
        System.out.println("Num Rows : " + i);

        //getWebAccountList
        List<WebAccount> list = app.dao.getWebAccountList(false,0);

        //convert List to ObjectArray
        if (list.size() > 0) {
            waList = new WebAccount[list.size()];
            for (short j = 0; j < list.size(); j++) {
                waList[j] = list.get(j);
            }
        }

        //iterate ObjectArray to PrintOut to console
        for (int j = 0; j < waList.length; j++) {
            WebAccount webAccount = waList[j];
            System.out.println("Name : " + webAccount.getUserName());
            System.out.println("Password : " + webAccount.getPassword());
            System.out.println("FullWebAccount : " + webAccount);
        }

    }

    public void setDao(WebAccountJdbcDAO dao) {
        this.dao = dao;
    }
}

That’s it, that’s how we use the DAO Layer that we have created before by using Spring Framework in Java Console Application. To discuss this java console application, please do your own analyzing in order to get more understanding of the codes that we have created.

 

I hope this will helpful.

Menteng, March 15th 2009

 

josescalia

Accessing Property File Using Spring Framework

On the previous post in this blog using Indonesian language, we tried to use property file to access database in order to avoid hardcode mechanism, and the accessing of the property file by using a class named ConfigProperties, now we will try to access property file without using those class but we will try to use Spring Framework to access property file.

As we knew, the existence of Spring Framework on Java technology is really-really help us the Java Developer, the modularity of this framework has made the enterprise java project development is easier to rebuild or modify.

We will not discuss much more about the Spring Framework here, we only will try to use the Spring Framework one of this framework feature to access property file. And of course the values of the property file to be used on our application chain later.

Let’s go directly to try this out. On Spring Framework, the usage of bean became a must, that’s why we will create an object as a representation of a bean, the scenario that we will make is every item that exist on property file will become a property of the object that that we have created. Let’s make the property file just like below:

application.properties file:

application.name=mojo
application.password=mojo123
application.url=http://localhost:8080/test_doang/test.jsp

We will put this file on config folder, a line with the src folder, just like below picture shown:

foldermacam2spring

With the item of the property file, we will create a simple object of Java pojo which will represent each item that exist on the property file above. The source code of this object is below:

PropertyHolder.java file:

package org.mojo.spring.entity;
/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: Mar 9, 2009
 * Time: 7:04:46 PM
 * To change this template use File | Settings | File Templates.
 */
public class PropertyHolder {
    private String name;
    private String password;
    private String url;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

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

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String toString() {
        return "PropertyHolder{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                ", url='" + url + '\'' +
                '}';
    }
}

 

 

 

 

On above source code, we create a file named PropertyHolder.java. On this file we only create 3 property of the object, because there’s only 3 item on the property file. On the usage, each property of this object will hold values that exist on the property file.

In order to make each item on the property file can be inject into each object property, we have to define the object on Spring configuration file, so when the application run, this configuration will be called at first line and finally each item on the property file can be injected into each property of the PropertyHolder object that we have created before. Below is the definition of the object that we define as a bean on spring configuration file, this file will also put on same folder with the property file location which is on config folder.

applicationContext-app.xml file:

 

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>

    <bean id="propertyConfigurer"          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="config/application.properties"/>
   </bean>

       <!-- Local Data Holder -->
    <bean id="propertyHolder" class="org.mojo.spring.entity.PropertyHolder">
        <property name="name" value="${application.name}"/>
        <property name="password" value="${application.password}"/>
        <property name="url" value="${application.url}"/>
    </bean>
</beans>

Basically, when an application that using Spring Framework start running, then all the bean that already configured on Spring configuration file will also called one by one, even maybe one bean will depends on another bean. On the defined bean above, we can see that we have defined two beans there, the first bean have an id called “propertyConfigurer”, this bean have a function to give information to the Spring Framework the location of the property file. While the other bean given an id as “propertyHolder”, this bean is a map of the object that we have created before. Let’s make an attention to the defined class of the second bean, and then each property that defined on the block of this defined bean, this is how we map each item of the property file to each property on the object.

Actually, this is the main focus of our try-it-out today, here’s how we access each items on the property file using Spring Framework. And if when we want to use the value of the property file items, all we need is just called the PropertyHolder object only, a line before we set the PropertyHolder object for sure. The usage example is just like below:

package org.mojo.spring.application;

import org.mojo.spring.entity.PropertyHolder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * Created by IntelliJ IDEA.
 * User: Mojo
 * Date: Mar 9, 2009
 * Time: 7:06:35 PM
 * To change this template use File | Settings | File Templates.
 */
public class TestReadProperty {
    private PropertyHolder holder =null;

    public void setHolder(PropertyHolder holder) {
        this.holder = holder;
    }

    public static void main(String[] args) {
        ApplicationContext context    = new FileSystemXmlApplicationContext("config/applicationContext-app.xml");
        TestReadProperty app = new TestReadProperty();
        app.setHolder((PropertyHolder) context.getBean("propertyHolder"));

        System.out.println("Name : " + app.holder.getName());
        System.out.println("Password : " + app.holder.getPassword());
        System.out.println("Url : " + app.holder.getUrl());
        System.out.println("full : " + app.holder);
    }
}

On the source code of usage example above, we can describe it just like this:

At first PropertyHolder object defined as a private variable named as holder. Then there’s a method which have a function as a setter of the holder object. And then on the main method of this sample program, we have defined an ApplicationContext as an object, this context called the Spring Framework configuration file, and then we have to define this program as an object too, in order to make all the property of the object can be called on the main method.

The next step is, set the PropertyHolder object by calling setter method of the PropertyHolder that we have made before on this example program. When this method called, then automatically Spring Framework will fill up the property of PropertyHolder object with the value of each item that exists on the property file. And the last step is we tried to print-out the value of object property that owned by PropertyHolder class to console. And don’t forget to import all the necessary class and library that needed by this example application on the top line of this example program as we seen above.

That’s it, our try-it-out today, a little try-out that using one the feature of Spring Framework that has a lot and useful feature that we can use on our development project. And if you want to try-it too, don’t forget to download the library of Spring Framework and other libraries that become dependency libraries for the Spring Framework it self

Have a nice try ….!!!

 

 

I Hope this will helpfull

Menteng, March 10, 2009

 

Josescalia

My First Flex Project

Two weeks ago, Vises, my work mate is busy creating something. I made an attention of what he busy for, and I found that he is recreating an absence application that I have made 6 months ago. I have created this absence application using Java Swing as a client and J2EE with Spring Framework as its server. I made this application because the HRD and Finance division of my office wanted me to create an application that able to log staff absences, so the finance division can pay the meal allowance for the staff based on its log every day.

The unique thing of this friend activity is, he tried to rebuild this absence application by using Adobe Flex. Well, I was interested with this Adobe Flex, my interest is more to Adobe Flex ability to create a pretty GUI design. By using Adobe Flex Builder, the making of design a GUI application is just simple drag and drop. It looks like creating a GUI application in Java by using the Netbeans and its Matisse Builder plug in. Actually there’s a little disappoint of mine, when I’m using Netbeans to create a Java GUI application. Sometimes the release build of my Java GUI application is not appropriate with the design of development. After seeing this Adobe Flex, I thought I should change my presentation layer of an application especially Desktop Application by using this Adobe Flex.

For about one weeks and three days, I search reference and then try to use this Adobe Flex as a presentation layer of my created application. And indeed, I have found that I easier to use Adobe Flex as a presentation layer of my application. And its looks like that I will decide to use Adobe Flex as a presentation layer of applications that I will create in the future.

Adobe Flex supported 3 Remote Application methods, which is:

1.    RPC Method (Remote Procedure Call).

2.    HTTP Service Method (read Web Application return using XML format).

3.    Web Service Method.

From those methods, the most preferred method of mine is the second method which is HTTP Service method. Adobe Flex can read a Web Application XML formatted return value, and then the value can be inserted into components that exist on Adobe Flex framework.

And I thought, because I have searched for about one week and three days about this Adobe Flex, it has to be at least one application that I can make using this Adobe Flex framework. Hmmm…… I thought what simple application that I can make with my limited knowledge of this Adobe Flex Framework. I got an idea; I will create a simple RSS Reader application. Why should RSS Reader? I thought a RSS reader is XML formatted, so it will be easier to make, because I don’t have to design the XML format for my first simple Flex application.

And after one day in front of my laptop try to create this application, finally my First Adobe Flex project created. Here are screenshot of my Flex RSS Reader Application.

Picture-1:

rssreader-tab1Picture-2:

rssreader-tab2

Let me try to describe here about the concept of my flex RSS Reader application. This RSS Reader application has 2 tabs. The first tab is RSS Reader, this is the main function of this application as it’s seen on picture-1, while the 2nd tab contains an form that have functions that can manage RSS link to be added, updated, or deleted by using this tab as it’s seen on picture -2.

On screenshot of picture-1, we can see there’s a combo box that user can choose, from what resource of the news that he would like to read. When user clicks one of the sources from the combo box, this application will try to request RSS Feeder to a link that became a value data on the combo box. After all the result of the request done, this application will automatically load the result of news items to Data Grid component on RSS List Panel, and when one of the news item on Data Grid component clicked by the user, this application will also automatically load the short description of the news to Text Area component on the Description panel. When user interest to read the full article of the news that selected, user can click Read This button. When this button clicked, then the default browser of user’s computer will show and directly open the page containing the news that he would love to read.

While on the screenshot of picture-2, is a view of RSS Entry tab, which on this tab, user can manage the sources of the RSS Reader on this application. When user wants to add a new source of RSS Feeder, he just needs to enter each text boxes on Add RSS Entry Panel and then click Add button. And when he needs to update or delete one of sources that already loaded on Data Grid on the Listed RSS Entry panel, all he needs is just click the item on the Data Grid and the application will automatically fill up the text boxes on the Edit RSS Entry panel, and then he click the update or delete button depends on what he want to do with the source item. And then we also can see on the both picture there’s an Exit button on the right top of the form. The function of this button is to close this Flex RSS Reader application.

This simple Flex RSS Reader application actually has a Back-End Application that I have created using PHP and MySQL Database. The Back-End Application will produce a web page XML Formatted result containing a list of RSS Reader sources that stored on MySQL Database table. Just because I don’t understand yet about how to use the property file on Flex Development, I do hardcode to write a link of this RSS Reader Back-End Application.  The Link of this RSS Reader Back-End Application is: http://localhost/flex_xml_lab/rss/rss_feeder.php. If you are interested of this application, then you also have to create this RSS Reader Back-End Application, and the link must be same with above Back-End Link that I have hardcode on this application.

And the XML formatted result that produced by the Back-End Application must have a pattern below:

 

<rss_list>
     <RSS>
        <RSS_ID>1</RSS_ID>
        <label>Detik</label>
        <data>http://rss.detik.com/index.php/detikcom</data>
     </RSS>
     <RSS>
         <RSS_ID>2</RSS_ID>
         <label>Detik Inet (local sample)</label>
         <data>http://localhost/flex_xml_lab/rss/rss_detikinet.xml</data>
     </RSS>
     <RSS>
        <RSS_ID>3</RSS_ID>
        <label>Google News (local sample)</label>
        <data>http://localhost/flex_xml_lab/rss/rss_google.xml</data>
     </RSS>
     <RSS>
        <RSS_ID>10</RSS_ID>
        <label>Detik Inet</label>
        <data>http://www.detikinet.com/feed</data>
     </RSS>
     <RSS>
         <RSS_ID>11</RSS_ID>
         <label>Antara Terkini</label>
         <data>http://www.antara.co.id/rss/news.xml</data>
     </RSS>
     <RSS>
         <RSS_ID>12</RSS_ID>
         <label>Antara Sains Dan Teknologi</label>
         <data>http://www.antara.co.id/rss/tek.xml</data>
      </RSS>
</rss_list>

 

On the Back-End Application, I made a table on MySQL Database named flex_project and the table name is rss_feeder, and the detail of the table shown below:

desc_rss_feeder

Or you also can make the table with this MySQL Syntax:

 

CREATE TABLE `rss_feeder` (
  `RSS_ID` int(100) NOT NULL AUTO_INCREMENT,
  `RSS_NAME` varchar(100) NOT NULL,
  `RSS_LINK` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`RSS_ID`)
);

 

And then, to create a Back-End Application using php, I have created a simple PHP CRUD (Create, Read, Update, and Delete) application to do select, insert, update, and delete database operation on to the table. I simplified this Back-End Application by creating only one php file. And the interaction between the database and php file can be recognized by a parameter named action for each database operation. I choose HTTP GET methods for interaction between a PHP and Flex RSS Reader Application, so the each database operation on the php file can be executed by detail below:

·      Action Read rss_feeder

http://localhost/flex_xml_lab/rss/rss_feeder.php?action=read

·      Action Insert rss_feeder

http://localhost/flex_xml_lab/rss/rss_feeder.php?action=add&rss_name=[name_of_rss_source]&rss_link=[link_of_rss]

·      Action Edit rss_reader

http://localhost/flex_xml_lab/rss/rss_feeder.php?action=add&rss_id=[id_of_rss]&rss_name=[name_of_rss_source]&rss_link=[link_of_rss]

·      Action Delete rss_reader

http://localhost/flex_xml_lab/rss/rss_feeder.php?action=delete&rss_id=[id_of_rss]

To accommodate above methods, then I created one php file only, and the source of the php file is below:

 

<?php
//define database paramater
define( "DATABASE_SERVER", "localhost" );
define( "DATABASE_USERNAME", "root" );
define( "DATABASE_PASSWORD", "9mtouche9" );
define( "DATABASE_NAME", "flex_project" );
$conn = mysql_connect(DATABASE_SERVER,DATABASE_USERNAME, DATABASE_PASSWORD);
mysql_select_db( DATABASE_NAME );
//define HTTP GET paramater
$action = $_GET['action'];
$return="";
//action read
if($action=="read"){
    $query = "select * from rss_feeder";
    $res = mysql_query($query);
    //return list of rss link
    $return = "<rss_list>";
         while ($result = mysql_fetch_object($res)) {
                   $return .="<RSS>
              <RSS_ID>$result->RSS_ID</RSS_ID>
              <label>$result->RSS_NAME</label>
              <data>$result->RSS_LINK</data>
              </RSS>";
         }
    $return .= "</rss_list>";
    mysql_close();
}
//action add
if($action=="add"){
    $rss_name = $_GET['rss_name'];
    $rss_link = $_GET['rss_link'];
    $query = "insert into rss_feeder(RSS_NAME,RSS_LINK) values('$rss_name','$rss_link')";
    $res = mysql_query($query);
    //$result = mysql_fetch_row($res);
    //return list of rss link
    $return = "<action_result>";
       if($res){
         $return .= "true";
       }else{
         $return .= "false";
       }
    $return .= "</action_result>";
}
//action edit
if($action=="edit"){
    $rss_id = $_GET['rss_id'];
    $rss_name = $_GET['rss_name'];
    $rss_link = $_GET['rss_link'];
    $query = "update rss_feeder set RSS_NAME='$rss_name', RSS_LINK='$rss_link' where RSS_ID='$rss_id'";
    $res = mysql_query($query);
    //$result = mysql_fetch_row($res);
    //return list of rss link
    $return = "<action_result>";
       if($res){
         $return .= "true";
       }else{
         $return .= "false";
       }
    $return .= "</action_result>";
}
//action delete
if($action=="delete"){
    $rss_id = $_GET['rss_id'];
    $query = "delete from rss_feeder where RSS_ID='$rss_id'";
    $res = mysql_query($query);
    //$result = mysql_fetch_row($res);
    //return list of rss link
    $return = "<action_result>";
       if($res){
         $return .= "true";
       }else{
         $return .= "false";
       }
    $return .= "</action_result>";
}
//print out result
print($return);
?>

 

 

On the script, indeed there’s another action instead read, another action also return XML formatted result, just because the return of another action is boolean type, so let’s just ignore it.

That’s it, a short description of this simple RSS Reader application that I have made by using Adobe Flex. I’m quite satisfied, because this Adobe Flex is so easy to design and to create a GUI application. And for the result the output of the GUI is prettier than Java Swing Application. And for the release build, Adobe Flex Builder has also owned it by using wizard, it’s really simple at least for me.

And for you, who wants to learn or maybe modified and learning together with me, below is the sources link of My First Flex Project

1.    RSS Reader Source (Zip File)

2.    PHP Back-End Application

3.    MySQL source file.

And Please feel free to rebuild and modify with your own need and desired, and don’t forget to give back your comment through this post.

 

Menteng, March 7th 2009.

I hope this will helpful

 

Josescalia

Accessing Ms Access Database with Java

Microsoft Access is a software database which still has been used until now. This database is very light, so this is an advantage for it’s user to chose this type of database in order to save the data. Microsoft Access is also come with a lot and usable feature. Starting from creating table, form, queries, report, and even the macros, everything became simple when we want a do it on Microsoft Access, and its typically often that this Microsoft Access is used by everyone to make a database application where the data will be save on its self.

We will not discuss a lot about what Microsoft Access can do here. On this time we will try to accessing a database that created using Microsoft Access with our beloved programming language which is Java.

Now, let’s arrange a scenario to discuss this topic:

  1. Create a database file named Java_MsAccess using Microsoft Access.

  2. Create a table on that database which contains fields:

  • Field name: CustomerID, type Number (single).

  • Field name: CustomerName, type Text (50).

  • Field name: CustomerAddress, type Text (250).

  • Field name: CustomerPhone, type Text (20).

  1. Fill up the table with necessary data.

  2. Create a DSN Data source DSN for this database.

  3. Create a Java Application for accessing this database using the Data source.

For the step 1 until the step 4, we will attach a screen shot only here, because I believe that we can do these steps without written reference here.

Okay, for the 1st step, below is the screen capture:

createmsaccessdb

And for the 2nd step, below is screen capture:

createmsaccessdb

 

And for the step 3rd, this is how we do it:

fillupmsaccesstable

And for the step 4th, okay for this step we will explain a little bit, so we can understand how to create a data source on windows platform for this database.

  • Click start Control Panel Administrative Tools Data Sources(ODBC)

  • And then on ODBC Database Administrator window, click Add button and then choose Driver do Microsoft Access (*.mdb), and then click finish button.

  • And then on ODBC Microsoft Access Setup window, give a name for this database JavaMsAccess, and then choose the database file by clicking select button, and find the database file that we have crated before. This is the image looks like:

createodbcdsn

And the DSN data source named by JavaMsAccess created successfully. Now we arrive to the step that we are cannot be patient to wait which is creating the Java application. Okay, here’s the process flow of our Java Application looks like:

  1. Choose and initialize the driver for this ODBC data source.

  2. Create a database connection to this ODBC data source.

  3. Create a Statement for the SQL Queries.

  4. Pick up the result of Query Statement executiom onto ResultSet

  5. Printout the ResultSet.

From these scenarios, let’s implement it on to Java Code. Take a look this Java source code below:

package org.mojo.blog.Java_depth.aboutMsOffice;

import Java.sql.*;

/**
* Created by IntelliJ IDEA.<br>
* User: Mojo<br>
* Date: 08 Feb 09<br>
* Time: 22:30:08<p>
*/
public class MsAccessJava {
private static String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
private static String url = "jdbc:odbc:JavaMsAccess";
 public static void main(String[] args) {
     String sql ="SELECT * from tblCustomer";
       try {
          Class.forName(driverName);
          Connection conn = DriverManager.getConnection(url);
          System.out.println("Connection Established..");
          Statement stmt = conn.createStatement();
          ResultSet rs = stmt.executeQuery(sql);
          while (rs.next()){
             System.out.println("+------------- Detail Customer ----------------------+");
             System.out.println("Customer ID : "+ rs.getInt(1));
             System.out.println("Customer Name : "+ rs.getString(2));
             System.out.println("Customer Address : "+ rs.getString(3));
             System.out.println("Customer Phone : "+ rs.getString(4));
             System.out.println("+----------------------------------------------------+");
             System.out.println("\n");
         }
       } catch (SQLException e) {
          e.printStackTrace();
       } catch (ClassNotFoundException e) {
          e.printStackTrace();
     }
  }
}

Let’s discuss line per line the above code.

The first line is a line where this Java file located on its package. While the 3rd line is a line where all the classes of Java.sql library has imported. And then we can see inside the program that there are two private static string variable defined which is:

………..
   private static String driverName = "sun.jdbc.odbc.JdbcOdbcDriver";
   private static String url = "jdbc:odbc:JavaMsAccess";
………..

The first variable is a driver name that we will use it later to accessing ODBC data source, while the second variable is an url of the data source that we would like to access, just remember this data source name have to equals with the data source that we have created before which is: JavaMsAccess.

And then let’s take a look the codes inside the main method. The first line on this main method is a line where we define a SQL query which we will use to access these Microsoft Access database. And then we create a try-catch block, this block is the block which all main process of the accessing process is happen. First in this block we initialize the driver that we have defined in the header of the program. And then we create a database connection and the print out the result of it’s connection.

…….
   Class.forName(driverName);
   Connection conn = DriverManager.getConnection(url);
   System.out.println("Connection Established..");
……….

The continuous steps are, create a statement, then execute the SQL Statement using the SQL query that we have defined before.

…….
     Statement stmt = conn.createStatement();
     ResultSet rs = stmt.executeQuery(sql);
……….

And the print out the result by loops the rs variable, which these ResultSet variable values had filled up before.

…….
   while (rs.next()){
        System.out.println("+----Detail Customer ------------------+");
        System.out.println("Customer ID : "+ rs.getInt(1));
        System.out.println("Customer Name : "+ rs.getString(2));
        System.out.println("Customer Address : "+ rs.getString(3));
        System.out.println("Customer Phone : "+ rs.getString(4));
        System.out.println("+--------------------------------------+");
        System.out.println("\n");
   }
…….

And then we add some catch statement to prevent error appear on runtime, and this catch is also can be use to trace the problem when error occured that can make our application cannot run properly.

If the program executed, and then the result will show just like image below – i have executed it on my favourite IDE, IntelliJidea 7.0.4

executeodbc_java

That’s it, that’s all our try out has finished. Please try and modify for your own need and your own desire.


Hope this will usefull

Menteng, 09th February, 2009


josescalia

Managing Authentication in Tomcat with JDBC Realms

After few times ago, we have used session to managing authorization for accessing Jsp pages, now let’s try to make another authentication for a web application by using Realms.

On Apache or any similar web server, we use Realms authentication by include a file called .htaccess to a directory, so only the listed users can access the content of those directory.

Just like the Apache, Realm is a feature of Tomcat which handles an authentication for the user who would like to access all the resources on a web application. Realm controls the roles of each listed user, these roles are references for tomcat to rule out which users can access which web application. By default Realms is flexibility supported by Tomcat. This flexibility mean is Tomcat is supporting this authentication with several ways that we can use as use as we like. The Realms authentication methods already supported by Tomcat are:

  1. File based authentication (The Memory Realms). With this method, the authentication processed by reading a file called tomcat-users.xml that exist on <Tomcat-Folder>/conf/tomcat-users.xml, this file contains a list of users with their roles.
  2. Database (JDBC) authentication(The JDBC Realms). This method is using database as storage of user list and its roles. On Tomcat 5.5, by default, there’s a few database software which is already supported for this JDBC Realms methods. In order to use this method we have to install the database connector by copying the database connector library such as mysql-connector.jar onto <Tomcat-Folder>/common/lib/.
  3. JNDI authentication (JNDI Realms). On this authentication method, Tomcat will validate user and its roles by reading the web directoryservice, such as LDAP. When using this authentication method the JNDI providers have to installed to Tomcat by copying the libraries on to <Tomcat-Folder>/common/lib/ folder.

From those above Realms authentication, we will try the second method which is Database (JDBC) authentication(The JDBC Realms) as out try-it-out now. We will use mysql database as storage of users list and its roles. While the scenarios of our try-it-out today are bellows:

  • Create a database as a storage which can hold users list and its roles.

  • Create a mysql username and password, this username is dedicated for a database that we have created on first step, and this username only had read privileges.

  • Activate Realm JDBC configuration on Tomcat.

  • Create web application configuration in order to make this web application support Realms.

On above scenarios, actually we only do once from step 1 to step 3, means the configuration from step 1 to step 3 will became permanent on Tomcat environment. While the step 4 is optional, means every web application that we will deploy later is may to use this Realm authentication, and may not use too, so it’s depends on us to decide whether a web application will using Realm authentication or not. And then if we want to add user with its roles, so the modification will only do inside mysql database.

And now let’s run out one by one the scenarios above. For the first scenario, please create a database and its tables on mysql database, just like mysql query bellows:

create database tomcat_server;
use tomcat_server;
-- Table structure for table `user_auth` --
CREATE TABLE IF NOT EXISTS `user_auth`
  ( `USERNAME` varchar(30) NOT NULL default '',
  `PASSWORD` varchar(30) NOT NULL default '',
   PRIMARY KEY (`USERNAME`) )
ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- Dumping data for table `user_auth` --
INSERT INTO `user_auth` (`USERNAME`, `PASSWORD`) VALUES ('admin', 'admin99'), ('mojo', '7mono7');
-- Table structure for table `user_role` --
CREATE TABLE IF NOT EXISTS `user_role`
  ( `ROLE_NAME` varchar(30) NOT NULL,
    `USERNAME` varchar(30) NOT NULL )
    ENGINE=MyISAM DEFAULT CHARSET=latin1;
-- Dumping data for table `user_role` --
INSERT INTO `user_role` (`ROLE_NAME`, `USERNAME`) VALUES ('tomcat', 'mojo'), ('manager', 'admin'), ('admin', 'admin');

These Query, can also directly executed by copy-paste onto mysl console, just remember the database, tables, users, and roles for the next configuration or scenarios.

Let’s continue with the 2nd scenario which is creating dedicated mysql username and password which only have read only privileges access. Why read-only privileges access? Because we have to be careful to give an access privileges on database user, especially the context of this Realms is related with the access of our whole web application. For this 2nd scenario, these is only my suggestion, but if you want to make a database user with more access privileges than this scenario for your next development, go a head (All by your own risk). Below is a sample query which can accommodate the 2nd scenario.

grant select on tomcat_server.* to 'tomcat-user'@'localhost' identified by 'tomcat55';

On above query, we make a user named tomcat-user and the password is tomcat55, grant select is a command of mysql database that this user have the read-only access to tomcat_server database.

And then let’s continue to the 3rd scenario, which in this scenario, we will activate the Realm configuration with JDBC methods on Tomcat. Realm configuration placed on servlet.xml file which is located on <Tomcat-Folder>/conf/ folder. So we have to modify this file in order to activate Realm with JDBC method. There are two steps to do in this 2nd scenario. The steps are:

  1. Activate Realm Configuration.

    Find and modify the servlet.xml just like bellow:

    <Realm className="org.apache.catalina.realm.UserDatabaseRealm" 
          resourceName="UserDatabase"/>
  2. Activate and modify the JDBC Realm configuration refers to 1st scenario that we did before. Modify the server.xml file just like below:

     <Realm className="org.apache.catalina.realm.JDBCRealm" 
               driverName="com.mysql.jdbc.Driver" 
               connectionURL="jdbc:mysql://localhost/tomcat_server" 
               connectionName="tomcat" connectionPassword="tomcat55" 
               userTable="user_auth" userNameCol="USERNAME" 
               userCredCol="PASSWORD" userRoleTable="user_role" 
               roleNameCol="ROLE_NAME" /> 

    Lets discuss a bit for our review of above configuration, in this configuration we are using com.mysql.jdbc.Driver for mysql-connector driver, and the we are using tomcat as a name for database username and for the database password we are using tomcat55 to create connection into mysql database as we have created before on the previous scenarios. Please make sure that the value on this configuration is correct as we create the data on database at the previous scenario.

And then now we can run 4th scenario which is applying JDBC Realms authentication to our web application. Just create or use the existed web application to applying this Realms authentication. We can apply this Realms Authentication by modifying web.xml file which is located on <Tomcat-Folder>/webapps/<your’s-application>/WEB-INF/ folder.

The modification can be do by adding few lines just like below on our web.xml file:


<?xml version="1.0" encoding="UTF-8"?> 
<web-app 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" 
            version="2.5"> 
<!--Access Configuration based on Realms--> 
   <security-constraint> 
      <web-resource-collection> 
         <web-resource-name>All Page</web-resource-name> 
         <url-pattern>/*</url-pattern> 
      </web-resource-collection> 
      <auth-constraint> 
         <role-name>tomcat</role-name> 
      </auth-constraint> 
   </security-constraint> 

   <login-config> 
      <auth-method>BASIC</auth-method> 
      <Realm-name>Tomcat-Advance-Authentication-Realm</Realm-name> 
   </login-config> 
    ... 
    ... 
<web-apps> 

On those lines above, all the authentication will be applied to whole resources on this web application, marked by line <url-pattern>/*</url-pattern>, and then for the authorization methods we are using BASIC.

That’s all, our try-it-out, using JDBC Realm on Tomcat as a validation for user to our web application resources. Please don’t you ever have a doubt to more explore for your own need and your own desires.

Thanks.

Menteng, Januari 26th 2008.

Josescalia.

Few Tips and Trick on Jsp and Servlet

On a web technology development using java programming language, we knew Servlet and Jsp. Servlet and Jsp came as presentation layer of a web application structure. Presentation layer is a layer which has responsibility to present view of processing result as the end of data flow process. When choosing servlet or jsp as a presentation layer, there’s must be some proper and suitable consideration referred to the purpose

Even though it’s just a presentation layer on a web application, Servlet and Jsp are also have some interest things to explore and use on our web application. Below are some tips and tricks which can be used on a Servlet and Jsp.

  1. Get parameter value from deployment descriptor(web.xml) using init Servlet method.

  2. Chek out this codes:

    public class SendMailServlet extends HttpServlet {
        private String smtpHost;
    
      public void init(ServletConfig config) throws ServletException {
        super.init(config);
        smtpHost = config.getInitParameter("smtpHost");
      }
     …………………………
    }
    

    Above code is a sample of a Send mail Servlet application. The process of send mail, must be need a SMTP Host as a server to send email in order to make email can be received to whom its send. In order to preventing hard-code, SMTP host name put it on a deployment descriptor (web.xml), so if there’s a change of a SMTP host name we don’t need to recode the source, recompile and redeploy the application, what we do is only change the value of a smtpHost parameter on web.xml and the application can run normally with a little modification.

    And of course below is cut code of a web.xml where the value of this parameter defined.

    <servlet>
            <servlet-name>sendMessage</servlet-name>
            <servlet-class>org.mojo.mail.web.servlet.SendMailServlet</servlet-class>
            <init-param>
                <param-name>smtpHost</param-name>
                <param-value>smtp.speed.net.id</param-value>
            </init-param>
    </servlet>
    

    And for the process flow are, when the first time this Servlet initialized and the application server will call the init method on this Servlet, and then this method will fill up the smtpHost variable with the value taken from the deployment descriptor where the Servlet defined.

  3. Using RequestDispatcher Interface to throw a process to another servlet.

  4. Its become an interesting chosen, when we made a scenario that each servlet will handling each different task. Such as there’s a Servlet which only handle send mail process, or a Servlet which only handle displaying error message, etc. with this type of scenario, we will be able to trace error, that’s possible to happen on a process flow, because each process have a different module.

    With this kind of scenario, we must need a throw of a process from one servlet to another servlet.To throw a process from one servlet to another servlet, we can use a RequestDispatcher interace. Chek out these codes:

    public class Test1Servlet extends HttpServlet{
    
         public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doGetInvoked");
            throwToServlet(req, res);
           }
        public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doPost Invoked");
            throwToServlet(req,res);
           }
        private void throwToServlet(HttpServletRequest req, HttpServletResponse res)
             throws IOException, ServletException {
            System.out.println("This Process wil throw to another servlet");
            RequestDispatcher rd = getServletContext().getNamedDispatcher("Test2");
            rd.forward(req,res);
          }
    }
    

    On above servlet class codes we can see there’s a line

    RequestDispatcher rd = getServletContext().getNamedDispatcher(“Test2”);

    This line is a line where the servlet will get ServletContext that declared on web.xml, and this line followed by below line

    rd.forward(req,res);

    and this line is a line which telling the application to throw a process to another servlet named Test2.

    Practically, don’t forget to add servlet Test2 definition on web.xml

    And if we want to throw the process flow to another servlet, but the thrown came from jsp, we do little modification of the line, so the changes will be look like below:

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%
      RequestDispatcher rd = getServletConfig().getServletContext().getNamedDispatcher("Test2");
      rd.forward(request,response);
    %>
    

    There’s an addition of a getServletConfig methods on initialized line of RequestDispatcher interface, and for the parameter of forward method is fill up with request and response that default on jsp class.

  5. Using sendRedirect method to throw a process to another URL.

    If on 2nd trick we used RequestDispatcher interface to throw a process to another servlet, in this trick we will use sendRedirect method to throw a process to another URL. The differences about this trick with 2nd trick is the 2nd trick only throw a process to a servlet that located at the same web-app context, while this trick it’s not just throwing a process to same web-app context but also throw using cross URL or different URL.

    To throw a process to another URL, please take a look below codes:

    public class Test1Servlet extends HttpServlet{
    
         public void doGet(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doGetInvoked");
            throwToURL(req,res);
           }
        public void doPost(HttpServletRequest req, HttpServletResponse res)
            throws ServletException, IOException {
            System.out.println("doPost Invoked");
            throwToURL(req,res);
           }
         private void throwToURL (HttpServletRequest req, HttpServletResponse res)
             throws IOException, ServletException {
            System.out.println("This Process wil throw to another URL");
            res.sendRedirect("Test2");
          }
    }
    

    On the above code, a line that telling the system to throw a process to another URL is appeared on res.sendRedirect(“Test2”);

    And if we want to do it on jsp, just modify the word res.sendRedirect into response.sendRedirect. Because once again, response variable already set by default on jsp file type, so we don’t have to make a variable for the ServletReponse class. The last but not least, of course, the URL-Mapping for this Test2 have to be declared on web.xml, except the target URL is not on our web-app context.

    Notes : The differences between 2nd tips and this tips from browser side is: the URL address on the 2nd trick didn’t change when the throwing process executed, while in this trick the URL address will change.

  6. Handling Null Value when parse out the parameter on HTTP Method.

  7. On HTTP Post or HTTP Get process, jsp will parse all the parameter that thrown from a form and then the other process will be executed after all the parameters defined. Some times when we parse the parameter on Jsp, we often have Null Value and that can cause the process is unable to continue, because jsp catch NullPointerException. Practically Null Value happens because the parameter that will parse didn’t bring a value form its feeder. So when the parse process executed, NullPointerException Error catch. To prevent this, we can make a default value for a variable that will responsible to carry out the value of parsed parameter.

    Please take a look below codes:

    <%
    String sId = request.getParameter("ID") == null ? "1" : request.getParameter("ID").trim();
    String sName= request.getParameter("Name") == null ? "" : request.getParameter("Name");
    %>
    

    On the above codes, we can see that String sId will be filled up by the value of parsed ID parameter, if the thrown ID parameter have Null value, then by default sId variable will be filled up with value 1. And its also happen with a catching process of Name parameter, but this parameter will fill up with the “” value if the value is not bound in the Name parameter.

And that’s it, few tips and tricks on servlet and jsp which become our discussion this time. I hope this helpful, and please you can use it for your own need.

 

Menteng, 18 Januari 2008

I Hope this will helpfull.

 

Josescalia.