<chapter id="RESTEasy_Spring_Integration">
    <title>Spring Integration</title>
    <para>RESTEasy integrates with Springframework in various forms. In this chapter we introduce different methods to
        integrate Springframework with RESTEasy.
    </para>
    <section id="BasicIntegration">
        <title>Basic Integration</title>
        <para>For Maven users, you must use the <code>resteasy-spring</code> artifact. And here is the dependency you
            should use:
        </para>
        <programlisting><![CDATA[<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-spring</artifactId>
    <version>3.15.1.Final</version>
</dependency>]]></programlisting>
        <para>
            RESTEasy comes with its own <code>ContextLoaderListener</code> that registers a RESTEasy specific
            <code>BeanPostProcessor</code>
            that processes JAX-RS annotations when a bean is created by a <code>BeanFactory</code>. And it will
            automatically scan for <code>@Provider</code> and JAX-RS resource annotations on your
            bean class and
            register them as JAX-RS resources.
        </para>
        <para>Here is the content that you should add into your <code>web.xml</code> file:
        </para>
        <programlisting><![CDATA[<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>]]></programlisting>
        <para>
            Please note that the <code>SpringContextLoaderListener</code> must be declared after <code>
            ResteasyBootstrap
        </code> as it
            uses
            <code>ServletContext</code>
            attributes initialized by it.
        </para>
        <para>
            And you can configure the Springframework to scan for the JAX-RS resources and beans in a Spring
            configuration file. The content of the file is shown as follow:
        </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"
       xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.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.springbasic">
        <context:include-filter type="annotation" expression="javax.ws.rs.Path"/>
    </context:component-scan>
    <context:annotation-config/>

