【问题标题】:Annotation based Spring / JAX-RS integration with no web.xml基于注释的 Spring / JAX-RS 集成,没有 web.xml
【发布时间】:2015-03-02 12:38:55
【问题描述】:

我正在尝试制作一个没有 web.xml 的 Servlet 3.0 REST 服务器,即仅依赖于 java 类和注释。我不确定如何同时使用 Spring 和 servlet 映射注册 Resource 类。

我目前有:

public class ApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer
{
    @Override
    protected Class<?>[] getRootConfigClasses()
    {
        return new Class<?>[]{RootConfiguration.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses()
    {
        return new Class<?>[]{RestServletConfiguration.class};
    }

    @Override
    protected String[] getServletMappings()
    {
        return new String[] {"/*"};
    }
}


@Configuration
@ComponentScan({"com.my.spring.beans", 
               "com.my.spring.services"})
public class RootConfiguration 
{
}

@Configuration
@ComponentScan("com.my.resource.classes")
public class RestServletConfiguration
{
}

当我启动应用程序时,spring bean 已正确连接,但我不确定如何正确设置 JAX-RS servlet 过滤器。我目前正在使用 Jersey,并且无法在网上找到很多关于在不使用 web.xml 的情况下将 Jersey 与 Spring 集成的信息。

有人知道如何以这种方式将 Jersey 与 Spring 集成吗?

【问题讨论】:

    标签: java spring jersey jax-rs servlet-3.0


    【解决方案1】:

    您可以以无 XML 模式集成 Spring 和 Jersey。

    您需要扩展类com.sun.jersey.spi.spring.container.servlet.SpringServlet。例如:

    package org.test;
    
    import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
    import javax.servlet.annotation.WebInitParam;
    import javax.servlet.annotation.WebServlet;
    
    @WebServlet(urlPatterns = {"/rest/*"}, initParams = {
        @WebInitParam(name = "com.sun.jersey.config.property.packages",
                value = "org.test.rest")})
    public class JerseyServlet extends SpringServlet {
    
    }
    

    实际上,它是一个servlet。参数com.sun.jersey.config.property.packages 表示扫描资源的位置(带有注释@Path 的类)。

    以下代码为资源示例:

    package org.test.rest;
    
    import javax.ws.rs.GET;
    import javax.ws.rs.Path;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.test.service.DummyService;
    
    @Path("test")
    @Component
    public class TestResource {
    
        @Autowired
        private DummyService service;
    
        @GET
        public String test() {
            return service.sayHello();
        }
    
    }
    

    这样的资源需要Spring扫描依赖注入。例如:

    package org.test.rest;
    
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    @ComponentScan("org.test.rest")
    public class RestConfiguration {
    
    }
    

    并且这个配置可以被初始化类加载。例如:

    package org.test;
    
    import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
    import org.test.rest.RestConfiguration;
    import org.test.service.ServiceConfiguration;
    
    public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
        @Override
        protected Class<?>[] getRootConfigClasses() {
            return new Class<?>[]{ServiceConfiguration.class, RestConfiguration.class};
        }
    
        @Override
        protected Class<?>[] getServletConfigClasses() {
            return new Class<?>[]{};
        }
    
        @Override
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
    
    }
    

    也许你想看看pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>org.test</groupId>
        <artifactId>jersey-spring</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>war</packaging>
    
        <name>jersey-spring</name>
    
        <properties>
            <endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>4.1.4.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>4.1.4.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-web</artifactId>
                <version>4.1.4.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>com.sun.jersey.contribs</groupId>
                <artifactId>jersey-spring</artifactId>
                <version>1.18.3</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-context</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-web</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-core</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-beans</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aop</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>javax</groupId>
                <artifactId>javaee-web-api</artifactId>
                <version>7.0</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.1</version>
                    <configuration>
                        <source>1.7</source>
                        <target>1.7</target>
                        <compilerArguments>
                            <endorseddirs>${endorsed.dir}</endorseddirs>
                        </compilerArguments>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-war-plugin</artifactId>
                    <version>2.3</version>
                    <configuration>
                        <failOnMissingWebXml>false</failOnMissingWebXml>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-dependency-plugin</artifactId>
                    <version>2.6</version>
                    <executions>
                        <execution>
                            <phase>validate</phase>
                            <goals>
                                <goal>copy</goal>
                            </goals>
                            <configuration>
                                <outputDirectory>${endorsed.dir}</outputDirectory>
                                <silent>true</silent>
                                <artifactItems>
                                    <artifactItem>
                                        <groupId>javax</groupId>
                                        <artifactId>javaee-endorsed-api</artifactId>
                                        <version>7.0</version>
                                        <type>jar</type>
                                    </artifactItem>
                                </artifactItems>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    【讨论】:

    • servlet 映射正在工作,但使用的资源对于任何自动装配的字段都有空值;大概是因为它是 Spring 创建的 Resource 的不同实例。
    • 比如我在TestResource的test()方法中放了一个断点,那么service就是null。
    • 应用初始化程序中的 getServletConfigClasses() 方法应该是什么?
    • 另外,JerseyServlet 注解中的 urlPatterns 值是否应该与 servlet 初始化程序的 getServletMappings() 方法中的值匹配?
    • 资源中的注入字段?我也很好用。我正在使用 Spring 4.1.4.RELEASE。顺便说一句,我正在使用 com.sun.jersey.contribs::jersey-spring::1.18.3 但不包括这个的依赖项。
    猜你喜欢
    • 2014-10-22
    • 2019-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2018-01-01
    相关资源
    最近更新 更多