Wednesday, July 28, 2010

Jersey and Spring Injection

On the project I am on we use iBatis, Spring, and Jersey. We have been using spring injection for our DAOs since the beginning, but our version of Jersey at the time did not support spring injection. To get around this we created factories allowing us to inject beans into the factories. Our REST classes then used the factory to get the beans they were interested in. As the project grew, so did the factory. When we upgraded to Jersey 1.0.3, we were able to take advantage of a Jersey-Spring jar, that would allow us to spring inject beans directly into our REST classes.

In our Maven pom.xml file we added the following dependency.

<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.0.3</version>
</dependency>

Then in the constructor of the REST Classes we were able to do the following: (NOTE: as of Jersey 1.4, @Inject becomes @InjectParam)

public class CompanyWS {
private ICompanyManager _companyManager;
private ICompanyTypeManager _companyTypeManager;
public CompanyWS (@InjectParam("companyManager") ICompanyManager companyManager,
@InjectParam("companyTypeManager") ICompanyTypeManager companyTypeManager) {
_companyManager= companyManager;
_companyTypeManager= companyTypeManager;
}
...


The web.xml file also needs to be modified to call out the SpringServlet, instead of the ServletContainer:


<servlet>
<servlet-name>REST Application</servlet-name>
<servlet-class>com.sun.jersey.spi.spring.container.servlet.SpringServlet</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.accenture.netcds.api.rest.RegisterResources</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>


One downside of the 1.0.3 Spring-Jersey library is that the automatic finding of the REST classes does not work in websphere 6.1. This has been reported as a bug to Jersey and is supposed to be fixed in the more recent versions. As a result the REST classes need to be registered in an Application class.


public class RegisterResources extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(CompanyWS.class);
return s;
}
}


Spring successfully injected the beans into the REST classes, allowing us to delete the factories we had been using that had grown quite large. Another simplification to make it easier to maintain the software over time.

1 comment:

shahzeb khan said...

Excellent work !!! it was a pain before.