I'm Solomon Duskis, NYC consultant and a Java/J2EE guy. I work at Sungard Consulting Services in NYC. The postings on this site are my own and do not necessarily represent the positions, strategies or opinions of my employer. Solomon is a DZone MVB and is not an employee of DZone and has posted 22 posts at DZone. You can read more from them at their website. View Full User Profile

Integrating JBoss RESTEasy and Spring MVC

10.15.2009
| 100577 views |
  • submit to reddit

Core RESTEasy/Spring MVC artifacts

web.xml

Spring MVC's entry point is the DispatcherServlet. There are two parts in setting up the DispatcherServlet, the first is to map the servlet to the URL pattern which must follow the rules specified in Section 11.2 of Servlet API Specification. The next step is configure the behavior of the the servlet by providing the configuration file which we call 'springmvc-servlet.xml'. By default, DispatcherServlet looks for a configuration file at "WEB-INF/{servlet-name}-servlet.xml" to find it's configuration, but we're going to use a Spring configuration from the classpath so that the configuration can be reused later in our junit test case.

<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>

<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
</servlet>

<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/contacts/*</url-pattern>
</servlet-mapping>



<web-app>

 

All requests will be forwarded to the Spring MVC DispatcherServlet. One can get much more sophisticated, but this is one of the simplest simplest web.xml you can create to integrate with Spring. Note that there isn't any reference here to a RESTEasy servlet. Other JAX-RS/Spring integrations require you to have an implementation specific Servlet to serve XML or JSon and a separate Spring MVC DispatcherServlet mapping to server HTML requests. RESTEasy integrates with DispatcherServlet to allow Spring MVC to direct the URL to either RESTEasy Resources or Spring MVC Controllers.

Next, let's take a look at the Spring MVC configuration.

springmvc-servlet.xml

In our basic project, there are five things we need to do in the springmvc-servlet.xml file.

  1. Register the Spring <context/> namespace
  2. Register the package(s) to scan for Spring MVC annotations.
  3. Configure the context annotation processor.
  4. Import the springmvc-resteasy.xml configuration file which specifies the default RESTEasy/Spring MVC integration Spring beans.
  5. Configure the ViewResolver bean to configure the presentation layer to use JSP.

Let's inspect the springmvc-servlet.xml file and focus on each of the above items. The springmvc-servlet.xml file itself is pretty short and shows off some of the features from Spring 2.5:

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:component-scan base-package="org.jboss.resteasy.examples.springmvc" />
<context:annotation-config />
<import resource="classpath:springmvc-resteasy.xml" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>

Demystifying the Spring Configuration

Spring allows for custom namespaces to reduce the verbosity of the configuration files. We make use of the <context/> namepsace by registering it in lines 3 and 4. Line 6 (component-scan) informs spring about which package(s) we want to scan and create the custom component object instances, such as controllers and service objects. We tell Spring about the packages we're interested in by using the <context:component-scan/> custom namespace and set the base-package attribute with the packages we're interested in (org.jboss.resteasy.examples.springmvc ). Later on, you'll see that we're going to be using two Spring annotations that allow the Spring runtime to glean Dependency Management information directly from the object itself: @Controller and @Service.

Line 7 (annotation-config) tells Spring that our application will be using annotations on how to configure the beans created by the (component-scan) operation of line 6. Spring looks for annotations such as Spring's @Autowired and @Required; JEE's @Resource; and JPA's @PersistenceContext and @PersistenceUnit to describe dependencies between bean instances. annotation-configSpring also looks for life-cycle annotations such as JSR 250's @PostConstruct and @PreDestroy. Our environment requires a dependency between our Controller and Service objects, and the annotation-config declaration will assist us to configure that relationship in Java code.

Line 8 (import) is all the XML that is necessary to configure a RESTEasy environment in Spring MVC. The nice thing about the integration with RESTEasy is that most of the configuration is done for you within an embedded configuration file called springmvc-resteasy.xml.

Lines 9-14 tell Spring how we intend to handle the rendering of our presentation layer. In our case, we want to use JSTL views that translate view names (such as "contact") to a JSP page found in the /WEB-INF/ directory (specifically /WEB-INF/contacts.jsp in our case). For more information about setting up Spring views, take a look at the spring documentation.

Next, let's take a look at how you can mix and match Spring and JAX-RS annotations in a Controller/Resource.



Published at DZone with permission of Solomon Duskis, author and DZone MVB.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

christophe charles replied on Fri, 2009/10/23 - 6:52am

Thanks !

Seb Cha replied on Wed, 2009/11/04 - 12:16pm

Good JAX-RS tutorial !

Tony Childs replied on Sat, 2010/05/01 - 9:58am

Thanks for the great article. There is something I have not been able to figure out, however.

Without Spring integration the RestEasy ConfigurationBootstrap.createDeployment() method adds any RestEasy context params - more specifically "resteasy.media.type.mappings" to map type extensions to MIME types.

Unfortunately, when Spring is integrated, these mappings are not picked up. I have been stepping through the code trying to figure out how I might be able to pass these context params to RestEasy when I noticed you had authored some classes in the Resteasy-Spring integration package, so I thought you might be the best person to ask. What would be the best way to get these mappings to RestEasy?

Thanks, Tony

Tony Childs replied on Sat, 2010/05/01 - 11:02am

After further examination of the startup behavior I managed to figure out a way to get the mappings in there. I copied your springmvc-resteasy.cml file and used it as a template for my own custom file. I then added/changed the folloing lines:

<bean id="jsonType" class="javax.ws.rs.core.MediaType" factory-method="valueOf">
   <constructor-arg value="application/json"/>
</bean>

<bean id="xmlType" class="javax.ws.rs.core.MediaType" factory-method="valueOf">
   <constructor-arg value="application/xml"/>
</bean>

<bean id="resteasy.dispatcher" class="org.jboss.resteasy.core.SynchronousDispatcher"
      depends-on="resteasy.intializer">
   <constructor-arg ref="resteasy.providerFactory"/>
   <property name="mediaTypeMappings">
      <map>
         <entry key="json" value-ref="jsonType"/>
         <entry key="xml" value-ref="xmlType"/>
      </map>
   </property>
</bean>

Suresh Bhaskaran replied on Fri, 2010/08/27 - 7:53pm in response to: christophe charles

Great Article! If any of you run into the following issue: "No mapping found for HTTP request with URI [/main/blog/list] in DispatcherServlet with name 'spring' ERROR org.jboss.resteasy.springmvc.ResteasyHandlerMapping - Resource Not Found: Could not find resource for relative Then all you have to do is modify your spring app context xml file: Add these 2 lines: (I am omitting the cone opening and closing cone brackets, as they do not appear here for some reasons: context:component-scan base-package="com.zyrisinc.googlecheckout.service" bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" property name="order" value="0" bean bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"

Pasta Farian replied on Wed, 2010/09/22 - 2:44pm

Update: I can access it by going to http://localhost:8080/examples-resteasy-springMVC-2.1-SNAPSHOT/contacts but when I try to add a contact, I end up back on http://localhost:8080/contacts which gives me a 404 and apparently no contacts were added. By the way, with Tomcat I needed to add jstl.jar to the runtime. ----- Hi, Great article. Very helpful. I am having trouble running this WAR on Tomcar 6. The WAR deploys without any errors but when I go to http://localhost:8080/contacts I get a HTTP 404. Can anyone deploy this on Tomcat successfully? or do I need to make some changes to the servlet mapping? Thanks.

Clay Press replied on Sun, 2011/10/16 - 11:07pm

Two Years After, this jboss/resteasy/spring/maven tutorial still builds and tests as advertised.  Nice demo.

Will java rest keep pace with the dynamic type competitive alternatives in the POST-sun.com era?  Which decision trumps:  resteasy vs jersey vs spring vs restlet <or> java/c@ vs python/ruby.

Two Years Later, where will java rest be

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.