Implementing URL Shortener with Servlet
I bet that most of you already tried Url Shortener Service to make your long link shorter and easier to write and remember. And perhaps you use more than one service, you name it ow.ly, goo.gl, bit.ly and still tons of services like that available freely on the cloud. But, how it works? here i will share its implementation with Servlet. It’s easy to implement, believe me.
First of all, prepare several tools below:
-
MySql Database Server. I use version 5.1.49 Community Edition, you can download newest MySql from http://www.mysql.com/downloads/mysql/. Or you can choose another DBMS implementation, like Oracle, Sql Server, etc.
-
MySql Connector/J, as our JDBC driver for MySql. You can download it from http://www.mysql.com/downloads/connector/j/. Please use suitable JDBC Driver if you choose another DBMS.
-
Servlet Container, here i use Apache Tomcat 6.0.32, you can download ithttp://tomcat.apache.org/. Of course, you can replace it with your own most favourite Web Server; Jetty, Glassfish, JBoss, etc.
-
servlet-api.jar, this is jar of Servlet API. You will need it to create a simple Http Servlet. You can download it from http://www.java2s.com/Code/Jar/STUVWXYZ/Downloadservletapijar.htm just in case you dont have it.
-
Your favourite Java IDE. In this tutorial I’m using Eclipse Helios 3.6, feel free to use similar IDE.
After you have all of these things above, we can start it. In order to make this post shorter, i assume that you have experience in creating new Web Project and adding required jars (servlet-api.jar and Mysql Connector/J ) to the classpath.
Scenario .
Before we started to the code, maybe i have to describe the business scenario first. My scenario is i want to make a simple program that take input of my long url and return a shorter link that formed like http://myserver/{id} , where {id} is my identifier to find the original url and turn my browser to open it.
Create Database
Run this Sql Script on your DBMS engine to create a table that stores our data. Dont forget, the id column has to be auto-increment. This is our primary key and we need it as a short url. You need to modify the Sql if you use other DBMS.
CREATE DATABASE /*!32312 IF NOT EXISTS*/`url_shortener` /*!40100 DEFAULT CHARACTER SET latin1 */; CREATE TABLE `url_data` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `long_url` text NOT NULL, PRIMARY KEY (`id`) );
Creating Servlet to Insert Long Url.
Now, create a new Java Class that extends javax.servlet.http.HttpServlet object and type below code.
package com.namex.shortener;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Insert extends HttpServlet {
/**
* Both POST and GET method are allowed to insert new record
*
*/
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String longUrl = request.getParameter("longUrl");
request.getSession().setAttribute("a", "a");
String a = response.encodeURL(request.getRequestURI());
request.getSession().setAttribute("a", "a");
System.out.println("->"+request.getRequestURI());
System.out.println(a);
System.out.println("shortening " + longUrl);
String serverName = request.getServerName();
int port = request.getServerPort();
String contextPath = request.getContextPath();
String shortUrl = null;
try {
shortUrl = new Logic().getShort(serverName, port, contextPath,
longUrl);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("short url: " + shortUrl);
request.getSession().setAttribute("shortUrl", shortUrl);
response.sendRedirect("index.jsp");
}
}
In my case, i want my program to handle both of POST and GET method, so i need to implement both of doGet and doPost method. Just in case you only want to handle GET method and not the POST, so you only need to override the doGet method.
See the new Logic().getShort(serverName, port, contextPath, longUrl); line. That is our Logic class that handle the whole business-logic problem. So we can see our servlet neater. Below is complete Logic source code, just type the whole thing, including not used yet function. And dont forget to adjust the getConnection according to your DBMS IP Address and credential.
package com.namex.shortener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Logic {
public Connection getConnection() throws IllegalAccessException,
ClassNotFoundException, SQLException {
//adjust it
String url = "jdbc:mysql://localhost/url_shortener";
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url, "root", "root");
return conn;
}
public String getId(String longUrl) throws Exception {
Connection conn = null;
ResultSet rs = null;
Statement st = null;
String query = "SELECT id FROM url_data WHERE long_url='"
+ longUrl.trim() + "'";
String id = null;
try {
try {
conn = getConnection();
st = conn.createStatement();
rs = st.executeQuery(query);
if (rs.next()) {
id = rs.getString("id");
}
} finally {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (conn != null) {
conn.close();
}
}
} catch (Exception e) {
throw e;
}
return id;
}
public String getShort(String serverName, int port, String contextPath,
String longUrl) throws Exception {
Connection conn = null;
Statement st = null;
String id = getId(longUrl);// check if URL has been shorten already
if (id != null) {
// if id is not null, this link has been shorten already.
// nothing to do
} else {
// at this point id is null, make it shorter
String sqlInsert = "INSERT INTO url_data(long_url) VALUES('"
+ longUrl.trim() + "')";
try {
conn = getConnection();
st = conn.createStatement();
st.execute(sqlInsert);
} finally {
if (st != null) {
st.close();
}
if (conn != null) {
conn.close();
}
}
// after we insert the record, we obtain the ID as identifier of our
// new short link
id = getId(longUrl);
}
return "http://" + serverName + ":" + port + contextPath + "/" + id;
}
public String getLongUrl(String urlId) throws Exception {
if (urlId.startsWith("/")) {
urlId = urlId.replace("/", "");
}
String query = "SELECT long_url FROM url_data where id=" + urlId;
String longUrl = null;
Connection conn = null;
ResultSet rs = null;
Statement st = null;
try {
conn = getConnection();
st = conn.createStatement();
rs = st.executeQuery(query);
if (rs.next()) {
longUrl = rs.getString("long_url");
}
} finally {
if (rs != null) {
rs.close();
}
if (st != null) {
st.close();
}
if (conn != null) {
conn.close();
}
}
return longUrl;
}
}
Adjusting web.xml for Insert Servlet.
To let the Server identify your new created servlet, adjust your web.xml like this.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>URLShortener</display-name> <servlet> <servlet-name>Insert</servlet-name> <servlet-class>com.namex.shortener.Insert</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Insert</servlet-name> <url-pattern>/insert</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
You see the <servlet></servlet> tag, between that tag is our servlet class and we give it a name Insert. So whenever we need to do configuration to this servlet, we use the name Insert. Dont forget to give negative integer to <load-on-startup></load-on-startup> because we wont need it to be loaded when the server is up. We only need the servlet loaded when it called explicitly from our program. You can see more detail about <servlet></servlet> tag here http://download.oracle.com/docs/cd/E13222_01/wls/docs81/webapp/web_xml.html#1039287
The <servlet-mapping></servlet-mapping> identify when the servlet is called by the program. In our case, the Insert servlet will be called when someone make request to /{context-path}/Insert.
Create User Interface.
Now it’s time to provide some user interface, i make a simple one with only 1 text-field and a simple scriptlet to view our recently shorted link. You can beautify it if you want. Put it on top of WEB-INF folder as index.jsp, because we want it to be the first page of our program.
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<!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=ISO-8859-1">
<title></title>
</head>
<body>
<form action="/url/insert" method="GET">
Long URL: <input type="text" name="longUrl" size="100" /> <input
type="submit" value="Get Short !" />
</form>
</p>
<%
if (session.getAttribute("shortUrl") != null) {
%>
Hi, your short url is:
<br />
<br />
<%=session.getAttribute("shortUrl")%>
<%
}
%>
</body>
</html>

