RestEasy, Tomcat, Maven, IntelliJ IDEA: A Getting Started Guide

Nicolai Ferraris
Jan 1, 2018 · 8 min read

This is a tutorial I am writing for getting started with building RESTful web services with IntelliJ, Maven, RestEasy, and Apache Tomcat.

I spent some time searching for a recently written getting started guide or some tutorials for working with RestEasy and how to setup my IntelliJ IDE for it. Unfortunately, I wasn’t able to find anything recent enough for my liking so I figured I’d have a go at writing one myself!

I’m also pretty new at writing guides like this, so any feedback would be greatly appreciated!

You can probably replicate a lot of the steps I’m doing with any other IDE, but I’m using IntelliJ.

Ok. Getting started:

0. Assumptions

I am assuming that you already have Apache Tomcat installed as well as some IDE of your choosing.

On a Mac, I installed Apache Tomcat using Homebrew, on Linux you can use apt to install it I believe.

Be sure to configure your IDE to utilize your Apache Tomcat installation! I found quite a few guides on how to do this with IntelliJ online.

1. Setup

First, create a new basic Java project in your IDE, for IntelliJ, hit “Create New Project”. On the left hand side, just select “Java” and hit “Next”.

You’ll be prompted if you want to create a project from template, just hit “Next” again.

You will then be prompted to provide a name and path to your project:

I just named mine “RESTHello”

Finally hit “Finish”.

You’ll then probably (hopefully) see your workspace, something similar to this:

