A REST service with Jetty and Jersey

A REST service with Jetty and Jersey

In this tutorial we are going to set up a maven project using Jetty and Jersey to create a simple REST service. Use your editor of choice. I am using IntelliJ Community Edition and this tutorial will follow the settings and structure of that editor.

Setting up a project

We start by creating a new project by choosing File > New > Project from the IntelliJ menu. Choose Maven from the menu and check Create form archetype. We are going for maven-archetype-quickstart.

Hit Next type in Groupid and Artifactid of your choice and hit Next, hit Next again and choose a project name. IntelliJ will now create a project structure looking somewhat like the picture below.

Now, create a new java file in the same package as App.java. I'll call it Resource.java. This will be the file where we are going to write our REST-methods using Jersey. Create a new folder under src, here we will create a index.html which we will use to send data to our server.

Now we have our project structure. Then we may start coding our REST service.

Adding dependencies

First we need to add some dependencies. Open up your pom.xml file. This magic document will download all the libraries you will need to complete your application.

Copy the following dependencies inside the dependencies-tag.

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-server</artifactId>
    <version>9.2.3.v20140905</version>
</dependency>

<dependency>
    <groupId>org.eclipse.jetty</groupId>
    <artifactId>jetty-servlet</artifactId>
    <version>9.2.3.v20140905</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.core</groupId>
    <artifactId>jersey-server</artifactId>
    <version>2.7</version>
</dependency>

<dependency>
    <groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-servlet-core</artifactId>
    <version>2.7</version>
</dependency>

<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
    <artifactId>jersey-container-jetty-http</artifactId>
    <version>2.7</version>
</dependency>

Creating the Jetty server

With the dependencies in our pom.xml, we now have access to several libraries from Jetty and Jersey that we are going to use to make our application. We will start by creating the server.

In our App.java-file, type the following code.

ResourceConfig config = new ResourceConfig();
config.packages("jettyjerseytutorial");
ServletHolder servlet = new ServletHolder(new ServletContainer(config));

Server server = new Server(2222);
ServletContextHandler context = new ServletContextHandler(server, "/*");
context.addServlet(servlet, "/*");

try {
    server.start();
    server.join();
} finnaly {
    server.destroy();
}

ResourceConfig (Jersey) inherit from Application and gives a new configuration without custom properties. The next line takes a vararg of packages as arguments to search for components/resources.

ServletHolder (Jetty) is a Servlet instance and context holder. It holds name, parameters and some states of javax.servlet.Servlet instance. The ServletContainer is a Servlet/Filter for deploying root resource classes.

Server (Jetty) is the main class for the Jetty HTTP Servlet server. It aggregates connectors and requests. The server itself is a handler and a ThreadPool.

ServletContextHandler (Jetty) takes the arguments HandlerContainer and contextPath. It gives Servlet context and is and extends ContextHandler. It allows for simple construction of a context with ServletHandler. The method addServlet() is a convenience method to add a Servlet.

Try running this by choosing Run > Run from the menu. Congrats, you now have your embedded Jetty server running. Now, let us add some action.

Jersey

@Path

The path where the resource is exposed.

@GET

Method handling HTTP GET requests.

@POST

Method handling HTTP POST requests.

@Produces

Specify the MIME media type a resource can produce and send back to the client.

@Consumes

Specify the MIME media type a resource can consume that were sent by the client.

Jersey gives us access to a set of annotations, which we can use to process HTTP requests like GET, POST, DELETE and PUT. We will take a look at POST and GET in this tutorial.

Root resource classes are plain old java objects (POJOs) that are annotated with @Path have at least one method annotated with @Path or a resource method designator such as @GET, @PUT, @POST or @DELETE.

Creating a @GET-method

In our Resource-class that we created earlier, we will add a method that will handle HTTP GET requests.

@Path("home")
public class Resource {
  @GET
  @Path("hello")
  @Produces(MediaType.TEXT_PLAIN)
  public String helloWorld() {
    return "Hello, world!";
  }
}

Start your server by running App.main(). When the server is running, open a web browser and see what happens when you go to http://localhost:2222/home/hello.

You should get a response like shown in the picture above. You now have a working REST service running using Jetty and Jersey. Next we will look at different methods on taking parameters from the URI, as well as creating a @POST method.

Queries and paths

Using the annotation @QueryParam allows us to give a parameter to our URI. In this case, if we type in the URI http://localhost:2222/home/param?name=Me our method will return "Hello, Me" to the browser.

@GET
@Path("param")
@Produces(MediaType.TEXT_PLAIN)
public String paramMethod(@QueryParam("name") String name) {
  return "Hello, " + name;
}

A @QueryParam will look for the given name of the parameter in the URI, here it is "name", and assign this to the following variable String name. By typing ?name=Me at the end of the URI, you assign the variable name to Me.

Another way to get values from the URI-path is to use the annotation @PathParam.

@GET
@Path(“path/{var}”)
@Produces(MediaType.TEXT_PLAIN)
public String pathMethod(@PathParam(“var”) String name) {
    return “Hello, “ + name;
}

In this case out value will be assigned to ".../{var}", which is of type String in this example. By typing http://localhost:2222/home/path/Me this method will return "Hello, Me" to the browser.

Creating a @POST method

Creating @POST methods will come in handy when you want to send data from your browser to your application. In this example we will send data to our application using a HTML-form.

Open up your index.html and create a HTML-form. It may look somewhat like this.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Simple Jersey</title>
</head>
<body>
  <form action="http://localhost:2222/home/post" method="post">
    <p>Name: <input type="text" name="name"></p>
  </form>
</body>
</html>

Note that form has some tags called action and method. At action we specify what URI our @POST-method is located on. The method should be post.

When opening index.html in a browser, it should look like the picture above.

In addition to this HTML-file, we need a @POST-method in our Resource class.

@POST
@Path("post")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces(MediaType.TEXT_HTML)
public String postMethod(@FormParam("name") String name) {
  return "<h2>Hello, " + name + "</h2>";
}

Here we say that this method will consume MediaType.APPLICATION_FORM_URLENCODED. In other words, this method expects fata from a HTML-form. We also say that the method will produce HTML-formatted data. Re-run your application and type in your name at index.html and see what happens. You should get "Hello, <your name>" as result in your browser.

You have now created a REST service using Jetty and Jersey with methods for both receiving and sending data from and to your server.

Sources

Heimsbakk, Veronika

Heimsbakk, Veronika

Konsulent // Application Lifecycle Management
veronika.heimsbakk@acando.no

 

Om bloggeren:
Veronika har studert programmering og nettverk ved Universitetet i Oslo og har en forkjærlighet for logikk, semantiske teknologier, typografi og elektronikk.

comments powered by Disqus