Testing Shortening
After we did all the steps above, now we can try it in action. Compile and make a WAR of your recently create application and deploy it on Tomcat. And open the program using your browser. Input the long URL, press the button and you can see the short URL generated below.

the result would be

IF, remember the BIG IF everything runs perfectly, our task isnt done yet. We still have to make a redirector that transforming the short url to the original url.
Creating Servlet to Transform Short Url.
Similar proses like here. Just type the Retrieve servlet, and be aware of line new Logic().getLongUrl(urlId);. We have had created this before and if you did what i told you before to code the Logic class completely, with all of its functions, the Retrieve servlet code should be perfect.
package com.namex.shortener;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Retrieve extends HttpServlet {
private static final long serialVersionUID = 1293961717469276130L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String urlId = request.getServletPath();
String longUrl = null;
if (urlId != null && !"".equals(urlId)) {
try {
longUrl = new Logic().getLongUrl(urlId);
} catch (Exception e) {
// handling exception here
e.printStackTrace();
}
}
if (longUrl == null) {
// if long url not found, send to index.jsp
System.out.println("long url not found, back to index.jsp");
response.sendRedirect("index.jsp");
} else {
//if long url found, so redirect the browser
System.out.println("redirecting to "+longUrl );
response.sendRedirect(longUrl);
}
}
}
Adjusting web.xml for Retrieve Servlet.
Dont forget we have to adjust the web.xml setting to let the Tomcat identify our servlet. The whole web.xml would be like this.
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>URLShortener</display-name> <servlet> <servlet-name>Insert</servlet-name> <servlet-class>com.namex.shortener.Insert</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Insert</servlet-name> <url-pattern>/insert</url-pattern> </servlet-mapping> <servlet> <servlet-name>Retrieve</servlet-name> <servlet-class>com.namex.shortener.Retrieve</servlet-class> <load-on-startup>-1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Retrieve</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
Test the Whole Shortener.
This is our last part, now you can test the program completely. Run your Tomcat and open our program. Insert the long url and open the short url in your browser, see if it return your page or not.
Now, our Url Shortening service has been created. There are still many ways to implement it using various techniques, we can use SOAP, REST or even EJB to handle the shortening and retrieving url. Now it’s your turn to improve it and implement it for your own need.
How Easy to Make Your Own Twitter Client Using Java
Got inspired by my friend, whom built his own Twitter client for his company’s client. So, i tried to build one using Java. And im surprised that how easy to make Twitter client, of course i still use third-party API to make my job easier.
This simple client will only have 2 purposes: reading timeline and post status. Dont worry, you can expand this application later, it’s simple and easy once you have your app got authorized by Twitter.
First of all, you have to go to official Twitter Developer Registration at https://dev.twitter.com/apps/new , and register your application detail there. For this blog purpose, i will create a new application that called “Namex Tweet for Demo“. It’s simple, just fill in some required data and voila it’s done in seconds.
After you passed this registration step, dont forget the most important things in here are these Consumer and Consumer Secret key. Just say, it’s a signature to let Twitter knows your application. These things will be hardcoded at your application. In here, my Consumer key is DXjHgk9BHPmekJ2r7OnDg and my Consumer Secret key is u36Xuak99M9tf9Jfms8syFjf1k2LLH9XKJTrAbftE0 . Dont use these keys in your application, it’s useless because i will turn off the application as short as this blogging purpose done.

