Using Spring’s StoredProcedure and RowMapper mechanisms

No Gravatar

One very useful portion of the Spring Framework is the StoredProcedure wrapper’s and the RowMapper objects. Together these allow you to call a stored procedure and then parse the result set back into a collection of objects with very little pain. Below is an example of how to do just this for a simple query like a user query.

First, we have the StoredProcedure class:


public class MyStoredProcedure extends StoredProcedure {

	public MyStoredProcedure (DataSource ds, String spname,
            Map map, String sqlOutKey, Integer returnType,
            RowMapper rowmapper) {
        super();
        setDataSource(ds);

        /* resultset has to be declared first over other declare parameters */
        if (rowmapper != null) {
            declareParameter(new SqlReturnResultSet(sqlOutKey, rowmapper));
        }

        if (map != null) {
            Iterator itr = map.keySet().iterator();
            while (itr.hasNext()) {
                String key = (String) itr.next();
                Integer value = (Integer) map.get(key);
                declareParameter(new SqlParameter(key, value.intValue()));
            }
        }

        /*
         * sql out paramter has to be declared based on the order in stored
         * procedures, In all our stored procedures we have it after input
         * parameters
         */
        if (returnType != null) {
            declareParameter(new SqlOutParameter(sqlOutKey, returnType
                    .intValue()));
        }

        setSql(spname);
        compile();
    }
}

Next, we have the Mapper class:



public class UserMapper implements RowMapper {
    public Object mapRow(ResultSet rs, int rowNum) throws SQLException {
        User user = new User();
        user.setUserId(rs.getString(Constants.USER_ID));
        user.setFirstName(rs.getString(Constants.FIRST_NAME));
        user.setLastName(rs.getString(Constants.LAST_NAME));
        user.setOrganizationName(rs.getString(Constants.ORGANIZATION_NAME));
        return user;
    }
}

Next, we have to query the actual stored procedure from a DAO. Here’s a sample method that would do just such a thing:


	public Collection searchUsers(User user) throws Exception {

		Map lhm = new LinkedHashMap(4);
		lhm.put(Constants.USER_ID, new Integer(Types.VARCHAR));
		lhm.put(Constants.FIRST_NAME,new Integer(Types.VARCHAR));
                lhm.put(Constants.LAST_NAME,new Integer(Types.VARCHAR));
                lhm.put(Constants.ORGANIZATION_NAME,new Integer(Types.VARCHAR));

		UserMapper mapper = new UserMapper();

		// Call Stored Procedure
		EntitlementsStoredProcedure proc = new EntitlementsStoredProcedure(
			ds, StoredProcedureConstants.USER_SEL, lhm,
			Constants.RESULTSET, null, mapper);

		// Collect the criteria for the search
		Map map = new LinkedHashMap(4);
		map.put(Constants.USER_ID, user.getUserId());
		map.put(Constants.FIRST_NAME, user.getFirstName());
		map.put(Constants.LAST_NAME, user.getLastName());
		map.put(Constants.ORGANIZATION_NAME, user.getOrganizationName());

		Map results =  proc.execute(map);
		List resultList = (LinkedList)results.get(Constants.RESULTSET);

		//iterate of results list and print
		for (Iterator it=resultList.iterator(); it.hasNext(); ) {
			User user1 = (User)it.next();
			System.out.println(user1);
		}

		return resultList;
	}

That’s all there is to it! This shows just how simple it is to do queries in an object oriented way, and have generic row mappers. There are full object relational mapping solutions, such as Hibernate, that do a great job of solving the working with relational data in an OO way paradigm, but they take a LOT of configuration and can be daunting if you’re not accustomed to working with them. This solution, however, I feel works very well in simpler scenarios. It also allows someone who is used to looking at code to quickly read through and get an idea of how to use this.

One point to note: this gets even simpler when using generics that are introduced in Java 1.5, but the environment I’m currently in is 1.4, so forgive me. I’ll leave the translation as an exercise for the reader.

Enjoy! Hope this helps!

Mapping your web server visitors in Google Earth, Part 3 (conclusion)

No Gravatar

