To make our Jersey RESTful Web Service Application be able to @Autowire service classes and inject Java Beans we will need to add to it a support for Spring Dependency Injection(DI) and below I am going to share with you how to do it.
To add Spring DI support to my JAX-RS application, I am going to use a very basic app I can create with maven. Follow this link to see how I use maven to create a very basic Jersey JAX-RS application.
JAX-RS, Jersey and Spring DI Dependencies in POM.XML
Once we have created our very basic Jersey JAX-RS application and have added the jaxrs-ri and the jersey-media-moxy dependencies to our pom.xml file there are a couple of more dependencies that we need to add to pom.xml file for our Spring DI to work. These two dependencies are: jersey-spring3 and commons-logging.
So the complete pom.xml file that I have now in my project and which is working well is with the two new dependencies already added is below:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.appsdeveloperblog.jersey</groupId> <artifactId>SpringDependencyInjectionExample</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>SpringDependencyInjectionExample Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.bundles/jaxrs-ri --> <dependency> <groupId>org.glassfish.jersey.bundles</groupId> <artifactId>jaxrs-ri</artifactId> <version>2.25</version> </dependency> <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy --> <dependency> <groupId>org.glassfish.jersey.media</groupId> <artifactId>jersey-media-moxy</artifactId> <version>2.25</version> </dependency> <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.ext/jersey-spring3 --> <dependency> <groupId>org.glassfish.jersey.ext</groupId> <artifactId>jersey-spring3</artifactId> <version>2.25.1</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-logging/commons-logging --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <finalName>SpringDependencyInjectionExample</finalName> </build> </project>
Extending ResourceConfig to Support Spring Dependency Injection
To make our web app to function like a Jersey application we needed to create a custom class which extends javax.ws.rs.core.Application. But now, to support Spring DI, instead of making our class extend Application class, we will need to extend ResourceConfig class. So the complete custom class which serves for me as Jersey Application Starting point looks like this:
import javax.ws.rs.ApplicationPath; import org.glassfish.jersey.server.ResourceConfig; @ApplicationPath("api") public class MyApi extends ResourceConfig { }
Create applicationContext.xml File
List Java Beans and service classes you want to be able to @Autowire into your application in applicationContext.xml file which in my case I have created in src/main/resources folder. I am going to @Autowire only one service class and below is my complete applicationContext.xml file:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="userService" class="com.appsdeveloperblog.service.impl.UserServiceImpl"/> </beans>
Adding Spring Framework Annotations
We can now @Autowire application services into our Root Resource class. For example to @Autowire a service class I will use:
@Autowired private UserService userService;
@Autowire UserService Class. Complete Code Example.
Let’s assume we are building a Web Service endpoint which needs to return user profile details. Our Root Resource class will look something like this:
import com.appsdeveloperblog.io.dto.UserDto; import com.appsdeveloperblog.service.UserService; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Path("/users") public class UsersEntryPoint { @Autowired private UserService userService; @GET @Path("/{userId}") @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) public UserProfile getUser( @PathParam("userId") String userId ) { UserProfile returnValue = new UserProfile(); UserDto userDto = userService.getUser(userId); if(userDto == null) return returnValue; returnValue.setFirstName(userDto.getFirstName()); returnValue.setLastName(userDto.getLastName()); return returnValue; } }
User Service Interface Class
package com.appsdeveloperblog.service; import com.appsdeveloperblog.io.dto.UserDto; public interface UserService { public UserDto getUser( String userId ); }
User Service Interface Implementation Class
import com.appsdeveloperblog.io.dto.UserDto; import com.appsdeveloperblog.service.UserService; public class UserServiceImpl implements UserService { @Override public UserDto getUser( String userId ) { if( userId==null ) return null; UserDto user = new UserDto(); user.setFirstName("Sergey"); user.setLastName("Kargopolov"); return user; } }
User Profile Rest Model Class (Return Value)
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class UserProfile { private String firstName; private String lastName; /** * @return the firstName */ public String getFirstName() { return firstName; } /** * @param firstName the firstName to set */ public void setFirstName(String firstName) { this.firstName = firstName; } /** * @return the lastName */ public String getLastName() { return lastName; } /** * @param lastName the lastName to set */ public void setLastName(String lastName) { this.lastName = lastName; } }
User Data Transfer Object Class
public class UserDto { private String firstName; private String lastName; /** * @return the firstName */ public String getFirstName() { return firstName; } /** * @param firstName the firstName to set */ public void setFirstName(String firstName) { this.firstName = firstName; } /** * @return the lastName */ public String getLastName() { return lastName; } /** * @param lastName the lastName to set */ public void setLastName(String lastName) { this.lastName = lastName; } }
Building RESTful Web Services is much more fun when you know the subject very well. Check out the video courses below which will definitely help you on your way to becoming a very good RESTFul Web Services developer.
Java Web Services. Video Course.
Learn how to design,create , consume and secure SOAP and REST web services from scratch in easy steps.
Since you are using @Autowired annotation in your Root Resource class, why do you have in your application context and not just