resteasy

RESTEasy Hello World Example

In this example we are going to get started with Java API for RESTful Web Services (JAX-RS), a set of APIs to developer REST services. JAX-RS is a new JCP specification that provides a Java API for RESTful Web Services over the HTTP protocol and  is part of the Java EE.  REST (REpresentational State Transfer) is a simple stateless architecture that generally runs over HTTP.

In our tutorial we are going to use RESTEasy,a JBoss project that provides various frameworks to help you build RESTful Web Services and RESTful Java applications. It is a fully certified and portable implementation of the JAX-RS specification.

For this example, we shall show you how to develop a Hello world REST Web application with RESTEasy.

These are the tools we are going to use on a Windows 7 platform:

  • JDK 1.7
  • Maven 3.1.0
  • Eclipse 4.3 Kepler
  • RESTEasy 3.0.4.Final

Because we are going to use Maven to build our project we shall use the Eclipse Maven plugin to create our  project. In Eclipse 4.3 Kepler Maven Plugin comes as standard with the IDE. Finally, we are going to deploy our application on Tomcat, creating a dedicated WAR file.

1. Create a new Maven project

Go to File -> Project ->Maven -> Maven Project.

new-maven-project-

In the “Select project name and location” page of the wizard, make sure that “Create a simple project (skip archetype selection)” option is checked, hit “Next” to continue with default values.

skip-archetype

In the “Enter an artifact id” page of the wizard, you can define the name and main package of your project. We will set the “Group Id” variable to "com.javacodegeeks.enterprise.rest.resteasy" and the “Artifact Id” variable to "JAXRS-RESTEasy". The aforementioned selections compose the main project package as "com.javacodegeeks.snippets.enterprise.rest.jersey.JAXRS-RESTEasy" and the project name as "JAXRS-RESTEasy". Hit “Finish” to exit the wizard and to create your project.

project-configuration

The basic Maven project structure  consists of the following folders:

  • /src/main/java folder, that contains source files for the dynamic content of the application,
  • /src/test/java folder contains all source files for unit tests,
  • /src/main/resources folder contains configurations files,
  • /target folder contains the compiled and packaged deliverables,
  • the pom.xml is the project object model (POM) file. The single file that contains all project related configuration.

In our example we are going to use Tomcat to deploy our Web Service. So we need to export out Project in WAR format. As we’ve discussed in JAX-WS Web Services On Tomcat , there are many ways you can generate the WAR file from a Web Application, but we are going to use our IDE for that. So, first of all we need to convert our simple Java project to a Dynamic Web Application. Generating the WAR file is not the only reason you should convert your project, as you can use many Java EE tools that Eclipse offers.

2. Change Project Facet

Go to the Package Explorer and Right Click on the Project. Go to “Properties”. In the menu on the left go to “Project Facets”, click on the link “Convert to faceted form…”

facets

In the next Window Select “Java” and “Dynamic Web Module”:

webapp-facet

You may also click on “Further configuration available…” link and select ” Generate web.xml deployment descriptor” and “WebContent” as the content directory. Click OK. The click Apply and OK to close the “Properties” window:

futher-config

This will convert your Project to a Dynamic Web Module with an auto generated “web.xml” file. This is the project structure

project-structure

3. Resolve project dependencies in pom.xml

Go to the Package Explorer, navigate to “pom.xml” file and paste the following code. This will obtain the RESTEasy framework libraries (resteasy-jaxrs) :

<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.javacodegeeks.enterprise.rest.resteasy</groupId>
	<artifactId>JAXRS-RESTEasy</artifactId>
	<version>0.0.1-SNAPSHOT</version>

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

	<dependencies>

		<dependency>
			<groupId>org.jboss.resteasy</groupId>
			<artifactId>resteasy-jaxrs</artifactId>
			<version>3.0.4.Final</version>
		</dependency>
	</dependencies>
</project>

4. REST Service

Go to the Package Explorer, under “Java Resources/src/main/java” and create a new Package “com.javacodegeeks.enterprise.rest.resteasy“. In this package we are going to create our JAX-RS Service Endpoint.

RESTEasyHelloWorldService.java:

package com.javacodegeeks.enterprise.rest.resteasy;

import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response;