And after registration step dont forget to visit Setting page and adjust setting for your application access.


Choose Read, Write and Access direct messages to get your application at full functional. you now can download additional java API for twitter, im using Twitter4J . Here, you have to download several jars,
- twitter4j-async-<a.b.c>
- twitter4j-core-<a.b.c>
- twitter4j-media-support-<a.b.c>
- twitter4j-stream-<a.b.c>
Notes: Dont use twitter4j-appengine.jar, it will cause your application thrown to exception on authorizing process.
In my version a is 2, b is 2 and c is 4. So it would look like twitter4j-async-2.2.4 etc. After these jars being downloaded at your machine, our downloading job has not done yet. We still have to download Apache Commons Codec as Twitter4J dependencies. After all of the jars downloaded, now we can start to code. Open your fave IDE and start it with me.
package com.namex.tweet;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
public class NamexTweet {
private final static String CONSUMER_KEY = "DXjHgk9BHPmekJ2r7OnDg";
private final static String CONSUMER_KEY_SECRET = "u36Xuak99M9tf9Jfms8syFjf1k2LLH9XKJTrAbftE0";
public void start() throws TwitterException, IOException {
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_KEY_SECRET);
RequestToken requestToken = twitter.getOAuthRequestToken();
System.out.println("Authorization URL: \n"
+ requestToken.getAuthorizationURL());
AccessToken accessToken = null;
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
while (null == accessToken) {
try {
System.out.print("Input PIN here: ");
String pin = br.readLine();
accessToken = twitter.getOAuthAccessToken(requestToken, pin);
} catch (TwitterException te) {
System.out.println("Failed to get access token, caused by: "
+ te.getMessage());
System.out.println("Retry input PIN");
}
}
System.out.println("Access Token: " + accessToken.getToken());
System.out.println("Access Token Secret: "
+ accessToken.getTokenSecret());
twitter.updateStatus("hi.. im updating this using Namex Tweet for Demo");
}
public static void main(String[] args) throws Exception {
new NamexTweet().start();// run the Twitter client
}
}
Compile and run the code, it will create permission for “Namex Tweet for Demo” to be linked with your Twitter account. Just open the “Authorization URL” shown at the screen and input the PIN shown by the website. Your application will send back the pin to Twitter, if it’s match your account will be linked with this new application and you can see you just posted a new status using “Namex Tweet for Demo “. Congratulation!
Notes: Authorization URL and PIN will generated differently each time it’s run.
![]()


