<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>
    <para>
        <emphasis role="bold">IMPORTANT:</emphasis> As of RESTEasy 5.0.0 the Spring integration has moved to a new
        project, group id and version. The new group id is <code>org.jboss.resteasy.spring</code>. Currently the
        artifact id's have not changed.
    </para>
    <para>RESTEasy currently supports Spring version &SPRING-VERSION;</para>
    <section id="BasicIntegration">
        <title>Basic Integration</title>
        <para>For Maven users, you must use the <code>org.jboss.resteasy.spring:resteasy-spring</code> artifact. And here is the dependency you
            should use:
        </para>
        <programlisting><![CDATA[<dependency>
    <groupId>org.jboss.resteasy.spring</groupId>
    <artifactId>resteasy-spring</artifactId>
    <version>${version.org.jboss.resteasy.spring}</version>
</dependency>]]></programlisting>
        <para>
            RESTEasy comes with its own <code>ContextLoaderListener</code> that registers a RESTEasy specific
            <code>BeanPostProcessor</code>
            that processes &REST-API; annotations when a bean is created by a <code>BeanFactory</code>. And it will
            automatically scan for <code>@Provider</code> and &REST-API; resource annotations on your
            bean class and
            register them as &REST-API; 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 &REST-API; 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="jakarta.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 MVC framework. Generally speaking, &REST-API; can be combined with a
            Spring <code>DispatcherServlet</code> and used in the same web application.
        </para>
        <para>
            An application combined in this way
            allows you to dispatch to either the Spring controller or the &REST-API; resource
            using the same base URL. In addition you can use the Spring <code>ModelAndView</code> objects as return
            arguments from <code>@GET</code> resource methods.
        </para>
        <para>The setup requires you to use 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:

            <programlisting><![CDATA[<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
    <display-name>resteasy-spring-mvc</display-name>

    <servlet>
        <servlet-name>resteasy-spring-mvc</servlet-name>
        <servlet-class>org.jboss.resteasy.springmvc.ResteasySpringDispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:resteasy-spring-mvc-servlet.xml</param-value>
        </init-param>
    </servlet>

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

</web-app>
]]></programlisting>
        </para>
        <para>Then within the <code>resteasy-spring-mvc-servlet.xml</code>, it should 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>
            And then you need to tell Spring the package to scan for your &REST-API; resource classes:
            <programlisting><![CDATA[<context:component-scan base-package="org.jboss.resteasy.examples.springmvc"/>
<context:annotation-config/>]]></programlisting>
            Above is the basic configuration for Spring MVC framework. To see a complete example, please check the
            <ulink url="https://github.com/resteasy/resteasy-examples/tree/master/resteasy-spring-mvc">Spring MVC
                Integration Example
            </ulink>
            we provided.
        </para>
        <para>
            In addition, A <code>jakarta.ws.rs.core.Application</code> subclass can be combined with a Spring
            <code>DispatcherServlet</code>
            and used in the same web application.
        </para>
        <para>
            A servlet definition is required
            for both the Spring <code>DispatcherServlet</code> and the <code>jakarta.ws.rs.core.Application</code> subclass
            in the <code>web.xml</code>,
            as well as RESTEasy Configuration Switch, <code>resteasy.scan.resources</code>. Here is an example
            of the minimum configuration information needed in the <code>web.xml</code>.

            <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 Jakarta RESTful Web Services resource files
    -->
    <context-param>
        <param-name>resteasy.scan.resources</param-name>
        <param-value>true</param-value>
    </context-param>
