4 minute read

Background

I originally wrote this series back in 2013 on a wiki. At that point in my career, I had spent several years working on java based projects, specifically webservices with jax-rs and Jersey (Sun/Oracle’s reference implementation of jax-rs). I became pretty proficient, and decided to write down some of my knowledge in a form “how-to” and starterkit / template project. I got good feedback that it was helpful both from teammates and external random techies.

I am 100% sure this info is outdated.

Tutorial List

Starter Kit

I had created a starter kit / template project. To clone the repository locally: git clone git@github.com:jasonray/jersey-starterkit.git

Have at it!

Purpose of this tutorial

This tutorial is a “hello-world” of sorts to show how to create a basic jersey project. I am using gradle to build and deploying to tomcat for this example.

tldr; I just want a starter project!

If you don’t care about the steps and just want a sample project, you can clone from jersey-starterkit.

I want to follow along on how to create a starter project

Prereq’s

Make sure gradle and tomcat (or other web container) are installed.

Specify dependencies

Create a build.gradle file with jax-rs and jersey dependencies.

If you are using eclipse, the eclipse plugin allow you to run gradle eclipseClasspath to build out the classpath with dependencies.

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'war'

repositories {
    mavenCentral()
}

dependencies {
	compile "javax.ws.rs:jsr311-api:1.1.1"

	compile 'com.sun.jersey:jersey-server:1.13'
	compile 'com.sun.jersey:jersey-core:1.13'
	compile 'com.sun.jersey:jersey-servlet:1.13'

	testCompile "junit:junit-dep:4.10"
}

Create project and import dependencies

Create an empty project.

If you are using eclipse, you can pull dependencies and import into the classpath by running gradle jar eclipseClasspath

Create resource class

The resource class is your actual endpoint for your webservice. If you are following a REST / Resource Oriented Architecture (ROA) approach, this is likely a “thing”/noun in your system, such as a customer, order, etc. I typically name this something like “CustomerResource” with methods like “getCustomers” or “getCustomer” or “updateCustomer”.

For this demo, we will use the obligatory hello world.

Create a new class, hello.java, that represents your resource. On this class add the @Path attribute. This attribute take a single value that represents the path to access this resource.

Note: if you are unable to resolve the javax.ws.rs.Path import it is likely that you have not yet pulled in the dependencies using gradle from earlier.

import javax.ws.rs.Path;

@Path("hello")
public class HelloWorldResource {
}

Now that we have the resource class, lets add a web service / resource method. For this, we will create a method of “sayHello” and apply the @GET attribute.

@GET
public String sayhello() {
   return "hello";
}

We can also specify the media type of the result using the @Produces attribute:

@GET
@Produces(MediaType.TEXT_PLAIN)
public String sayhello() {
   return "hello";
}

My final class looks like:

package jayray.net.hello;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("hello")
public class HelloWorldResource {
	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayhello() {
		return "hello";
	}

}

Configure jersey servlet

Jersey works by using a servlet to capture calls to a URL, and routing to the correct methods based on the path, media type, and method.

To configure to which URL’s the servlet will listen, we need to add a servlet section to the web.xml file.

First, if you don’t already have one, create a web.xml file to /src/main/webapp/WEB-INF:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
</web-app>

Next, add the servlet definition, and specify to start on startup. The name is arbitrary and the class references the class from the jersey package.

<servlet>
   <servlet-name>Jersey</servlet-name>
   <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
   <load-on-startup>1</load-on-startup>
</servlet>

Next, Jersey needs to know which classes could possibly be resource classes. To do this we use an init param to specify the packages that contain the resource classes. This can be a semicolon delimited list. In my example, my resource class is in the jayray namespace so I add the following to my servlet definition:

<init-param>
   <param-name>com.sun.jersey.config.property.packages</param-name>
   <param-value>jayray</param-value>
</init-param>

Last, we need to specify which URL’s get routed to Jersey. You can route all (“*”) or a limited set. I generally use “rest” or “api” as my root.

<servlet-mapping>
   <servlet-name>Jersey</servlet-name>
   <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

The full web.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
	<display-name>jersey sample</display-name>
	<servlet>
		<servlet-name>Jersey</servlet-name>
		<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
		<init-param>
			<param-name>com.sun.jersey.config.property.packages</param-name>
			<param-value>jayray</param-value>
		</init-param>
		
		<!-- the following is only needed if you want to use the built-in support
		for mapping pojo objects to json. -->
		<init-param>
			<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
			<param-value>true</param-value>
	</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>Jersey</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>
</web-app>

Compile, deploy, and exercise

To compile, run ./gradlew clean war

I am running apache-tomcat, so I am going to deploy by copying the created war from /builds/lib to my apache-tomcat webapps directory:

cp build/libs/jersey-starterkit.war /Applications/apache-tomcat-6.0.33/webapps/

To exercise the web service, open a browser to the URL or use curl to exercise the URL:

curl localhost:8080/jersey-starterkit/rest/hello