@Path("/RESTEasyHelloWorld")
public class RESTEasyHelloWorldService {

	@GET
	@Path("/{pathParameter}")
	public Response responseMsg( @PathParam("pathParameter") String pathParameter,
			@DefaultValue("Nothing to say") @QueryParam("queryParameter") String queryParameter) {

		String response = "Hello from: " + pathParameter + " : " + queryParameter;

		return Response.status(200).entity(response).build();
	}
}

There are some thing to notice here:

  • We use @Path("/RESTEasyHelloWorld") annotation in the class definition. This means that RESTEasyHelloWorldService REST service can be reached in the URL .../RESTEasyHelloWorld".
  • In that URL, all GET requests are going to be handled by responseMsg method which is annotated with @GET.
  • In this example we explore two ways to pass parameters in a GET request in REST services. One of them is URI path parameters. We define this parameter with @Path("/{pathParameter}") annotation on responseMsg method. For example, to pass “JavaCodeGeeks” as the value of a path parameter, called pathParameter, we should follow .../RESTEasyHelloWorld/JavaCodeGeeks URL. Now, to parse that parameter we have to declare an argument to the method that will handle the request, in our case that is responseMsg. The way to parse path parameters is by using @PathParam annotation in the argument of the method. In this case the parameter will be parsed as a String. If you try to follow .../RESTEasyHelloWorld URL you will get HTTP Status 405 - Method Not Allowed, as responseMsg will only handle requests in the form of .../helloWorldREST/{any_value}
  • The second way to pass parameter is Query parameters. For example, to pass “Enjoy” as a value of a query parameter, called queryParameter, one should follow .../RESTEasyHelloWorld/{any_value}?queryParameter=Enjoy URL. Now, to parse that parameter we have to declare an argument to the method that will handle the request, in our case that is responseMsg. The way to parse query parameters is by using @QueryParam annotation in the argument of the method. In this case the parameter will be parsed as a String. If you try to follow .../RESTEasyHelloWorld/{any_value} the queryParameter parameter cannot be parsed and you would get a HTTP 400 (Client Error) error. This is why you can use @DefaultValue, to define a default value for the parameter and thus the service will be always available even if the request URI does not contain the corresponding query string.
  • If all parameters are parsed correctly, the URI path parameter will be available to  responseMsg through pathParameter variable, and query parameter will be available to responseMsg through queryParameter variable.

@QueryParam and @PathParam can only be used on the following Java types:

  • All primitive types except char
  • All wrapper classes of primitive types except Character
  • Have a constructor that accepts a single String argument
  • Any class with the static method named valueOf(String) that accepts a single String argument
  • Any class with a constructor that takes a single String as a parameter
  • List<T>, Set<T>, or SortedSet<T>, where T matches the already listed criteria. Sometimes parameters may contain more than one value for the same name. If this is the case, these types may be used to obtain all values.

5. web.xml