</web-app>]]></programlisting>
        </para>
        <para>Note that RESTEasy parameters like resteasy.scan.resources may be set in a variety
            of ways. See
            <xref linkend="microprofile_config"/>
            for more information about application configuration.
        </para>
        <para>
            If your web application contains &REST-API; provider classes the RESTEasy Configuration
            Switch, <code>resteasy.scan.providers</code>, will also be needed. And if the url-pattern for the
            &REST-API; Application subclass is other than <code>/*</code> you will need to declare the RESTEasy
            Configuration Switch, <code>resteasy.servlet.mapping.prefix</code>. 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 <code>/*</code>. Here is an example of such a <code>web.xml</code>:

            <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>
        <para>Above are the usages of RESTEasy Spring MVC integration usages.</para>
    </section>
    <section id="SpringUndertow">
        <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-spring-undertow">
                Demo Of Undertow Embedded Spring Container
            </ulink> as usage example.
        </para>
    </section>
    <section id="SpringWebAnnotation">
        <title>Processing Spring Web REST annotations in RESTEasy</title>
        <para>
            RESTEasy also provides the ability to process Spring Web REST annotations (i.e. Spring classes annotated
            with <code>@RestController</code>)
            and handle related REST requests without delegating to Spring MVC. This functionality is currently
            experimental.
        </para>
        <para>
            In order for RESTEasy to be able to process Spring <code>@RestController</code>, you first need to include
            the following
            dependency.
        </para>
        <para>
            <programlisting><![CDATA[<dependency>
    <groupId>org.jboss.resteasy.spring</groupId>
    <artifactId>resteasy-spring-web</artifactId>
    <version>${version.org.jboss.resteasy.spring}</version>
</dependency>]]></programlisting>
        </para>
        <para>
            Currently RESTEasy does not auto-scan for <code>@RestController</code> annotated classes,
            so you need to add all <code>@RestController</code> annotated classes to your <code>web.xml</code> file as
            shown in the following
            example.
        </para>
        <programlisting><![CDATA[<web-app>
   <display-name>RESTEasy application using Spring REST annotations</display-name>

    <context-param>
        <param-name>resteasy.scanned.resource.classes.with.builder</param-name>
        <param-value>org.jboss.resteasy.spi.metadata.SpringResourceBuilder:org.example.Controller1,org.example.Controller2</param-value>
    </context-param>

   ...
</web-app>]]></programlisting>
        <para>
            In the example above, <code>Controller1</code> and <code>Controller2</code> are registered and are expected
            to be annotated with
            <code>@RestController</code>.
        </para>
        <para>
            The list of the currently supported annotations can be found below:
        </para>
        <table frame="topbot">
            <tgroup cols="2" rowsep="1" colsep="1">
                <thead>
                    <row>
                        <entry>Annotation</entry>
                        <entry>Comment</entry>
                    </row>
                </thead>
                <tbody>
                    <row>
                        <entry>@RestController</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@RequestMapping</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@GetMapping</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@PostMapping</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@PutMapping</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@DeleteMapping</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@PatchMapping</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@RequestParam</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@RequestHeader</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@MatrixVariable</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@PathVariable</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@CookieValue</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@RequestBody</entry>
                        <entry/>
                    </row>
                    <row>
                        <entry>@ResponseStatus</entry>
                        <entry>Only supported as a method annotation</entry>
                    </row>
                    <row>
                        <entry>@RequestParam</entry>
                        <entry/>
                    </row>
                </tbody>
            </tgroup>
        </table>
        <para>
            Furthermore, the use of <code>org.springframework.http.ResponseEntity</code> as a return value is
            supported as
            is the use of <code>jakarta.servlet.http.HttpServletRequest</code> and
            <code>jakarta.servlet.http.HttpServletResponse</code>
            as method parameters.
        </para>
        <para>To see an example of the usage, please check the <ulink
                url="https://github.com/resteasy/resteasy-examples/tree/master/resteasy-spring-rest">RESTEasy support of
            Spring REST annotations
        </ulink> sample project we provided.
        </para>
    </section>
    <section id="SpringBootStarter">
        <title>Spring Boot starter</title>
        <para>
            The RESTEasy project has its support for Spring Boot integration. It was originally developed by PayPal team
            and has been donated to RESTEasy community. The project is currently maintained here:
            <ulink url="https://github.com/resteasy/resteasy-spring-boot">RESTEasy Spring Boot Starter Project</ulink>.
        </para>
        <para>
            Here is the usage in brief:
        </para>
        <para>Firstly, add dependency to your Spring Boot application:
            <programlisting><![CDATA[<dependency>
   <groupId>org.jboss.resteasy</groupId>
   <artifactId>resteasy-spring-boot-starter</artifactId>
   <version>${latest_version_of_restesy_spring_boot}</version>
   <scope>runtime</scope>
</dependency>]]></programlisting>
        </para>
        <para>
            And then you can use Spring annotation <code>@Component</code> to register your &REST-API; <code>Application
        </code> class:
            <programlisting><![CDATA[package com.sample.app;

import org.springframework.stereotype.Component;
import jakarta.ws.rs.ApplicationPath;
import jakarta.ws.rs.core.Application;

@Component
@ApplicationPath("/sample-app/")
public class JaxrsApplication extends Application {
}]]></programlisting>
        </para>
        <para>
            Finally, to register &REST-API; resources and providers, just define them as Spring beans, and they will be
            automatically registered. Notice that &REST-API; resources can be singleton or request scoped, while &REST-API;
            providers must be singletons.
        </para>
        <para>To see complete examples, please check the <ulink
                url="https://github.com/resteasy/resteasy-spring-boot/tree/master/sample-app">sample-app
        </ulink> in the project codebase.
        </para>
    </section>
    <section id="SpringUpgradeInWildfly">
        <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>