A few days later, but here’s the conclusion to the story. In part 2, I showed how to parse out the apache log file to get a list of IP addresses. Now all you have to do is, one by one, geolocate those addresses and write them out to a KML doc that gets displayed in Google Earth (or even Google Maps).
For geolocating, I’m using the free product by MaxMind (http://www.maxmind.com/app/ip-location) to do the lookups for the geolocation. Here’s the code to do the geolocation and write out to KML.


import com.maxmind.geoip.*;
import java.io.*;

/* sample of how to use the GeoIP Java API with GeoIP City database */
/* Usage: java CityLookupTest 64.4.4.4 */

class CityLookup {
    public static void main(String[] args) {
        try {
            LookupService cl = new LookupService(args[0],
                    LookupService.GEOIP_STANDARD);
            BufferedReader in = new BufferedReader(new FileReader(args[1]));
            BufferedWriter out = new BufferedWriter(new FileWriter(args[2]));
            String str;

            out.write("<?xml version="1.0" encoding="UTF-8"?>n");
            out.write("<kml xmlns="http://earth.google.com/kml/2.1">n");
            out.write("<document>n");
            while ((str = in.readLine()) != null) {
                Location loc = cl.getLocation(str);
                if (loc == null) {
                    System.out.println("loc null");
                } else {
                    out.write(" <placemark>");
                    out.write("<name>" + str + "</name>");
                    out.write("<description>" + str + "</description>");
                    out.write("<point>");
                    out.write("<coordinates>" + loc.latitude + ","
                            + loc.longitude + "</coordinates>");
                    out.write("</point>");
                    out.write("</placemark>n");
                }
            }
            in.close();
            out.write("</document>n");

            out.write("</kml>n");
            out.close();
            cl.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Now, all you have to do is import the file into Google Earth, or if you have a publicly available web server, you can put the file there, and have google maps pick it up by passing the file as a parameter.
I hope you’ve enjoyed reading this 3-part tutorial as much as I’ve enjoyed writing it. This could be the start of a fun project. Hope you enjoy!

Part 2

Part 1

Mapping your web server visitors in Google Earth, Part 2

No Gravatar

Part 1 of this series talked at a high level about what was to be accomplished – viewing your web server visitors geographically on a map. It’s got a cool factor, but actually is quite useful for some folks.

This part of the series will show you how to take the Apache web server’s combined log format and get out the ip addresses that have visited your site. This code just parses a file, and takes the first token (first text before a space) and writes out a new line for each address. Alternatively, you could, instead of printing each line out, you could add them to a StringBuffer for better performance, then print them out. A reasonable idea would be to add them to a concrete implementation of java.util.Set so you only saw unique IP addresses. Anyhow, here’s the starter code.


import java.io.*;

public class ParseLogFile {
    public static void main(String[] args) {
        String newline = System.getProperty("line.separator");
        try {
            BufferedReader in = new BufferedReader(new FileReader(args[0]));
            BufferedWriter out = new BufferedWriter(new FileWriter(args[1]));
            String str;
            while ((str = in.readLine()) != null) {
                String[] strs = str.split(" ");
                out.write(strs[0] + newline);
            }
            in.close();
		out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

This should read in the apache log file and write out to a file with a long list of ip addresses / domain names. The above code is very simple and fairly unnecessary. You could easily use OS utilities to accomplish the same thing, and you could do this for any type of log file, really. This was just an example.

The last step is taking the output file, and then geolocating each address, and creating some KML out of the addresses. That’s gonna be saved for part 3. See you soon.

Mapping your web server visitors in Google Earth, Part 1

No Gravatar

OK, so this is mostly just for the cool factor. However, it is somewhat useful to see where your visitors are coming from at a glance. This type of project would be a nice project for a display wall in a server room somewhere. This example (explained fully other parts to come over the next few days) is simple in that it only looks at 1 apache log file format. It uses some open source information for doing it’s mapping, and then generates the KML for Google Earth to display a bunch of little dots on the earth for every access on your web server. The extensions to this project could be endless, starting with supporting many more file formats, and creating a prettier version of this – mine’s fairly rough. Well, more to come, but you’ll see the code over the next few days.

Java Testing: What do you use?

No Gravatar

This post is a generic post about what tools I use for testing in Java. Some of these are dependent on the frameworks that you use, some are generic across all of Java. I’ll probably update this post with future tools as I use them. What do you use? Just add it in the comments.

JUnit: The mother of all testing in Java. This unit test framework is on version 4 now, and is very stable and extremely effective. In my opinion, it is the single most effective tool to increase the quality of a developer’s code. (TestNG would be a similar framework here) [ http://www.junit.org/ ]

Cactus: This is a framework for testing server-side java code both with a real container or a mock container. [ http://jakarta.apache.org/cactus/ ]

StrutsTestCase: This framework allows developers to test code that utilizes the struts framework [ http://strutstestcase.sourceforge.net/ ]

Checkstyle: This tool checks your code against a set of coding standards. [ http://checkstyle.sourceforge.net/]

Findbugs: This is a static analysis tool to find bugs in Java programs. [ http://findbugs.sourceforge.net/ ]

Emma: This tool reports on test case coverage for your unit tests. [ http://emma.sourceforge.net ]

JDepend: This tool gives you quality metrics for your java code. [ http://www.clarkware.com/software/JDepend.html ]

PMD: PMD is another bug-finding utility for scanning your java code. [ http://pmd.sourceforge.net/ ]

Linking Struts and Spring with DelegatingActionProxy

No Gravatar

Struts is great for a generic MVC framework for J2EE apps.
Spring is great for it’s inversion of control capabilities, as well as many other fantastically useful features.
But … what happens when you want to link them? Well, my favorite way to do this is via the DelegatingActionProxy in Spring’s API. Essentially, you follow these steps:
1. Setup struts to know where spring is:


<plug-in classname="org.springframework.web.struts.ContextLoaderPlugIn">
	<set-property property="contextConfigLocation"
		value="/WEB-INF/applicationContext.xml" />
</plug-in>

2. Setup your action in struts to use the DelegatingActionProxy


<action path="/admin/myAction1"
	type="org.springframework.web.struts.DelegatingActionProxy"
	parameter="myAction1" name="MyForm" scope="request"
	input="/admin/home.do" validate="false">
    <forward name="success" path="/admin/myAction2.do" />
</action>

3. Configure an action in spring to link the action path to the appropriate struts action class


<bean name="/admin/myAction1" class="com.some.MyAction">
    <property name="myDA">
        <ref bean="myDA" />
    </property>
</bean>

That’s it! Now you’ve hooked up struts and spring successfully and cleanly. If you’d like more alternatives and information, this link can help out.

Using the Struts MappingDispatchAction

No Gravatar

When you have an application with many actions and they tend to be fairly thin, you can use the MappingDispatchAction from struts to ease your headaches. Instead of having a class for every action, you can place multiple actions in one class file via the use of methods other than execute, the standard struts action method. Here are the various pieces.

In the action,


public class MyAction extends MappingDispatchAction{
    public ActionForward doSomething1(ActionMapping mapping,
            ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
                //place code here
    }
    public ActionForward doSomething2(ActionMapping mapping,
            ActionForm form, HttpServletRequest request,
            HttpServletResponse response) throws Exception {
                //place code here
    }
}

In the struts-config.xml


	<action path="/actions/doSomething1.do"
			type="com.some.MyAction" parameter="doSomething1"
			name="MyForm" scope="request" validate="true">
		<forward name="success" path="/pages/myPage.jsp" />
        </action>
	<action path="/actions/doSomething2.do" type="com.some.MyAction"
			parameter="doSomething2" name="MyForm"
			scope="request" validate="true">
		<forward name="success" path="/pages/myPage2.jsp" />
        </action>

There you go, that’s all there is to it. Now you can have multiple methods in one action, and can handily reduce the amount of extraneous code in your application that’s just boilerplate action classes.

Java 5 Generics

No Gravatar

Here’s a quick example of the difference between Java 1.4 Iterators and Java 5 generics.

Here’s 1.4:


List myList = new ArrayList();

myList.add(new Person("John Melton"));
myList.add(new Person("Bill Mares"));

for (Iterator it=myList.iterator(); it.hasNext(); ) {
    Person person = (Person) it.next();
    System.out.println(person);
}

Now the Java 5 generics version:


List<Person> myList = new ArrayList<Person>();

myList.add(new Person("John Melton"));
myList.add(new Person("Bill Mares"));

for (Person person : myList) {
    System.out.println(person);
}

See – very pretty. You just add those fun angle brackets (<>) to denote generics, and the code is cleaned up quite a bit. In my experience, the returns on beauty only get greater the more code you write. There’s also some great templating features with generics to make generic processing procedures very flexible. I love the syntactic sugar … mmmm.

Happy coding!

← Previous Page