7

I am using Jersey 2.10 and jersey-spring3 and Spring 4. I want to achieve DI(basically services) in jersey resources as well as in other places and want to create Spring Beans through Java Configuration.

Currently,I am not able to find out any way to do this. Any idea how to do this?

my web.xml looks like this

<web-app>
    <display-name>Restful Web Application</display-name>
    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
             org.glassfish.jersey.servlet.ServletContainer 

        </servlet-class>
        <init-param>
            <param-name>
                jersey.config.server.provider.packages
            </param-name>
            <param-value>com.xyz</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/application-context.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>
beinghuman
  • 2,088
  • 7
  • 27
  • 36
  • And except the deployment descriptor, what have you tried so far to get some beans managed by a container? Any efforts? – tmarwen Sep 06 '14 at 15:15
  • I know that annotationconfigapplicationcontext is used to load @Configurable class to create/manage beans.but don't know how to achieve this using Jersey. – beinghuman Sep 06 '14 at 15:19

4 Answers4

9

web-app:

<context-param>
    <param-name>contextClass</param-name>
    <param-value>
      org.springframework.web.context.support.AnnotationConfigWebApplicationContext
  </param-value>
</context-param>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>xxx.xxx.configuration.ApplicationConfiguration</param-value>
</context-param>

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<servlet>
    <servlet-name>SpringApplication</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>xxx.xxx.controllers.HelloController</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>SpringApplication</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

JavaBased Configuration:

@Configuration
public class ApplicationConfiguration {
  @Bean
  HelloService helloService () {
    return new HelloServiceImpl();
  }
}

and simple controller:

@Component
@Path("/helloController")
public class HelloController {

  @Autowired
  @Qualifier("helloService")
  private HelloService helloService ;


   @GET
   @Path("/hello")
   public String hello() {
    helloService.service();
  }
}

for testing:

localhost:8080/[AppName]/helloController/hello

remember about excluding old Spring dependencies you may have some conflicts if you don't. You can do this same as on the example below or through DependencyManagement.

<dependencies>

    <!-- Jersey -->

    <dependency>
        <groupId>org.glassfish.jersey.ext</groupId>
        <artifactId>jersey-spring3</artifactId>
        <version>2.11</version>
        <exclusions>
            <exclusion>
                <artifactId>spring-context</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
            <exclusion>
                <artifactId>spring-beans</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
            <exclusion>
                <artifactId>spring-core</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
            <exclusion>
                <artifactId>spring-web</artifactId>
                <groupId>org.springframework</groupId>
            </exclusion>
            <exclusion>
                <artifactId>jersey-server</artifactId>
                <groupId>org.glassfish.jersey.core</groupId>
            </exclusion>
            <exclusion>
                <artifactId>
                    jersey-container-servlet-core
                </artifactId>
                <groupId>org.glassfish.jersey.containers</groupId>
            </exclusion>
            <exclusion>
                <artifactId>hk2</artifactId>
                <groupId>org.glassfish.hk2</groupId>
            </exclusion>
        </exclusions>
    </dependency>

    <!-- Spring 4 dependencies -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.0.6.RELEASE</version>
    </dependency>

</dependencies>
Marek Raki
  • 3,056
  • 3
  • 27
  • 50
  • can you please share this code? as example, for example. :) – Java Dude Jan 20 '15 at 20:52
  • Works like a charm. Thank you. – Rami Del Toro Sep 13 '15 at 02:16
  • AFAIK the `@Component` annotation is only required if you need Spring functionality that requires proxying, such as `@Transactional`. – herman Nov 27 '15 at 12:23
  • what kind of a project do we have to create in order to use jersey and spring? I tried creating a dynamic web project and i did not get any pom.xml file. in what file do we have to add the above mentioned dependencies and exclusions? – Minions Jan 17 '16 at 16:01
  • In Eclipse I use plugin: 'M2E - Maven Integration for Eclipse'. Then you can right click on your project -> Configure -> Convert to Maven project. Then you will see the pom.xml file. – Marek Raki Jan 17 '16 at 20:01
2

Old Fashioned way:

Since you have already initialized the ContextLoaderListener a simple trick is to use the WebApplicationContext to retrieve your beans at any application point:

WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
SomeBean someBean = (SomeBean) ctx.getBean("someBean");

Jersey Support:

Or you can use the annotation based discovery, since Jersey has already support for Spring DI. You have to register your beans under your main application entry point. That entry point, in below example will be some.package.MyApplication, should be provided as an <init-param> of the servlet container:

<servlet>
  <servlet-name>SpringApplication</servlet-name>
  <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
  <init-param>
    <param-name>javax.ws.rs.Application</param-name>
    <param-value>some.package.MyApplication</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>

Register you beans in your application:

package some.package;

import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.spring.scope.RequestContextFilter;

public class MyApplication extends ResourceConfig {
  public MyApplication () {
    register(RequestContextFilter.class);
    register(SomeBean.class);
    // ...
  }
}

Here you can take a look to a ready to run example from Jersey Git repo.

Steven Benitez
  • 10,936
  • 3
  • 39
  • 50
tmarwen
  • 15,750
  • 5
  • 43
  • 62
  • 1.how to use your old approach.In which class would I create the context.I mean Jersey is scanning the annotated classes to register for resources.How will is use the context composed class.? – beinghuman Sep 06 '14 at 15:43
  • 2.Why should I make my jersey resource Spring Managed resource by using @Component.3.Your link points to the use of applicationContext(beans are created in applicationContext)4.Can I register @ Configurable Class(which contains my beans) in MyApplication Class. – beinghuman Sep 06 '14 at 15:50
  • Here you are touching too multiple Spring faces in a single shot and I absolutely won't ask those because it gets wide out of the main issue and since I assume I maid my answer quite clear and even provided two ways to achieve OP goal. Better than saying can I do this or that is to try it yourself and explore the results, if you are stack or confused at some point, just be back here and personally I will be glad to support you if I catch your post :) – tmarwen Sep 06 '14 at 16:17
  • I really appreciate your answer.I will try what you suggested and then if it works I accept it. – beinghuman Sep 06 '14 at 16:47
1

Here is something that I found starting from various tutorials. Combined with other answers you should have a complete example.

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

public class WebInitializer implements WebApplicationInitializer {
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(AppConfig.class);
        ctx.setServletContext(servletContext);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ctx);
        ServletRegistration.Dynamic servlet = servletContext.addServlet("jersey-serlvet", new SpringServlet());
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}
1

For those trying to do it with Java config:

    public static void main(String[] args) throws IOException {
        HttpServer server = new HttpServer();
        NetworkListener listener = new NetworkListener("grizzly2", "localhost", 2088);
        server.addListener(listener);

        WebappContext ctx = new WebappContext("ctx","/");
        final ServletRegistration reg = ctx.addServlet("spring", new SpringServlet());
        reg.addMapping("/*");
        ctx.addContextInitParameter( "contextClass", "org.springframework.web.context.support.AnnotationConfigWebApplicationContext" );
        ctx.addContextInitParameter( "contextConfigLocation", "com.example.AppConfig" );
        ctx.addListener( "org.springframework.web.context.ContextLoaderListener" );
        ctx.addListener("org.springframework.web.context.request.RequestContextListener");

        ctx.deploy(server);

        server.start();

        System.in.read();

}
gshock
  • 584
  • 7
  • 18