In our “web.xml” file, we register “org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher“ as our servlet container. We also register org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap. The ResteasyBootstrap listener is responsible for initializing some basic components of RESTeasy as well as scanning for annotation classes you have in your WAR file. It receives configuration options from <context-param> elements of the “web.xml” file. This configuration variable must be set if your servlet-mapping for the Resteasy servlet has a url-pattern other than /*, as shown in the following code. In our case we use two of these parameters:

  • resteasy.servlet.mapping.prefix: In this parameter we define the URI prefix of our Service. This should take the same value as servlet-mapping property.
  • resteasy.scan : If set true, this will tell ResteasyBootstrap to automatically search for REST Services Implementation, both @Provider and JAX-RS resource classes (@Path, @GET, @POST etc…) and register them.

web.xml:

<?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"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>JAXRS-RESTEasy</display-name>

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

	<!-- Auto scan REST service -->
	<context-param>
		<param-name>resteasy.scan</param-name>
		<param-value>true</param-value>
	</context-param>

	<!-- this should be the same URL pattern as the servlet-mapping property -->
	<context-param>
		<param-name>resteasy.servlet.mapping.prefix</param-name>
		<param-value>/rest</param-value>
	</context-param>

	<listener>
		<listener-class>
			org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
			</listener-class>
	</listener>

	<servlet>
		<servlet-name>resteasy-servlet</servlet-name>
		<servlet-class>
			org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
		</servlet-class>
	</servlet>

</web-app>

8. Set Deployment Assembly

In order to make the appropriate libraries available to Tomcat, in the /WEB-INF/lib folder when extracting the WAR file, go to the Package Explorer, Right click on the Project -> Properties -> Deployment Assembly -> Click Add:

deployment-assembly

On the next window click on “Java Build Path Entries” and click “Next”

build-path-entries

The select “Maven Dependencies” :

maven-dependencies

And click “Finish”. Now when you export the WAR file, all of these libraries will be placed in the /WEB-INF/lib folder and thus they become visible to Tomcat.

9. Export WAR file

Now, go to the Package explorer and Right Click on the Project -> Export -> WAR file :

export-war-files

After exporting the WAR file you have to copy it to CATALINA_BASE/webapps folder. There are quite a few ways to create the WAR file. You can use MavenAnt, or even the jar command line tool.

Now you can start Tomcat. Then put the following URL in your Web Browser :

http://localhost:8080/JAXRS-RESTEasy/rest/RESTEasyHelloWorld/JavaCodeGeeks?queryParameter=Enjoy%20RESTEasy

This is what you will get:

browser

This was a RESTEasy Hello World Example. Download the Eclipse Project of this example : JAXRS-RESTEasy.zip

10. Alternative REST Service Registration

You can configure Java API for RESTful Web Services (JAX-RS) applications in multiple ways depending on your needs. To take advantage of the Java Platform, Enterprise Edition (Java EE)  functionality, you can use the annotation scanning capabilities, like we did in the example above. By using annotation scanning, you can omit a JAX-RS javax.ws.rs.core.Application subclass or have a minimally defined javax.ws.rs.core.Application subclass. You can optionally add javax.ws.rs.core.Application subclasses to your application and then add the URL patterns required using either the javax.ws.rs.ApplicationPath annotation or a web.xml servlet definition.

Here we create a subclass of javax.ws.rs.core.Application.

MyRESTApplication.java:

package com.javacodegeeks.enterprise.rest.resteasy;

import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.core.Application;

public class MyRESTApplication  extends Application {

	private Set<Object> singletons = new HashSet<Object>();

	public MyRESTApplication() {
		singletons.add(new RESTEasyHelloWorldService());
	}

	@Override
	public Set<Object> getSingletons() {
		return singletons;
	}
}

In our Application class we dedine a Set that will hold all the root resource and provider classes. The default lifecycle for resource class instances is per-request. The default lifecycle for providers is singleton. If you create your own Provider class using @Provider annotation, you should also mark them with @Singleton annotation. In our case we just need to add a new RESTEasyHelloWorldService instance to this set.

And then we need to modify the web.xml file accordingly. As you will notice we do not need to add a listener or enable the auto scan service feature as we define our own application implementation as a parameter in the servlet definition.

web.xml:

<?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"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>JAXRS-RESTEasy</display-name>

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

	<!-- this should be the same URL pattern as the servlet-mapping property -->
	<context-param>
		<param-name>resteasy.servlet.mapping.prefix</param-name>
		<param-value>/rest</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.javacodegeeks.enterprise.rest.resteasy.MyRESTApplication</param-value>
		</init-param>
	</servlet>

</web-app>

This the Eclipse project of this example : JAXRS-RESTEasy-CustomApplication.zip

Nikos Maravitsas

Nikos has graduated from the Department of Informatics and Telecommunications of The National and Kapodistrian University of Athens. During his studies he discovered his interests about software development and he has successfully completed numerous assignments in a variety of fields. Currently, his main interests are system’s security, parallel systems, artificial intelligence, operating systems, system programming, telecommunications, web applications, human – machine interaction and mobile development.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Dan
Dan
7 months ago

I know this is quite an old article so I don’t imagine this might get any response, but I’d be over the moon if someone did end up responding to my question. The article recommends to deploy to Tomcat. however I decided to try this with Wildfly instead and I get no text response, nothing, no error either. Just wondering if there might some reason why? I’ve tried many different ways of configuring the web.xml but none work, I either get a 404 not found exception or no response. Many thanks for the article, I appreciate the work that has… Read more »

Back to top button