Looks kinda empty right now… :(

Right click the bar on the left hand side, the project explorer window. Hit “Add Framework Support”.

Select Maven and hit “OK”.

Select ‘Maven’

Some files, including a pom.xml, will be generated.

You might also be prompted “Maven projects need to be imported”. I selected “Enable Auto-Import”.

Provide a groupId. For simplicity’s sake, I will be using “com.nicolaifsf”.

Next we are going to get our project’s dependencies.

The dependencies we will be using are the following:

  • RestEasy
  • RestEasy Client
  • JUnit

Add the following to your pom.xml before the closing </project> :

<repositories>
<repository>
<id>JBoss repository</id>
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>
<dependencies> <!--resteasy-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.4.Final</version>
</dependency>
<!--rest-easy client-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.1.4.Final</version>
</dependency>
<!--unit test-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
</dependencies>

This is how mine looks like now:

We have now specified the dependencies to our project that we will be using.

Now let’s specify in our pom.xml that we are writing a web application:

Add the following after the </dependencies> and before </project> :

<packaging>war</packaging>

At this point my entire pom.xml looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.nicolaifsf</groupId>
<artifactId>RESTHello</artifactId>
<version>1.0-SNAPSHOT</version>

<repositories>
<repository>
<id>JBoss repository</id>
<url>https://repository.jboss.org/nexus/content/groups/public-jboss/</url>
</repository>
</repositories>

<dependencies>

<!--resteasy-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.1.4.Final</version>
</dependency>

<!--rest-easy client-->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.1.4.Final</version>
</dependency>

<!--unit test-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>


</dependencies>

<!--Indicate that its a web app-->
<packaging>war</packaging>
</project>

Next, we are going to add our web.xml.

First, create a directory with the path: /src/main/webapp/WEB-INF.

Then, we now want to create a new file inside of this directory with the name “web.xml”.

My file hierarchy after creating the directories and web.xml

Add the following to your “web.xml”.

(filling in your groupId for where I have {{ groupId }}:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<!--Prefix for the endpoints-->
<param-value>/</param-value>
</context-param>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>{{ groupId }}.app.HelloApplication</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<!--Prefix for endpoint-->
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>

Mine looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>Restful Web Application</display-name>

<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<!--Prefix for the endpoints-->
<param-value>/</param-value>
</context-param>

<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>
org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>com.nicolaifsf.app.HelloApplication</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<!--Prefix for endpoint-->
<url-pattern>/*</url-pattern>
</servlet-mapping>

</web-app>

Here we have specified the some of the configurations of our web application. We specified that this application will be at “<host addr>/”, or the root.

We have given a name to the servlet, and we have specified the entrypoint of our application, in my case “com.nicolaifsf.app.HelloApplication”.

2. Add Our Classes

First, we are going to create two packages:

  1. {{ your groupId }}.app
  2. {{ your groupId }}.rest

For example, I have:

Let’s now add under our “rest” package, a file named “HelloRestService.java”.

In HelloRestService we’re going to add the following code:

package com.nicolaifsf.rest; // Note your package will be {{ groupId }}.rest

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;

@Path("/")
public class HelloRestService {
@GET // This annotation indicates GET request
@Path("/hello")
public Response hello() {
return Response.status(200).entity("hello").build();
}
}

This specifies a base path “/” and if “/hello” follows, to then reply back with a response with a 200 status code (OK), and “hello”.

“@Path(“/”)” specifies that the root is “/”

“@GET” specifies that this is the code to execute if we get a GET request

“@Path(“/hello”)” is the endpoint to utilize.

We now have to create the actual application. Note how before in the web.xml we specified com.nicolaifsf.app.HelloApplication . Let’s add that class to our app package now!

We now have both our HelloApplication and HelloRestService!

Add the following code to your HelloApplication:

package com.nicolaifsf.app; // {{ groupId}}.app// import the rest service you created!
import com.nicolaifsf.rest.HelloRestService;
import com.nicolaifsf.rest.HelloRestService; import javax.ws.rs.core.Application;
import java.util.HashSet;
import java.util.Set;
public class HelloApplication extends Application {
private Set<Object> singletons = new HashSet<Object>();
public HelloApplication() {
// Register our hello service
singletons.add(new HelloRestService());
}
@Override
public Set<Object> getSingletons() {
return singletons;
}
}

Here we have defined the Application entrypoint that we specified in our web.xml.

We registered our HelloRestService by adding into to our set of singletons.

And finally, we have overrided the Application class to have “getSingletons()”.

Now we’ve set up our application. Time to run it!

But first…

3. Setting up your build configurations

This might be different per IDE, but the following instructions are for IntelliJ:

First, select this dropdown on the top right hand side of the window:

Hit “Edit Configurations”.

From the new window that popped open, hit the “+” button on the top left, and select “Tomcat Server” > “Local”.

You will then be shown this:

Hit the “+” button on the bottom part, right below “Build” and select “Build Artifacts”.

It will then prompt you to select artifacts.

I selected “RESTHello:war” and hit OK:

Next click the “Deployment” tab and hit the “+” under the “Deploy at the server startup” section:

Hit “Artifact”, then in the window that pops up, select the artifact you specified earlier and hit OK:

Finally hit “Apply” and “OK” to complete the configuration.

This is now how my window looks like:

Finally:

4. Running your application

Hit the green play button on the top right hand corner to build and run your application.

Navigate to your browser window and go to “localhost:8080/hello”.

You should now see on your browser the word “hello” on your screen.

It works!

Congrats! You’ve now made a simple RESTful server with RestEasy, Maven, and Tomcat!

5. Testing

Very important is also testing our code!

Under “src/test/java/” create a new file called “HelloRestServiceTest.java”.

Add the following code (replacing “com.nicolaifsf” with whatever your groupId is):

import com.nicolaifsf.rest.HelloRestService;
import org.jboss.resteasy.core.Dispatcher;
import org.jboss.resteasy.mock.MockDispatcherFactory;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import javax.ws.rs.core.Response;
import java.net.URISyntaxException;

public class HelloRestServiceTest {
private static Dispatcher dispatcher;
private static POJOResourceFactory noDefaults;
// This code here gets run before our tests begin
@BeforeClass
public static void setup() {
dispatcher = MockDispatcherFactory.createDispatcher();
noDefaults = new POJOResourceFactory(HelloRestService.class);
dispatcher.getRegistry().addResourceFactory(noDefaults);
}
// One of our actual tests!
@Test
public void helloTest() {
try {
// Specify the endpoint we want to test, for our example, we use "/hello"
MockHttpRequest request = MockHttpRequest.get("/hello");
MockHttpResponse response = new MockHttpResponse();
// Invoke the request
dispatcher.invoke(request, response);
// Check the status code
Assert.assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
// Check that the message we receive is "hello" Assert.assertEquals("hello", response.getContentAsString());
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}

The stuff in Setup creates a Mock dispatcher that we can utilize to test the HelloRestService class without having to run our server. With this, we can run our tests much faster!

Note how the setup method is annotated with “@BeforeClass”, this indicates that this should be run before the tests are run.

In “helloTest()”, we create MockHTTPRequest and MockHTTPResponse objects. We then utilized the dispatcher to “invoke” the request.

Finally we then use JUnit’s “Assert.assertEquals” to compare the status code, and messages that we expected versus what we actually received.

This code here tests the endpoint we created “/hello”!

You can run the test on IntelliJ by hitting the “play” icons on the left!

Everything should come back as having passed the test case.

Congrats, not only have you developed a RESTful service with RestEasy at this point, but now you’ve also learned how to write a basic Unit Test for it as well!

Conclusion

Thanks for taking the time to read my tutorial! Please let me know if there are any mistakes I’ve made, or if there’s anything I can do to improve. I’m always looking for feedback and am always looking to get better :).

Nicolai Ferraris

Written by

Student — NYU Fall of 2017

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade