草庐IT

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

codeneng 2023-03-28 原文

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>

  • 除了部署描述符之外,到目前为止,您还尝试过什么让一些 bean 由容器管理?有什么努力吗?
  • 我知道 annotationconfigapplicationcontext 用于加载 @Configurable 类来创建/管理 beans。但不知道如何使用 Jersey 来实现这一点。


网络应用程序:

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>

  • 你能分享这个代码吗?例如,例如。 :)
  • 奇迹般有效。谢谢你。
  • AFAIK 仅当您需要需要代理的 Spring 功能(例如 @Transactional)时才需要 @Component 注释。
  • 为了使用 jersey 和 spring,我们必须创建什么样的项目?我尝试创建一个动态 Web 项目,但没有得到任何 pom.xml 文件。我们必须在哪个文件中添加上述依赖项和排除项?
  • 在 Eclipse 中,我使用插件:M2E - Eclipse 的 Maven 集成。然后您可以右键单击您的项目 -> 配置 -> 转换为 Maven 项目。然后你会看到 pom.xml 文件。


老套路:

由于您已经初始化了 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 中的准备运行示例。

  • 1.如何使用您的旧方法。我将在哪个类中创建上下文。我的意思是泽西岛正在扫描带注释的类以注册资源。如何使用上下文组合类。?
  • 2.为什么我应该使用@Component.3.Your链接指向使用applicationContext(beans are created in applicationContext)4.我可以在MyApplication中注册@Configurable Class(包含我的beans)班级。
  • 在这里,您一次接触了太多 Spring 面孔,我绝对不会问这些,因为它超出了主要问题,因为我认为我的回答非常清楚,甚至提供了两种实现 OP 目标的方法。比说我可以做这个或那个更好的是自己尝试并探索结果,如果您在某些时候感到困惑或困惑,请回到这里,如果我收到您的帖子,我将很高兴为您提供支持 :)
  • 我非常感谢您的回答。我会尝试您的建议,如果可行,我会接受。


对于那些尝试使用 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);
    }
}

有关将 Jersey 2 和 Spring 与基于 Java 的配置集成的更多相关文章

  1. ruby-on-rails - 独立 ruby​​ 脚本的配置文件 - 2

    我有一个在Linux服务器上运行的ruby​​脚本。它不使用rails或任何东西。它基本上是一个命令行ruby​​脚本,可以像这样传递参数:./ruby_script.rbarg1arg2如何将参数抽象到配置文件(例如yaml文件或其他文件)中?您能否举例说明如何做到这一点?提前谢谢你。 最佳答案 首先,您可以运行一个写入YAML配置文件的独立脚本:require"yaml"File.write("path_to_yaml_file",[arg1,arg2].to_yaml)然后,在您的应用中阅读它:require"yaml"arg

  2. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  3. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  4. Ruby Sinatra 配置用于生产和开发 - 2

    我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm

  5. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  6. ruby-on-rails - 我如何将 Hoptoad 与 DelayedJob 和 DaemonSpawn 集成? - 2

    我一直很高兴地使用DelayedJob习惯用法:foo.send_later(:bar)这会调用DelayedJob进程中对象foo的方法bar。我一直在使用DaemonSpawn在我的服务器上启动DelayedJob进程。但是...如果foo抛出异常,Hoptoad不会捕获它。这是任何这些包中的错误...还是我需要更改某些配置...或者我是否需要在DS或DJ中插入一些异常处理来调用Hoptoad通知程序?回应下面的第一条评论。classDelayedJobWorker 最佳答案 尝试monkeypatchingDelayed::W

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  9. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

  10. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

随机推荐