Tag Archives: programming

Ajax + Servlet

Introduction

Found myself with some spare time on my hands and decided to figure out how Ajax works and develop a little example for the blog seeing that I haven’t updated since near infinity in Internet time.

Ajax

Ajax (AJAX) stands for Asynchronous JavaScript and XML. It is a technique using JavaScript and server objects to change webpage content only for a specific piece of the webpage without refreshing the whole page. This is different from normal JavaScript because the change includes an exchange of data with the server. This allows access to services that are found on a server like databases and business logic. Users have an experience that is more interactive. A good example would be a series of pictures being displayed that are only accessible from a database. Each time a picture is clicked it changes to a new picture.

An Ajax request has two major parts, the request and the interactive server portion that hands out the data the request wants. The request creates a XMLHttpRequest and sends the request as a standard html post or get. The server responds in kind with XML. If done right, this draws a hard line between the presentation layer and the business layer. This is not a new idea. JSPs have backing beans. Thick clients have remote objects (RMI anyone?). Ajax in my opinion goes farther by removing the need for a specific type of server side support it needs. It doesn’t care if it is PHP or a Servlet. All it cares for is the contract to be fulfilled. This creates a situation where the implementation of the server objects can change completely and the webpage won’t care. That’s right, one day a bunch of server scripts can be used and then six months later, a set of servlets can be used to replace them. That is an extreme example because of having to stand up a web container in place of the server that supports scripts but a lot of the mapping requests to the server can be done rather painlessly using servlet mapping.

Example

Let’s get to an example of Ajax in action. This example updates three fields with the time from different time zones. The first one is local time, the second is GMT and the last time is for New York. I am using a JavaScript library named jQuery to help write the JavaScript and the Ajax request. For more information on jQuery, go to http://jquery.com/. Since this is a Java blog, the server object is a servlet named TimeServlet.java. All the code can be downloaded from https://github.com/darylmathison/time-ajax-example. The example was created in Eclipse so Eclipse users can import it as a project. The web container I used is a Tomcat 5.5 server.

Webpage

Here is the webpage that makes the requests to the server object. It puts the current time from three different time zones into an html table beneath the label of the time zone it represents. The current time is displayed every time the “Show Times” button is clicked.

<html>

<head>

<meta http-equiv=“Content-Type” content=“text/html; charset=ISO-8859-1”>

<title>AJAX Timetitle>

<script type=“text/javascript” src=“jquery.js”>script>

<script type=“text/javascript”>

