RESTEasy, JBoss project, implementation of the JAX-RS specification. In this tutorial, we show you how to use RESTEasy framework to create a simple REST style web application.

Technologies and Tools used in this article:

  1. RESTEasy 2.2.1.GA
  2. JDK 1.6
  3. Maven 3.0.3
  4. Eclipse 3.6

What’s REST?

Read thisthis and this to understand what’s REST.

1. Directory Structure

Review final directory structure of this tutorial. Just a standard web project structure.

2. Standard Web Project

Create a standard Maven web project structure.

mvn archetype:generate -DgroupId=com.tuts.heomi.netmon -DartifactId=RESTfulExample -DarchetypeArtifactId=maven-archetype-webapp -DinteractiveMode=false

Convert to Eclipse web project.

mvn eclipse:eclipse -Dwtpversion=2.0

3. Project Dependencies

Declares JBoss public Maven repository and “resteasy-jaxrs” in your Maven pom.xml file. That’s all you need to use RESTEasy.

File : pom.xml

<project ...">

	<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>2.2.1.GA</version>
		</dependency>

	</dependencies>
</project>

4. REST Service

A simple REST service. See demo at the end of the article, it should be self-explanatory.

package com.favtuts.rest;

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

@Path("/message")
public class MessageRestService {

	@GET
	@Path("/{param}")
	public Response printMessage(@PathParam("param") String msg) {

		String result = "Restful example : " + msg;

		return Response.status(200).entity(result).build();

	}

}

5. web.xml

Now, configure listener and servlet to support RESTEasy. Read this JBoss documentation for detail explanation.

File : web.xml

<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>

	<!-- Auto scan REST service -->
	<context-param>
		<param-name>resteasy.scan</param-name>
		<param-value>true</param-value>
	</context-param>
	
	<!-- this need same with resteasy servlet url-pattern -->
	<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>
     
	<servlet-mapping>
		<servlet-name>resteasy-servlet</servlet-name>
		<url-pattern>/rest/*</url-pattern>
	</servlet-mapping>

</web-app>

Note
You need to set the “resteasy.servlet.mapping.prefix” if your servlet-mapping for the resteasy servlet has a url-pattern other than “/*“.

In above example, the resteasy servlet url-pattern is “/rest/*“, so you have to set the “resteasy.servlet.mapping.prefix” to “/rest” as well, otherwise, you will hit resource not found error message.

Note

Remember to set “resteasy.scan” to true, so that RESTEasy will find and register your REST service automatically.

7. RUN

Run the web project with Tomcat 7 server, we see the console logs:

Jun 25, 2022 8:50:03 AM org.jboss.resteasy.plugins.server.servlet.ConfigurationBootstrap 
INFO: Adding scanned resource: com.favtuts.rest.MessageRestService
Jun 25, 2022 8:50:03 AM org.apache.catalina.loader.WebappLoader buildClassPath
INFO: Unknown loader jdk.internal.loader.ClassLoaders$AppClassLoader@55054057 class jdk.internal.loader.ClassLoaders$AppClassLoader
Jun 25, 2022 8:50:03 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8181"]
Jun 25, 2022 8:50:03 AM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Jun 25, 2022 8:50:03 AM org.apache.catalina.startup.Catalina start
INFO: Server startup in 846 ms

You see the ResteasyBootstrap listener is activated and the MessageRestService resource is scanned.

If you run the web project with JBoss EAP 7.4, you will see the error: RESTEASY003190: Could not find constructor for class: org.jboss.resteasy.core.AsynchronousDispatcher

09:04:46,387 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 74) MSC000001: Failed to start service jboss.deployment.unit."RESTfulExample.war".undertow-deployment: org.jboss.msc.service.StartException in service jboss.deployment.unit."RESTfulExample.war".undertow-deployment: java.lang.RuntimeException: java.lang.RuntimeException: RESTEASY003190: Could not find constructor for class: org.jboss.resteasy.core.AsynchronousDispatcher

	... 10 more
09:04:49,229 ERROR [org.jboss.as.controller.management-operation] (Controller Boot Thread) WFLYCTL0013: Operation ("deploy") failed - address: ([("deployment" => "RESTfulExample.war")]) - failure description: {"WFLYCTL0080: Failed services" => {"jboss.deployment.unit.\"RESTfulExample.war\".undertow-deployment" => "java.lang.RuntimeException: java.lang.RuntimeException: RESTEASY003190: Could not find constructor for class: org.jboss.resteasy.core.AsynchronousDispatcher
    Caused by: java.lang.RuntimeException: java.lang.RuntimeException: RESTEASY003190: Could not find constructor for class: org.jboss.resteasy.core.AsynchronousDispatcher
    Caused by: java.lang.RuntimeException: RESTEASY003190: Could not find constructor for class: org.jboss.resteasy.core.AsynchronousDispatcher"}}

...

09:04:49,284 INFO  [org.jboss.as.controller] (Controller Boot Thread) WFLYCTL0183: Service status report
WFLYCTL0186:   Services which failed to start:      service jboss.deployment.unit."RESTfulExample.war".undertow-deployment: java.lang.RuntimeException: java.lang.RuntimeException: RESTEASY003190: Could not find constructor for class: org.jboss.resteasy.core.AsynchronousDispatcher
WFLYCTL0448: 1 additional services are down due to their dependencies being missing or failed

If deploying to JBoss 7.x you need to change the scope of your resteasy dependencies to provided. This is because those particular libraries are already included in JBoss as modules. More info., please refer to this question: http://stackoverflow.com/questions/15603662/asynchronousdispatcher-error

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
    <version>2.2.1.GA</version>
    <scope>provided</scope>
</dependency>

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-multipart-provider</artifactId>
    <version>2.2.0.GA</version>
    <scope>provided</scope>
</dependency>

6. Demo

In this example, web request from “projectURL/rest/message/” will match to “MessageRestService“, and “projectURL/rest/message/{any values}” will match to @PathParam parameter.

Test 1 : http://localhost:8080/RESTfulExample/rest/message/favtuts

Test 2 : http://localhost:8080/RESTfulExample/rest/message/hello%20world

Alternative REST Service Registration

In above example, you are register REST service via “ResteasyBootstrap” listener. Here i show you another way,

Create a class and extends javax.ws.rs.core.Application, and add your REST service manually.

package com.favtuts.app;

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

import com.favtuts.rest.MessageRestService;

public class MessageApplication extends Application {
	private Set<Object> singletons = new HashSet<Object>();

	public MessageApplication() {
		singletons.add(new MessageRestService());
	}

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

File : web.xml , no more listener, configure your application class like below :

<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>
		<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.favtuts.app.MessageApplication</param-value>
		</init-param>
	</servlet>

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

</web-app>

Done.

Download Source Code

$ git clone https://github.com/favtuts/java-jax-rs-tutorials.git
$ cd RESTfulExample

Run web project on JBoss EAP 7.4

Test 1 : http://localhost:8080/RESTfulExample/rest/message/favtuts

Test 2 : http://localhost:8080/RESTfulExample/rest/message/hello%20world

References

  1. RESTEasy Framework
  2. RESTEasy installation and configuration
  3. IBM : RESTful Web services: The basics
  4. RESTful Web Services
  5. Wiki : Representational State Transfer
  6. RESTEasy Hello World Example Tutorial

Leave a Reply

Your email address will not be published. Required fields are marked *