In here you can see, we input no username and password of Twitter account but we can use our account within application. Yeah it’s possible because of OAuth . It “transformed” password-input-process to sending-receive-token. So dont worry, Third-party Twitter client application cant read and store no password of your Twitter account. In simple, it’s safer and prevent password thieving.
Now we still have a tiny problem, at this point, your program still need to open Twitter’s website and input pin back to the application. So, maybe you are asking on the cloud, do i need this annoying authorization on the future ? well, gladly the answer is NO. At the time your app being authorized by Twitter, you have no use to re-authorize it again — with a simple note you have to save the Access Token and Secret Access Token . What the hell is that, how could i get that. Well, you have it already, see the image below, i put it in a big red rectangle so it will be more eye-catchy. In here, our token is and our secret token is. These 2 tokens have to be saved somewhere, you can choose your own method to save it: Persistence, CSV, DBMS, etc. It’s all up to you.

So, i saved the tokens! How do i reuse it? It’s simple, see below code. It’s how to use your tokens, so you wont have the re-authorization process again. Try to post and read your timeline now.
package com.namex.tweet;
import java.io.IOException;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.AccessToken;
public class NamexTweet {
private final static String CONSUMER_KEY = "DXjHgk9BHPmekJ2r7OnDg";
private final static String CONSUMER_KEY_SECRET = "u36Xuak99M9tf9Jfms8syFjf1k2LLH9XKJTrAbftE0";
public void start() throws TwitterException, IOException {
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_KEY_SECRET);
// here's the difference
String accessToken = getSavedAccessToken();
String accessTokenSecret = getSavedAccessTokenSecret();
AccessToken oathAccessToken = new AccessToken(accessToken,
accessTokenSecret);
twitter.setOAuthAccessToken(oathAccessToken);
// end of difference
twitter.updateStatus("Hi, im updating status again from Namex Tweet for Demo");
System.out.println("\nMy Timeline:");
// I'm reading your timeline
ResponseList list = twitter.getHomeTimeline();
for (Status each : list) {
System.out.println("Sent by: @" + each.getUser().getScreenName()
+ " - " + each.getUser().getName() + "\n" + each.getText()
+ "\n");
}
}
private String getSavedAccessTokenSecret() {
// consider this is method to get your previously saved Access Token
// Secret
return "oC8tImRFL6i8TuRkTEaIcWsF8oY4SL5iTGNkG9O0Q";
}
private String getSavedAccessToken() {
// consider this is method to get your previously saved Access Token
return "102333999-M4W1Jtp8y8QY8RH7OxGWbM5Len5xOeeTUuG7QfcY";
}
public static void main(String[] args) throws Exception {
new NamexTweet().start();
}
}