</beans>]]></programlisting>
        <para>
            Let's say the above file is named <code>resteasy-spring-basic.xml</code>, then in your <code>web.xml</code> the
            can be configured like this:
        </para>
        <programlisting><![CDATA[<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:resteasy-spring-basic.xml</param-value>
</context-param>]]></programlisting>
        <para>In addition, you need to configure your RESTEasy servlet in <code>web.xml</code>. Here is the example:
        </para>
        <programlisting><![CDATA[<servlet>
    <servlet-name>Resteasy</servlet-name>
    <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Resteasy</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>]]></programlisting>
        <para>Instead of using <code>HttpServletDispatcher</code> for deployment, you can also use the <code>
            FilterDispatcher
        </code> in <code>web.xml</code>:
        </para>
        <programlisting><![CDATA[<filter>
    <filter-name>resteasy-filter</filter-name>
    <filter-class>
        org.jboss.resteasy.plugins.server.servlet.FilterDispatcher
    </filter-class>
</filter>]]></programlisting>
        <para>To see a complete example of the above basic usage, please check the <ulink
                url="https://github.com/resteasy/resteasy-examples/tree/master/resteasy-spring-basic">Basic Example
        </ulink> we provided.
        </para>
    </section>
    <section id="CustomizedConfiguration">
        <title>Customized Configuration</title>
        <para>
            If you do not want to use the <code>SpringContextLoaderListener</code> provided by RESTEasy, and want to
            create your bean factories, then you can manually
            register the RESTEasy <code>BeanFactoryPostProcessor</code> by creating an instance of the RESTEasy
            <code>SpringBeanProcessor</code>.
        </para>
        <para>And you must configure the <code>RestasyBootstrap</code> into the scope to create the <code>
            ResteasyDeployment
        </code> so the relative
            classes can be fetched from <code>ServletContext</code>.
        </para>
        <para>
            There is also a
            <code>SpringBeanProcessorServletAware</code>
            class that implements the <code>ServletContextAware</code> interface provided by Springframework.
            The <code>SpringBeanProcessorServletAware</code> can be used to fetch the
            <code>Registry</code>
            and <code>ResteasyProviderFactory</code> from the <code>ServletContext</code>.
        </para>
        <para>To demonstrate the above process, we have also provide an example. Please check the
            <ulink url="https://github.com/resteasy/resteasy-examples/tree/master/resteasy-spring-customized">Spring and
                Resteasy Customized Example
            </ulink>
            we provided.
        </para>
        <para>
            Our Spring integration supports both singletons and the "prototype" scope. RESTEasy handles injecting
            <code>@Context</code>
            references. Constructor injection is not supported though. Also, with the "prototype" scope,
            RESTEasy will inject any <code>@*Param</code> annotated fields or setters before the request is dispatched.
        </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 <code>ProxyFactoryBean</code>. If you
            are using
            auto-proxied beans, you will be ok.
        </para>
    </section>
    <section id="SpringMVC">
        <title>Spring MVC Integration</title>
        <para>
            RESTEasy can also integrate with the Spring <code>DispatcherServlet</code>. The advantages of using this are
            that you
            have a simpler <code>web.xml</code> 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 <code>ModelAndView</code> objects as return
            arguments from
            <code>@GET</code>
            resource methods. Setup requires you using the Spring <code>DispatcherServlet</code> in your <code>web.xml
        </code> file, as well
            as importing the <code>springmvc-resteasy.xml</code> file into your base Spring beans xml file. Here's an
            example
            <code>web.xml</code>
            file:
        </para>
        <programlisting><![CDATA[<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 <code>springmvc-resteasy.xml</code> 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 <code>resteasy.deployment</code> bean which
            is an
            instance
            of <code>ResteasyDeployment</code>. 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>
    </section>
    <section 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>Note that RESTEasy parameters like resteasy.scan.resources may be set in a variety
        of ways. See <xref linkend="config_mechanisms"/> for more information about application configuration.</para>
        <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>
    </section>
    <section>
        <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><![CDATA[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>
    </section>
    <section>
        <title>Undertow Embedded Spring Container</title>
        <para>
            We provide a undertow-based embedded spring container module, called "resteasy-undertow-spring". To use it,
            you need to add the following additional dependencies into your project:
        </para>
        <programlisting><![CDATA[<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-undertow</artifactId>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>org.jboss.resteasy</groupId>
  <artifactId>resteasy-undertow-spring</artifactId>
  <scope>test</scope>
</dependency>]]></programlisting>
        <para>In the "resteasy-undertow-spring" module, we have a embedded server class called
            "UndertowJaxrsSpringServer". In its "undertowDeployment(...)" method, it will accept the spring context
            configuration file:
        </para>
        <programlisting><![CDATA[public DeploymentInfo undertowDeployment(String contextConfigLocation, String mapping)
]]></programlisting>
        <para>
            We can provide a minimal spring config like the following:
        </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
        ">
    <context:component-scan base-package="org.jboss.resteasy.springmvc.test"/>
    <context:annotation-config/>
    <import resource="classpath:springmvc-resteasy.xml"/>
</beans>]]></programlisting>
        <para>In above configuration, the "springmvc-resteasy.xml" in the classpath is provided by the "resteasy-spring"
            module by default. Let's name the above configuration file with "spring-servlet.xml", and the following code
            will include it and setup the UndertowJaxrsSpringServer and start it:
        </para>
        <programlisting><![CDATA[UndertowJaxrsSpringServer server = new UndertowJaxrsSpringServer();
server.start();

DeploymentInfo deployment = server.undertowDeployment("classpath:spring-servlet.xml", null);
deployment.setDeploymentName(BasicSpringTest.class.getName());
deployment.setContextPath("/");
deployment.setClassLoader(BasicSpringTest.class.getClassLoader());

server.deploy(deployment);]]></programlisting>
        <para>Above is the code example to setup and start UndertowJaxrsSpringServer. To see a complete example, please
            check the <ulink
                    url="https://github.com/resteasy/resteasy-examples/tree/master/resteasy-springMVC">
                resteasy-springMVC
            </ulink> as demo app.
        </para>
    </section>
    <section>
        <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 <code><![CDATA[resteasy-jboss-modules-<version>.zip]]></code>,
            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
            <![CDATA[modules/system/layers/base/org/jboss/resteasy/resteasy-spring/main/bundled/resteasy-spring-jar]]>.
        </para>
    </section>
</chapter>
