Category Archives: Spring

REST in Spring without using Spring Webservices

I quite like using Spring. Especially when using the Spring/Hibernate combo.

About a year ago I started using Spring for a whole heap of REST webservices I was writing. In the process I found it surprisingly easy. Various other colleagues experimented with RESTLET (http://www.restlet.org/) and Jersey (https://jersey.dev.java.net/). But as I wanted to use Hibernate easily and I was using Spring MVC to build the client component of the project I was working on, so I used Spring MVC to build the services. Pretty simple. (Even though I refer to Spring 2.5 in the pom file, I am not using the features of 2.5.)

Here’s an example:

I have created a simple webapp using maven. The webapp is called rest-webapp. I have created a stupid service that retrieves the name of an evil programmer.

This means that the request would look like:
http://localhost:8080/rest-webapp/evil/programmers/1

and this would return:
Dr Evil

I wrote a simple class that does this and also returns a 404 error if the request for tne evil programmer does not exist.

This means that the request would look like:
http://localhost:8080/rest-webapp/evil/programmers/6

would return a 404 error with the message: HTTP Status 404 – This evil programmer does not exist!!

pom.xml

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5</version>
</dependency>

web.xml

<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<!DOCTYPE web-app PUBLIC “-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN” “http://java.sun.
com/dtd/web-app_2_3.dtd”>
<web-app>
<display-name>rest-webapp</display-name>
<description>Test Rest Service</description>
<servlet>
<servlet-name>mytest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mytest</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>1</session-timeout>
</session-config>
</web-app>

mytest-servlet.xml (Spring Application Context)

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

<bean id=”urlMapping” class=”org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>
<property name=”mappings”>
<props>
<prop key=”/evil/programmers/*”>myController</prop>
</props>
</property>
</bean>

<bean id=”myController” class=”au.bandaid.programming.controller.MyTestController”>
</bean>

</beans>


MyTestController.java

package au.bandaid.programming.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import au.bandaid.programming.exception.HttpStatusException;

public class MyTestController implements Controller {

private Hashtable list;

public MyTestController() {
list = new Hashtable();
// Set an arbitary list
list.put(“1”, “Dr Evil”);
list.put(“2”, “Big Bad Billy”);
list.put(“3”, “Big Bad Billy”);
list.put(“4”, “Stevie Exception”);
list.put(“4”, “Frank Void”);
}

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {

// Determine the type of method
try {
if (request.getMethod().toUpperCase().equals(“GET”)) {
writeResponse(response, “text/xml”, HttpServletResponse.SC_OK, get(request));
}
//else if (method.toUpperCase().equals(“POST”))
//else if (method.toUpperCase().equals(“DELETE”))
//else if (method.toUpperCase().equals(“PUT”))

else {
throw new HttpStatusException(HttpServletResponse.SC_NOT_IMPLEMENTED, “Operation: ” + request.getMethod() + ” not supported.”);
}
}
catch (HttpStatusException e) {
response.sendError(e.getStatusCode(), e.getMessage());
}
catch (Exception e) {
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.toString());
}

return null;
}

private String get(HttpServletRequest request) throws HttpStatusException {

// Grab some parameters
// I am not using any now
String type = request.getParameter(“type”);

// Look at the request
// am expecting rest-webapp/programmers/1
Pattern p = Pattern.compile(“[1-9]+”);
Matcher m = p.matcher(request.getPathInfo());
String index = “”;
if (m.find()) {
index = m.group();
}

if (!list.containsKey(index)) {
throw new HttpStatusException(HttpServletResponse.SC_NOT_FOUND, “This evil programmer does not exist!!”);
}

return “” + list.get(index) + ““;
}

private void writeResponse(HttpServletResponse response, String contentType, int statusCode, String ouput) throws IOException {
response.setContentType(contentType);
response.setStatus(statusCode);
PrintWriter out = new PrintWriter(response.getOutputStream());
out.println(ouput);
out.close();
}

}

Some extra reading:
http://jira.springframework.org/browse/SPR-4419 – Comprehensive REST Support
http://springframework.org/docs/MVC-step-by-step/Spring-MVC-step-by-step.html

The Hans Gruber effect – Using Spring and Hibernate JPA

At the end of the movie Die Hard John McClane (Bruce Willis), releases the watch from Holly’s wrist which results in Hans Gruber (Alan Rickman) falling to his death. Hans was hanging out of a window in a huge high rise, holding onto the wrist of Holly. The iconic scene has the view from their perpective seeing Hans flapping his arms moving further and further away from them as he falls to the ground. In some ways I felt like Hans flapping my arms trying to make Hibernate JPA and Spring work, whilst gravity was pulling me closer to my death …

Well my work colleague, Dave, first put me on the path to enlightenment. He references Ignacio’s experience or rather what he did to make the thing work. However, in all the references I flapped more and more as they all do it a little differently. Also Ignacio uses Spring auto-wiring and recently in a Spring course by Interface 21, the presenter, reckoned that auto-wiring should not really be used.

Maybe the biggest factor in my Hans Gruber impersonation is that at times everyone else makes it look so easy while I feel like a dufus. But I did eventually succeed.

Here’s how it worked for me:

I pretty much based everything I did on Getting Started with JPA in Spring 2.0, however I couldn’t get it to work properly. I also used Hibernate JPA and therefore had to make a few changes. I will list these changes below.

Issue 1: Gather all the required Jar’s

This is a bit of a problem as many of the blogs I read didn’t give a list of Jar’s required. I downloaded a version of:

* Spring 2.04
* Hibernate 3.2
* Hibernate Entity Manager 3.3.1

From these downloads a I used the following jar files. Still not sure if they are all needed but here is the list:

antlr-2.7.6.jar
dom4j-1.6.1.jar
javassist.jar
asm-attrs.jar
ejb3-persistence.jar
jboss-archive-browsing.jar
asm.jar
hibernate-annotations.jar
jta.jar
cglib-2.1.3.jar
hibernate-commons-annotations.jar
log4j-1.2.14.jar
classes12.jar (I am using Oracle DB)
hibernate-entitymanager.jar
spring-2.0.4.jar
commons-collections-2.1.1.jar
hibernate-validator.jar
commons-logging-1.0.4.jar
hibernate3.jar

Issue 2: Spring config file

There were a few issues with setting up the config file.

Note the following:

  • Include the annotations for transactions, this becomes relevant when performing transactions and a solution for Lazy fetches.
  • I couldn’t get it to wotk with ContainerEntityManagerFactoryBean so I used LocalContainerEntityManagerFactoryBean

<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:tx=”http://www.springframework.org/schema/tx”
xsi:schemaLocation=”
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd”>

<!– Put this here if you want to use transactions –>
<tx:annotation-driven transaction-manager=”transactionManager”/>

<!– This comes from the blog
http://blog.interface21.com/main/2006/05/30/getting-started-with-jpa-in-spring-20/ –>
<bean id=”restaurantDao” class=”blog.jpa.dao.JpaRestaurantDao”>
<property name=”entityManagerFactory” ref=”entityManagerFactory”/>
</bean>

<!– I used Oracle just change the dialect below to match your db –>
<!– I couldn’t get the ContainerEntityManagerFactoryBean to work
so I used LocalContainerEntityManagerFactoryBean –>
<bean id=”entityManagerFactory” class=”org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean”>
<property name=”dataSource” ref=”dataSource” />
<property name=”jpaVendorAdapter”>
<bean
class=”org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter”>
<property name=”showSql” value=”true” />
<property name=”generateDdl” value=”false” />
<property name=”databasePlatform” value=”org.hibernate.dialect.Oracle9Dialect” />
</bean>
</property>
</bean>

<bean id=”dataSource” class=”org.springframework.jdbc.datasource.DriverManagerDataSource”>
<property name=”driverClassName” value=”oracle.jdbc.driver.OracleDriver” />
<property name=”url” value=”jdbc:oracle:thin:@xxx:1521:xxx” />
<property name=”username” value=”bandaid” />
<property name=”password” value=”bandaid” />
</bean>

<bean id=”transactionManager” class=”org.springframework.orm.jpa.JpaTransactionManager”>
<property name=”entityManagerFactory” ref=”entityManagerFactory” />
<property name=”dataSource” ref=”dataSource” />
</bean>

</beans>

Issue 3: Lazy vs Eager Fetching

All was happy until I started playing around with lazy fetching. The problem was that I kept getting a session ending error after the initial read. This appears to be a Spring issue. Spring closes the database connection and you try to do the lazy fetch it throws an error that basically means the database connection doe snot exist. So after reading many blogs, pulling my hair out and crying myself to sleep at night, I stumbled onto the following blog Hibernate Lazy Loading.

I discovered a few work arounds for Spring:

  1. Don’t make any Lazy calls and just call the collection manually. I didn’t like that option.
  2. Make everything Eager. Not a good one either.
  3. Implement the OpenSessionInViewFilter in the Spring config. I read a few more blogs, referenced all the spring books I had and still couldn’t get the thing to work. It does seem to work but I couldn’t figure it out.
  4. Use the Spring @Transaction annotation for the method or class. That’s why I declared the annotations in the above spring config file.

Outcome

I am very happy. Smiles all round. After many days impersonating Hans Gruber, I finally got the thing to work. It’s really simple and easy. I will tell my friends about it.