Now our simple Twitter application has been -could be- done, we can read and post to Twitter. Of course, many things still on the task list if you want to make it professionally and -perhaps- sell it. A nice UI, reading and sending Direct Message, Searching Users, Follow and Unfollow. I put these jobs on your shoulder, cause i just want to share it’s easy to make a Twitter client and i hope this short tutorial can help you in developing Twitter client using Java.
Happy Code All !
Learn fundamental of Java ? Use ancient JDK
Many Java developers are categorized as a good one in developing program using Java. But, i met so many of them are weak and less in java fundamentals itself. They can develop new program easily. But when i asked, what happening in background of java itself. Only few of them can explain it goodly and in appropriate way. Start to investigate what happening with them, reflecting they are not a newbie as Java Developer, 2 or 3 years in field experience.
After some research about situation and background of few developers. I can pull out my own conclusion, they are facing some fundamental problems because they are started to code using JDK 1.5, i classified this version as modern JDK. In 1.5 and later there are boxing-unboxing feature to make easier relationship between primitive and its wrapper, foreach loop statement to make looping process simpler. We wouldn’t see those things in 1.4. In 1.4 we have to use primitive data types and the wrapper explicitly and we still have to do explicit type-casting instead of using foreach. In my simple words: “Almost everything run by write it!”.
I’m not saying here that manual is the best way to do everything, but i found many cases during my professional experience, that with manual ways, we can learn how one process in a code could be done and doing analytic about whats happening with the code.
For the simplest example, look at between 2 pieces of code.
- int myNumber = new Integer(10);
- int mySecondNumber = 10;
On JDK 1,5 those codes will produce exact results. Nothing error and nothing produce runtime exception. I give simple question to some people that declared as Java Developer. Only few of them can give me satisfaction answer.
Now with JDK 1.4 one of those 2 codes will produce error. The first one will produce compilation error. Meanwhile with 1.5, the first one will run perfectly but the code will take some unnecessary processes, means the code will use some space of memory for useless thing.
And yet another example,
- List<SomeClass> myList= new ArrayList<SomeClass>();
- List mySecondList= new ArrayList();
Whats the difference between both lists? well the most common answer i got only, “You can use foreach for myList but not to mySecondList”, well the answer is right, i wont hesitate about that. But still, the answer i got wasn’t the answer that i looking for. I’m looking for deeper answer, fundamentally.
For the ancient one, i still give 1.4 my humble recommendation. Maybe it’s a little bias because i started my java code using 1.4, forgive me for this. And please dont take me wrong, i’m not saying that the latest JDK is bad or automatic process is bad. I believe in thought that Java Architects have done very good job by providing simplicity and easiness in use of Java. But still, responsibility to know Java in fundamental way itself still be ours.
So, if you want to know better about Java Fundamental, maybe you should try ancient JDK. Watch and learn the process. And spread your own knowledge.
Well, i wouldn’t give you the answer for the differences of my codes above. Let it be your tasks, considered this is your homework
And for the last, this article based on my truly experience so maybe the content wont fit you at all. Please share your own or give me correction if you are thinking my article is too cheesy, old-style or maybe too idealist. Im glad to read from you soon
Making MyBatis more reuseable
I’ve been using MyBatis (formerly iBatis) since 2 or 3 years ago, and ive no doubt about this framework’s capability in handling my needs to do many database operations.
But, bad practice in using this can make your code ends painfully, especially when you have to do some code refactoring on it. I just want to share several tips and tricks to make your MyBatis application easier to refactor, more reuseable and less dependency.
- Do the IF in Java level: as a Programmer, you will and always experiencing many cases of IFs statement, for the simplest, when you want to change the output of null value from database to another value, you can do this query on mysql:
SELECT IFNULL(a_column,'null replacement value') FROM a_table
AVOID that, that way will make your program has heavy dependency on mysql, because IFNULL is mysql native function, you’ll experiencing problem if you have to change database platform eg: Sql Server or Oracle. It will be better to let Java handle this for you, like this:
if(aColumn==null){
aColumn="null replacement"; }
- Avoid data formatting in MyBatis: We often change the format of the database output, example: Datetime is the most common datatype that need to be formatted before it being an output, we can do the formatting with something like this,
SELECT DATE_FORMAT(date_column,'%d-%m-%Y') FROM a_table
Avoid that, same as before, that code practice will has heavy dependency. Just use simple ANSI query
SELECT date_column as dateColumn FROM a_table.
And let Java takes the formatting job with its available classes, SimpleDateFormat to do datetime formatting, NumberFormat for number formatting, and so on. And as an added value you can put the format-pattern in constants or properties so it will be easier if you want to change the pattern.
- Pass value as parameter: For the example, In mysql you can retrieve current datetime information with now() function, and in case you want to put current date-time in table, you can write sql command like this:
INSERT INTO a_table(column1, time_stamp) VALUES( #{paramValue},now())
Well, stop doing this thing, a better solution, you can write more reuseable query by putting timestamp into parameter and pass it, just like this
INSERT INTO a_table(column1, time_stamp) VALUES( #{paramValue},#{currentTimestamp})) -
Group often used query with <sql> </sql>: In one MyBatis XML, we often facing several same part-of-queries and MyBatis is smart to add <sql> as a feature and make it capable to grouping the query, so we can use and reuse it. By using this feature, you can make your query more feasible and easier to refactor.
For example: i used to do data pagination, and i can write the worse solution just like this.
<!-- Not Recommended, AVOID -->
<select id="select" resultType="my.resultBean" parameterType="my.paramBean">
SELECT column1, column2 FROM my_table
LIMIT #{startData}, #{dataPerPage}
</select>
but, with sql grouping feature, now i can write more elegant query just like this,
<sql id="pagingSql">
LIMIT #{startData}, #{dataPerPage}
</sql>
<select id="select" resultType="my.resultBean" parameterType="my.paramBean">
SELECT column1, column2 FROM my_table
<include refid="pagingSql" />
</select>
So with this, now my pagingSql can be used by another query by using <include>
Now, i’m finish and hoping this short article can help you to write more elegant program using Java and MyBatis.
Dont be a Programmer, be a Consultant
So, what is the difference between them? well imagine the situation i had before. My boss told me to develop a system to retrieve CSV(Comma Separated Value) file that sent by another company. As a programmer, it’s nice and easy to do, the things i have to do are:
-
Listening to the certain connection.
-
Accept the file.
-
Save the file.
-
And done.
Easy and easy, right? but… as a consultant, i have to think more than those 4 steps. At least i still have many pre and postconditions, such as:
-
What if the connection isn’t established well?
-
What if the client is sending the wrong file?
-
What if the connection down meanwhile process is still on progress?
- What if the client is sending the file twice?
What if, what if and what if. They are still many of Ifs available. Of course we cant handle all of the IF situations, but at least we prepared for common and certain problems already. We cant anticipated all of them, but we try to reduce the possibilities.
So, from my point of view, the huge and main differences between Programmer and Consultant are:
- Programmer does ONLY the code, meanwhile Consultant has to be a solution maker.
- Programmer is preparing for now situation, meanwhile, Consultant is preparing the ‘future’ condition and try anticipating a new born problem.
- Programmer does the job with their technical skill, meanwhile, Consultant does it with combination of Technical Skill and Experience.
- Programmer solve the task, meanwhile, Consultant solve the problem.
Easy to be a Programmer, you can learn it if you have a passion, patience, and practicing the programming language, but not all of us can be a good consultant, it need time and experience, sometimes the problem cant be solve with common and text-book based solution, sometimes we have to solve it (or patch it) with a tricky solution.
So, from now on, prepare and learn to be a Consultant, not only do the code but try to learn the problem with sense, feel, analyze and give solution for it.
Install mySQL on CentOS Linux
Installing mysql on CentOS, is easy, as 1,2,3. Though i wouldnt say this will be as easy as windows’s installation.
In this short tutorial i will explain how to do it, via console, as most servers dont have GUI installed. And preassumeably, you are login as root and have active internet connection.
- Get installation package: to get mysql installation package easy (CentOS has yum repository manager). Just type yum install mysql-server on your CentOS’s console.
![]()
Type y, and let Yum do its job, until below screen appear.
-
Make sure mysql is started by typing /etc/init.d/mysql start
-
run mysql_secure_installation to set credential and security for your mysql, and enter your current root password, you can leave it blank because we havent set it up yet. And follow instructions on the screen.
- Set root password? [Y/n]: fill with Y if you want to set root password for your mysql. Root password is the top level access for your mysql, so be wise in use it. And dont forget the password.
- Remove anonymous users? [Y/n]: By default, mysql has anonymous user account that can be used by anyone to log into mysql without having user account. Remove anonymous user in production, meanwhile in development is up to you.
- Disallow root login remotely? [Y/n]: If you want root can be accessed from remote computer, you have to set it with n. By allowing root login remotely, your root account can be accessed from any computer that connected with your mysql machine.
- Remove test database and access to it [Y/n]: By default, mysql has database named ‘test’ that used only for testing purpose. You can remove it safely because it has no effect to your mysql system.
- Reload privilege tables now? [Y/n]: Fill with Y if you want to reload your privilege that had been set up immediately.
-
run mysql_install_db to adjust your mysql system tables.
-
Setting CentOS firewall. After your mysql has been installed on your machine, now the last step you have to do is giving firewall privilege to your mysql port, so it can be accessed from remote machine. Of course you have to do it, because in many cases i believe you wont access your mysql directly from your machine. To do this, on your CentOS Console, type setup and you will have below screen.
![]()
Choose Firewall configuration and Run Tool to get into Firewall configuration window.
Choose Customize, and fill Other ports with 3306 (default mysql port). And press OK.
Voila, your mysql has been set up, and please let me know if you have any problem installing it.
Development Tools I Can’t Live Without
There are so many Software Development Tools that spread widely on the cloud, and these are my favourites. Im not mentioning they are the best, but they are fit me and i’m happy to use them in my daily professional life. If you have different opinion, so be my guess.
Integrated Development Enviroment (IDE).
Candidates: Eclipse, Netbeans and JBuilder.
Winner: Eclipse, eclipse is available freely on the cloud. It has so many plugins, start from various servers plugins, subversion integration, Reporting tools integration and still many more. And now it supports other languages too, such as PHP. Well frankly, i’m start my career with JBuilder as my escoter through the Java code while im a trainee, but lately i found the eclipse is the better solution compared to JBuilder. I use Netbeans several times found it good, but still eclipse is the most suitable for me, the UI, fonts, shortcut and plugins are so into my style.
Versioning Tool
Candidates: Microsoft Visual Source Safe (VSS) and Subversion (SVN).
Winner: SVN. Compared to VSS, SVN is free and open source, thats one point. The second point is, SVN can be installed on cross platforms, server on Linux and Client uses Windows, they are not a problem at all. If you asked me, i have no trust on Windows to handle my entire source codes, since it has so many vulnerabilities on security issues, such as: virus attack. Can you imagine, the whole project’s source code is vanished by a virus ? just in a second, your job will be gone by (almost) forever. The third point is, SVN can be accessed from many varians of clients, RapidSVN, TortoiuseSVN, can be integrated with Eclipse through plugin feature, and it can be accessed with Command Line Interface too, just in case you have no UI Manager installed.
Application Server
Candidates: Weblogic, Tomcat, Glassfish
Winner : Glassfish and Tomcat. On this category, i have double winners. Tomcat win because of the simplicity, it’s so easy to install and using it, even if you are still a green developer. If you just (keep in mind: JUST) looking for an application container server and you arent using many J2EE features, such as: JMS, Connection Pooling,etc. i would love to give Tomcat two thumbs up. BUT, if you are looking for a container server and have a need in using many J2EE Enterprise Server Features, use Glassfish, it’s free, open source, has so many users, easy to use, set up and to manage. Weblogic is a good (if not the best) application server that i had used before, but sometimes, i found it hard to use and expensive too to be use as production server, Weblogic trial version is free but only allow 5 concurrent users.
Database Engine
Candidates: Oracle, mySQL, Sql Server.
Winner: Nobody, each server has their own usage domain. Examples: If you looking for a free, cross-platform,easiness and liteness, use mySQL. If you are a Sql Server Expert and have support license of Sql Server and only use Windows OS, use Sql Server. If you looking for a huge features of DBMS Engines and when money isnt big problem for you use Oracle. So, i cant decided which one is the best, i use them all and found they have their own unique features depend on the case.
Plain Text Editor
Candidates: Notepad++, PSPad
Winner: Notepad++. Both are free, support plugins, and support programming language style highlighter. But i found PSPad works slowly when experiencing with huge size of text files, Log files for the example. Meanwhile, Notepad++ can open it faster (though not fast or fastest).
Database Designer
Candidates: Mysql Workbench, Software Ideas Modeler, Power Architect, Microsoft Visio.
Winner : Power Architect. It’s free, easy to use and cross platforms. Frankly, Workbench works greatly, but i found so many bugs on it and it only supports for the mySQL DBMS. So when i have to handling other DBMSs, it won’t work, for example:I can’t design table that handling Oracle’s Varchar2. So, i choose Architect as a winner. Software Ideas is great too, but i prefer Power Architect because of the taste of UI Flavour. And Visio, though many developers like it, i’m not a big fan of it.
PDF Creator
Candidates: Cute PDF Writer, Primo PDF
Winner: Cute PDF Writer. Though my main job is Software Developer, sometimes, i have to handling with documentation problem. Such as: Database Design, Source code documentation, and Coding Guideline. I think it would be nice and neat to give the document on PDF format, it can be opened cross platforms, from browsers and even from mobile devices. So I need the PDF Creator to give me a hand to create PDF documentation. I found Cute PDF is faster and more bug free rather than Primo PDF. I use Primo for the first time and got good impression on it, until my OS got crashed and became nag screen every time i tried to create a PDF, meanwhile with Cute PDF, i can create PDF smoothly.
File Merge and Compare
Candidates: Beyond Compare, WinMerge
Winner: WinMerge. Why WinMerge is my winner, it can be integrated into Subversion, so i can easily use WinMerge from inside the Subversion to determine the difference and do the merge between two files.
SSH Client
Candidates: Putty, WinSCP
Winner: WinSCP. Absolutely WinSCP is a winner. Nice GUI, easy to use, and can ‘translate’ the console view into nice UI experience. Though, i’m still looking for a better SSH Client, still i couldn’t found anything better.
Well, i think those are all. Based from my personal taste, those are the best and the most suitable for me. Please let me know if you have anything better or any disagreement.
Singleton vs Prototype Spring injection
For a newbie developer that just started their journey in the Spring auto injection world. I will explain about the differences Singleton and Protoype Spring Injection.
To make it easier i will create a simple POJO Java Class that only contain one property and its setter getter.
package com.namex.spring;
public class NamexBean {
private String myMessage;
public String getMyMessage() {
return myMessage;
}
public void setMyMessage(String myMessage) {
this.myMessage = myMessage;
}
}
SINGLETON
And for the first, we will advancing the singleton scope.
<beans xmlns="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xsi:schemaLocation="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a> <a href="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</a>"> <bean id="namexBean" class="com.namex.spring.NamexBean" scope="singleton" /> </beans>
By default, spring has its scope as a “singleton”, so you if you not specifiying the scope attribute, it will be the “singleton”.
Now, i will create my java tester class, to start to test the effect of the singleton scope.
package com.namex.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Tester {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring-Context.xml" });
NamexBean firstBean = (NamexBean) context.getBean("namexBean");
firstBean.setMyMessage("This is the first bean's message");
System.out.println("firstBean: " + firstBean.getMyMessage());
NamexBean secondBean = (NamexBean) context.getBean("namexBean");
System.out.println("secondBean: " +secondBean.getMyMessage());
}
}
the output would be:
firstBean: This is the first bean's message secondBean: This is the first bean's message
Now, it’s clear, with the singleton scope, spring will create one instance that will be shared across among others. So they will be have the same memory reference.
PROTOTYPE
Now how about with the Prototype?
<beans xmlns="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>" xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xsi:schemaLocation="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a> <a href="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</a>"> <bean id="namexBean" class="com.namex.spring.NamexBean" scope="prototype" /> </beans>
package com.namex.spring;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Tester {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { "Spring-Context.xml" });
NamexBean firstBean = (NamexBean) context.getBean("namexBean");
firstBean.setMyMessage("This is the first bean's message");
System.out.println("firstBean: " + firstBean.getMyMessage());
NamexBean secondBean = (NamexBean) context.getBean("namexBean");
System.out.println("secondBean: " +secondBean.getMyMessage());
}
}
the output would be:
firstBean: This is the first bean's message secondBean: null
It’s obvious that the Prototype scope create a new instance and not shared the instance among.
WHICH ONE IS BETTER ?
The answer is really simple: it’s depend. Depend in which way you need the code to do and how you code it.
How to run iBatis using Namespace
Have you ever run the query i the iBatis Sqlmap and got the erroneous lines of code when you use the namespace into it?
com.ibatis.sqlmap.client.SqlMapException: There is no statement named Salesman.insert in this SqlMap.
It easy enough to solve the problem, just add the line below in your iBatis Configuration and make sure you now use the namespace when calling it.
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE sqlMapConfigPUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN""http://www.ibatis.com/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <settings useStatementNamespaces="true" /> <!-- add this line --> <sqlMap resource="ibatis/Web-Registration-Report.xml" /> </sqlMapConfig>
Be aware. Since now, your code will produce error if you not using the namespace. So it will be wiser to make a final decision whether to use the namespace or not.
Working with DTD in Eclipse
DTD, Document Type Definition, can help you when you are writing XML file. DTD can force XML rule integrity, so you won’t write wrong XML Scheme.
In eclipse, DTD can help you in writing XML with its intellisense feature, just like you do the Java. Just type any word and help will came after you.
To insert DTD file in eclipse is such an easy problem, just run your eclipse and point your mouse at Window -> Preferences -> Web and XML -> XML Catalog, if you point it correctly you will see this screen.

Click Add… Button and fill Information about your DTD, i will explain how to determine Key and Web Address informations from the XML file, later.

Now OK, and create your XML file, just like below and press CTRL+SPACE to ensure you have inserted the DTD correctly. If the intellisense came out perfectly, we can assume that Eclipse can handle your DTD perfectly now.

As i promised, now i will explain about relating XML to its DTD. See the picture below and i thought now you can determine it by yourself.

Pretty simple huh. Well, hope this short tutorial would be useful for you.




