1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281
|
<chapter id="RESTEasy_Spring_Integration">
<title>Spring Integration</title>
<para>
RESTEasy integrates with Spring 3.0.x. We are interested in other forms of Spring integration, so please help contribute.
</para>
<sect2 id="SpringBeanProcessor">
<title>Basic Integration</title>
<para>For Maven users, you must use the resteasy-spring artifact. Otherwise, the jar is available in the downloaded distribution.
</para>
<programlisting>
<![CDATA[
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-spring</artifactId>
<version>whatever version you are using</version>
</dependency>
]]>
</programlisting>
<para>
RESTEasy comes with its own Spring ContextLoaderListener that registers a RESTEasy specific BeanPostProcessor that processes JAX-RS annotations when a bean is created by a BeanFactory. What does this mean? RESTEasy will automatically scan for @Provider and JAX-RS resource annotations on your bean class and register them as JAX-RS resources.
</para>
<para> Here is what you have to do with your web.xml file</para>
<programlisting>
<web-app>
<display-name>Archetype Created Web Application</display-name>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.jboss.resteasy.plugins.spring.SpringContextLoaderListener</listener-class>
</listener>
...
</web-app>
</programlisting>
<para>
The SpringContextLoaderListener must be declared after ResteasyBootstrap as it uses ServletContext attributes initialized by it.
</para>
<para>
If you do not use a Spring ContextLoaderListener to create your bean factories, then you can manually register the RESTEasy BeanFactoryPostProcessor by allocating an instance of org.jboss.resteasy.plugins.spring.SpringBeanProcessor. You can obtain instances of a ResteasyProviderFactory and Registry from the ServletContext attributes org.jboss.resteasy.spi.ResteasyProviderFactory and org.jboss.resteasy.spi.Registry. (Really the string FQN of these classes). There is also a org.jboss.resteasy.plugins.spring.SpringBeanProcessorServletAware, that will automatically inject references to the Registry and ResteasyProviderFactory from the Servlet Context. (that is, if you have used RestasyBootstrap to bootstrap Resteasy).
</para>
<para>
Our Spring integration supports both singletons and the "prototype" scope. RESTEasy handles injecting @Context references. Constructor injection is not supported though. Also, with the "prototype" scope, RESTEasy will inject any @*Param annotated fields or setters before the request is dispatched.
</para>
<para>
</para>
<para>
NOTE: You can only use auto-proxied beans with our base Spring integration. You will have undesirable affects if you are doing handcoded proxying with Spring, i.e., with ProxyFactoryBean. If you are using auto-proxied beans, you will be ok.
</para>
</sect2>
<sect2 id="SpringMVC">
<title>Spring MVC Integration</title>
<para>
RESTEasy can also integrate with the Spring DispatcherServlet. The advantages of using this are that you have a simpler web.xml file, you can dispatch to either Spring controllers or RESTEasy from under the same base URL, and finally, the most important, you can use Spring ModelAndView objects as return arguments from @GET resource methods. Setup requires you using the Spring DispatcherServlet in your web.xml file, as well as importing the springmvc-resteasy.xml file into your base Spring beans xml file. Here's an example web.xml file:
</para>
<programlisting>
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>Spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
</programlisting>
<para>Then within your main Spring beans xml, import the springmvc-resteasy.xml file</para>
<programlisting>
<![CDATA[
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
">
<!-- Import basic SpringMVC RESTEasy integration -->
<import resource="classpath:springmvc-resteasy.xml"/>
....
]]>
</programlisting>
<para>
You can specify resteasy configuration options by overriding the resteasy.deployment bean which is an instance
of org.jboss.resteasy.spi.ResteasyDeployment. Here's an example of adding media type suffix mappings as well
as enabling the RESTEasy asynchronous job service.
</para>
<programlisting>
<![CDATA[
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
">
<!-- Import basic SpringMVC RESTEasy integration -->
<import resource="classpath:springmvc-resteasy.xml" />
<!-- override the bean definition for deployment -->
<bean id="resteasy.deployment" class="org.jboss.resteasy.spi.ResteasyDeployment" init-method="start" destroy-method="stop">
<property name="asyncJobServiceEnabled" value="true"/>
<property name="mediaTypeMappings">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
</bean>
...
]]>
</programlisting>
</sect2>
<sect2 id="JaxrsWithSpringMVC">
<title>JAX-RS with Spring MVC</title>
<para>
A JAX-RS Application subclass can be combined with a Spring DispatcherServlet
and used in the same web application. An application combined in this way
allows you to dispatch to either the Spring controller or the JAX-RS resource
using the same base URL. In addition you can use the Spring ModelAndView
objects as return arguments from @GET resource methods.
</para>
<para>
Configuring a web application of this type requires a web.xml and spring-servlet.xml
file and a reference to springmvc-resteasy.xml. A servlet definition is required
for both the Spring DispatcherServlet and the Application subclass in the web.xml,
as well as RESTEasy Configuration Switch, resteasy.scan.resources. Here is an example
of the minimum configuration information needed in the web.xml.
</para>
<programlisting>
<![CDATA[
<web-app>
<servlet>
<servlet-name>mySpring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>mySpring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>myAppSubclass</servlet-name>
<servlet-class>org.my.app.EntryApplicationSubclass</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myAppSubclass</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- required RESTEasy Configuration Switch directs auto scanning
of the archive for JAX-RS resource files
-->
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>true</param-value>
</context-param>
</web-app>
]]>
</programlisting>
<para>
If your web application contains JAX-RS provider classes the RESTEasy Configuration
Switch, resteasy.scan.providers, will also be needed. And if the url-pattern for the
JAX-RS Application subclass is other than /* you will need to declare the RESTEasy
Configuration Switch, resteasy.servlet.mapping.prefix. This switch can be declare
either as a context-param or as a servlet init-param. It's value must be the text
that preceeds the /*. Here is an example of such a web.xml.
</para>
<programlisting>
<![CDATA[
<web-app>
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>myAppSubclass</servlet-name>
<servlet-class>org.my.app.EntryApplicationSubclass</servlet-class>
<init-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/resources</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>myAppSubclass</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
<context-param>
<param-name>resteasy.scan.resources</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>resteasy.scan.providers</param-name>
<param-value>true</param-value>
</context-param>
</web-app>
]]>
</programlisting>
<para>
The spring-servlet.xml file must import springmvc-resteasy.xml, however this file does
not need to be present in the archive. In addition a component-scan, declaration of the packages
that contain you application classes is needed. At minimum your spring-servlet.xml should contain
these statements.
</para>
<programlisting>
<![CDATA[
<beans>
<import resource="classpath:springmvc-resteasy.xml"/>
<context:component-scan base-package="org.my.app"/>
</beans>
]]>
</programlisting>
</sect2>
<sect2>
<title>Spring Boot starter</title>
<para>
The RESTEasy project does not include its own component for Spring Boot integration, however PayPal has developed a very interesting <ulink url="https://github.com/paypal/resteasy-spring-boot">RESTEasy Spring Boot starter</ulink> and shared it with the community. You can see below an example of how to use it. Please refer to the <ulink url="https://github.com/paypal/resteasy-spring-boot/blob/master/mds/USAGE.md">relevant documentation</ulink> on GitHub for further information.
</para>
<para>
First, add dependency <literal>com.paypal.springboot:resteasy-spring-boot-starter</literal> to your Spring Boot application. It is recommended to you use <ulink url="http://search.maven.org/#search%7Cga%7C1%7Cg:com.paypal.springboot">the latest version</ulink>.
Second, optionally you can register one or more JAX-RS application classes. To do so, just define it as a Spring bean, and it will be automatically registered. See the example below.
</para>
<programlisting>
package com.sample.app;
import org.springframework.stereotype.Component;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@Component
@ApplicationPath("/sample-app/")
public class JaxrsApplication extends Application {
}
</programlisting>
<para>
Finally, to register JAX-RS resources and providers, just define them as Spring beans, and they will be automatically registered. Notice that JAX-RS resources can be singleton or request scoped, while JAX-RS providers must be singletons.
</para>
</sect2>
<sect2>
<title>Upgrading in WildFly</title>
<para>
<emphasis role="bold">Note.</emphasis>
As noted in <xref linkend="upgrading-wildfly"/>, the RESTEasy distribution comes with a zip file called resteasy-jboss-modules-<version>.zip,
which can be unzipped into the modules/system/layers/base/ directory of WildFly to upgrade to a new version of RESTEasy.
Because of the way resteasy-spring is used in WildFly, after unzipping the zip file, it is also necessary to remove the
old resteasy-spring jar from modules/system/layers/base/org/jboss/resteasy/resteasy-spring/main/bundled/resteasy-spring-jar.
</para>
</sect2>
</chapter>
|