将 Jersey 2 和 Spring 与基于 Java 的配置集成

Integrating Jersey 2 and Spring with Java Based Configuration

我正在使用 Jersey 2.10 和 jersey-spring3 和 Spring 4。
我想在球衣资源以及其他地方实现 DI(基本服务),并希望通过 Java 配置创建 Spring Bean。

目前,我无法找到任何方法来做到这一点。
知道怎么做吗?

我的 web.xml 看起来像这样

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
<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>


网络应用程序:

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
<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>

基于 Java 的配置:

1
2
3
4
5
6
7
@Configuration
public class ApplicationConfiguration {
  @Bean
  HelloService helloService () {
    return new HelloServiceImpl();
  }
}

和简单的控制器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Component
@Path("/helloController")
public class HelloController {

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


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

用于测试:

localhost:8080/[AppName]/helloController/hello

记住要排除旧的 Spring 依赖项,否则可能会产生一些冲突。您可以按照下面的示例或通过 DependencyManagement 执行此操作。

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
<dependencies>

    <!-- Jersey -->

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

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

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

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

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

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

</dependencies>


老套路:

由于您已经初始化了 ContextLoaderListener,一个简单的技巧是使用 WebApplicationContext 在任何应用程序点检索您的 bean:

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

泽西支持:

或者你可以使用基于注解的发现,因为 Jersey 已经支持 Spring DI。您必须在主应用程序入口点下注册您的 bean。在下面的示例中,该入口点将是 some.package.MyApplication,应该作为 servlet 容器的 <init-param> 提供:

1
2
3
4
5
6
7
8
9
<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>

在你的应用程序中注册你的bean:

1
2
3
4
5
6
7
8
9
10
11
12
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);
    // ...
  }
}

在这里,您可以查看 Jersey Git repo 中的准备运行示例。


对于那些尝试使用 Java 配置的人:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    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();

}

这是我从各种教程中发现的。结合其他答案,您应该有一个完整的示例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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);
    }
}