$(document).ready(function() {

var timeid = “timeid”;

$(“#timebutton”).click(function() {

$(“#local”).load(‘/TimeAjax/TimeServlet’, {timeid: “local”});

$(“#GMT”).load(“/TimeAjax/TimeServlet”, {timeid: “GMT”});

$(“#newyork”).load(“/TimeAjax/TimeServlet”, {timeid: “newyork”});

});

$(“#errorMsg”).ajaxError(function(event, request, settings, error){

$(this).append(“ajax call failed: “ + settings.url);

alert(settings.url);

});

});

script>

head>

<body>

<table>

<tr>

<td>Local Timetd>

<td>GMT Timetd>

<td>New York Timetd>

tr>

<tr>

<td><span id=“local”> span>td>

<td><span id=“GMT”> span>td>

<td><span id=“newyork”> span>td>

tr>

<tr>

<td colspan=“3”><div id=“errorMsg”>div>td>

tr>

table>

<button id=“timebutton”>Show Timesbutton>

body>

html>

The load function is where the actual request happens.

$(“#local”).load(‘/TimeAjax/TimeServlet’, {timeid: “local”});

$(“#GMT”).load(“/TimeAjax/TimeServlet”, {timeid: “GMT”});

$(“#newyork”).load(“/TimeAjax/TimeServlet”, {timeid: “newyork”});

This is a series of requests for items that have the id of local, GMT and newyork respectively. They all call the servlet with different timeids to tell the servlet what time zone to display back. These requests are sent out when the “Show Times” button is clicked.

<td><span id=“local”> span>td>

<td><span id=“GMT”> span>td>

<td><span id=“newyork”> span>td>

These are the three table cells that are going to be changed when the responses come back.

Servlet

Here is the code for the TimeServlet that services the requests from the webpage. It grabs the timeid from the request and uses java.text.SimpleDateFormat to format the current time into the respective time zone.

public class TimeServlet extends HttpServlet {

private static final long serialVersionUID = 1L;


/**

* Default constructor.

*/

public TimeServlet() {
// TODO Auto-generated constructor stub

}

/**

* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)

*/

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String timeid = request.getParameter(“timeid”);

System.out.println(“timeid is “ + timeid);

if (timeid != null && timeid.length() > 0 ) {

response.setContentType(“text/xml”);

response.setHeader(“Cache-Control”, “no-cache”);

Calendar cal = null;

String dateformat = “HH:mm”;

SimpleDateFormat format = null;


if (“local”.equals(timeid)) {

System.out.println(“in local”);

cal = Calendar.getInstance();

format = new SimpleDateFormat(dateformat);

response.getWriter().write(“” +

format.format(cal.getTime())+ “”);

} else if(“GMT”.equals(timeid)) {

cal = Calendar.getInstance();

format = new SimpleDateFormat(dateformat);

format.setTimeZone(TimeZone.getTimeZone(“GMT”));

response.getWriter().write(“” + format.format(cal.getTime()) + “”);

} else if(“newyork”.equals(timeid)) {

TimeZone tz = TimeZone.getTimeZone(“America/New_York”);

cal = Calendar.getInstance();

format = new SimpleDateFormat(dateformat);

format.setTimeZone(tz);

response.getWriter().write(“” + format.format(cal.getTime())+ “”);

} else {

response.getWriter().write(“cannot find timeid”);

}

} else {

response.getWriter().write(“there is no timeid”);

}

}

/**

* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)

*/

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

doGet(request, response);

}

}

The real work happens in the doGet method.

String timeid = request.getParameter(“timeid”);

Here is where the timeid passed from the Ajax request is pulled from the HttpServletRequest. The passed timeid variable is tested for validity to ward off any NullPointerExceptions.

The below code details what I did to display the time for the local time zone.

if (“local”.equals(timeid)) {

System.out.println(“in local”);

cal = Calendar.getInstance();

format = new SimpleDateFormat(dateformat);

response.getWriter().write(“” + format.format(cal.getTime())+ “”);

}

This is easy because Java defaults to the local locale and time zone. It gets trickier for GMT and the New York time zones but not too much because all that needs to happen is setting the time zone of the formatter.

else if(“GMT”.equals(timeid)) {

cal = Calendar.getInstance();

format = new SimpleDateFormat(dateformat);

format.setTimeZone(TimeZone.getTimeZone(“GMT”));

response.getWriter().write(“” + format.format(cal.getTime()) + “”);

}

This is repeated for the New York time zone using the “America/New_York” time zone.

Last Thoughts

This is another tool in the toolbox for web development. It allows web components to be more interactive enhancing the user experience on your website. It can also be used to further separate presentation and business logic. If you have any comments or questions about this post, please leave them below.

Advertisement

Searching Jars

I have run into the problem where I am looking for the right jar file from a production environment and bring it to a development environment. The problem is that when I get the ClassNotFoundException or the “I can’t find this class” error from the compiler, the right jar file does not come out and say, “Include me in your classpath!” To solve that problem I created an application to do it. It searches recursively through directories and finds all the jar files. Once it finds a jar file, the jar file is opened and a regex search is done to the names to find the missing resource. If the resource is found, the jar file that contains the resource is returned. Otherwise, null is printed on the screen. Below is the class file:

public class JarsSearch {

public static final String FILE_PARAM = “–file”;

public static final String ROOT_PARAM = “–root”;

public static final String HELP_PARAM_PATTERN = “-? | –help”;


public static final String DEFAULT_ROOT = “.”;


private String filename;

private String rootpath = DEFAULT_ROOT;

public JarsSearch() {}


public JarsSearch(String root, String filename) {

setRootpath(root);

setFilename(filename);

}

/**

* @return the filename

*/

public String getFilename() {

return filename;

}

/**

* @param filename the filename to set

*/

public void setFilename(String filename) {

this.filename = filename;

}

/**

* @return the rootpath

*/

public String getRootpath() {

return rootpath;

}

/**

* @param rootpath the rootpath to set

*/

public void setRootpath(String rootpath) {

this.rootpath = rootpath;

}

/**

* looks for the file on any jar under the rootpath

*

* @return String the path of the containing jar file

*/

public String find() {

String jarFilename = null;


try {

File[] jarsNdirs = new File(getRootpath()).listFiles(new JarFileFilter());

Arrays.sort(jarsNdirs, new ListingComparator());

for (File f: jarsNdirs) {

if (f.isDirectory()) {

JarsSearch js = new JarsSearch(f.getCanonicalPath(), getFilename());

jarFilename = js.find();

if (Utils.isStringValid(jarFilename)) {

break;

}

} else { // if not a directory, then a jar file

JarEntry entry;

Pattern p = Pattern.compile(getFilename());

Matcher m = null;


JarFile jarFile = new JarFile(f, false, JarFile.OPEN_READ);

Enumeration e = jarFile.entries();

while (e.hasMoreElements()) {

entry = e.nextElement();

//System.out.println(“printing entry name: ” + entry.getName());

m = p.matcher(entry.getName());

if (m.matches()) {

jarFilename = f.getCanonicalPath();

}

}

jarFile.close();

}

}

} catch (Exception e) {

e.printStackTrace();

}


return jarFilename;

}


public String toString() {

return “JarsSearch[ filename pattern – “ + getFilename() + “, root path – “ + getRootpath() + ” ]”;

}


/**

* @param args

*/

public static void main(String[] args) {

String filepattern = null;

String rootdir = null;


for(int i = 0; i < args.length; i++) {

if (args[i].matches(HELP_PARAM_PATTERN)) {

showArgs();

} else if (args[i].matches(FILE_PARAM)) {

if ((i + 1) < args.length) {

filepattern = args[i + 1];

i++;

continue;

}

} else if (args[i].matches(ROOT_PARAM)) {

if ((i + 1) < args.length) {

rootdir = args[i + 1];

i++;

continue;

}

} else {

showArgs();

}

}


JarsSearch js = new JarsSearch();

if (!Utils.isStringValid(filepattern) || ROOT_PARAM.equals(filepattern)) {

showArgs();

} else {

js.setFilename(filepattern.trim());

}

if (Utils.isStringValid(rootdir) && !FILE_PARAM.equals(rootdir)) {

js.setRootpath(rootdir.trim());

}


System.out.println(js.find());

System.exit(0);

}


protected static void showArgs() {

System.out.println(“–help: this listing”);

System.out.println(“-? : this listing”);

System.out.println(ROOT_PARAM + “: where to start looking from. Default = ‘.'”);

System.out.println(FILE_PARAM + “: regex pattern of a file to look for in a jar file”);

System.exit(0);

}

}

class JarFileFilter implements java.io.FileFilter {

public boolean accept(File arg0) {

String name = arg0.getName();

return ( arg0.canRead() && ( arg0.isDirectory() || name.endsWith(“jar”) ) );

}


}

class ListingComparator implements java.util.Comparator {

public int compare(File arg0, File arg1) {

if (arg0.isDirectory() && !arg1.isDirectory()) {

return -1;

} else if (!arg0.isDirectory() && arg1.isDirectory()) {

return 1;

} else { // ( (arg0.isDirectory() && arg1.isDirectory()) || (arg0.isFile() && arg1.isFile()) )

return arg0.compareTo(arg1);

}

}


}

To get a complete copy of all the source code found on this post, go to https://github.com/darylmathison/jar-search-example.

Tips for the Home Coder

I don’t know about anyone else but I spend a good amount of time coding at home.  It is nice because I get to drink beer and code at the same time.  It is tough to do because I have all my home duties plus getting an hour or two to make something fun or learn somethings.  I started to look at what I do at work to save time since “Time is Money” at work but “Time is Time” at home.  Here is a quick list.

Source Control

It sounds simple enough but I looked over the times where I have blasted my code at home and spent a week restoring while a simple “svn revert” would have done the trick.  For those who are worried about standing up a new server at home, don’t.  There are many sites out there that will host your code for free.  I keep all mine at darylmathisonblog.googlecode.com.  A lot of these sites do this for open source only so if you are making the next best mousetrap, you should take the time and stand one up at your abode.  Now all your changes are in one place that can be easily backed up by someone else or yourself.

Automated Testing

Automated testing is an investment in the future.  In the beginning, it is a real pain to set up, then it becomes awesome time saver. With the click of a button tests that could have taken minutes to finish by hand are done in seconds.  Unit tests can be combined and create test suites, now any change can be tested against the whole system or just that module.  Automated test can run while you make dinner or put the kids to bed.  The other neat thing, if you walk away from a project for a while the tests can give you an idea of how that module is supposed to run so you don’t spend a week of spare time figuring out your own code.  Don’t forget to source control your automated tests too.

Use an IDE

An IDE (Integrated Development Environment) will pay back in the long run.  When I am compiling, the error log created contains links to the offending code.  When I create a new Java class, I use templates to initially set up the class.  When I am starting up a new project, the IDE organizes it to make it easy to deploy.  Good ones are expandable so I can create a tool to help me create a solution if one hasn’t been created already.  I have been using Eclipse lately and the amount of add-ons it has blows me away.  I can install servers on my computer and Eclipse will start up and shutdown the server as needed.  It automatically builds source code so I know exactly where the code doesn’t compile before I do a test.

Well, there is my quick list.  If you can think of anything else, post a comment.

Links

www.eclipse.org

www.googlecode.com