java - JAX-RS 不适用于 Spring Boot 1.4.1

标签 java maven spring-boot jax-rs

我正在尝试使用 Spring Boot 版本 1.4.1.RELEASE 开发一个简单的基于 JAX-RS 的 Web 服务。然而得到这个异常(exception) -

java.lang.IllegalStateException: No generator was provided and there is no default generator registered
at org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.internalCreate(ServiceLocatorFactoryImpl.java:308) ~[hk2-api-2.5.0-b05.jar:na]
at org.glassfish.hk2.internal.ServiceLocatorFactoryImpl.create(ServiceLocatorFactoryImpl.java:268) ~[hk2-api-2.5.0-b05.jar:na]
at org.glassfish.jersey.internal.inject.Injections._createLocator(Injections.java:138) ~[jersey-common-2.23.2.jar:na]
at org.glassfish.jersey.internal.inject.Injections.createLocator(Injections.java:123) ~[jersey-common-2.23.2.jar:na]
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:330) ~[jersey-server-2.23.2.jar:na]
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:392) ~[jersey-container-servlet-core-2.23.2.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177) ~[jersey-container-servlet-core-2.23.2.jar:na]
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369) ~[jersey-container-servlet-core-2.23.2.jar:na]

这是我的计划详细信息 -

POM.xml 中包含的依赖项 -

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

这是 JerseyConfig 文件 -

package com.test.main;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
import com.test.resources.TutorialResource;

@Component
public class JerseyConfig extends ResourceConfig{
    public JerseyConfig() {
        register(TutorialResource.class);
        packages("com.test.resources");
    }
}

最佳答案

Important: Looks like this issue is not present in most recent versions of Spring Boot. However the content of this answer can still be used as a guide when you want to create an application with Spring Boot and Jersey.

<小时/>

Spring Boot 1.4.1 中 JAR 的布局发生了变化

layout of executable jars has changed在 Spring Boot 1.4.1 中:应用程序的依赖项现在打包在 BOOT-INF/lib 中,而不是 lib 中,并且应用程序自己的类现在打包在 BOOT-INF 中/classes 而不是 jar 的根目录。它影响 Jersey :

Jersey classpath scanning limitations

The change to the layout of executable jars means that a limitation in Jersey’s classpath scanning now affects executable jar files as well as executable war files. To work around the problem, classes that you wish to be scanned by Jersey should be packaged in a jar and included as a dependency in BOOT-INF/lib. The Spring Boot launcher should then be configured to unpack those jars on start up so that Jersey can scan their contents.

我发现注册类而不是包是有效的。请参阅下面使用 Spring Boot 和 Jersey 创建应用程序的步骤。

使用 Spring Boot 和 Jersey 创建 Web 应用程序

确保您的 pom.xml 文件将 spring-boot-starter-parent 声明为父项目:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.4.1.RELEASE</version>
</parent>

您还需要以下依赖项:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

以及 Spring Boot Maven 插件:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

出于示例目的,创建一个带有 @Path 注解的 Jersey 资源类并定义一个资源方法来处理 GET 请求,生成 text/plain :

@Path("/greetings")
public class GreetingResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public Response getGreeting() {
        return Response.ok("Hello, World!").build();
    }
}

然后创建一个扩展 ResourceConfig 的类或Application注册 Jersey 资源并用 @ApplicationPath 进行注释。在 Spring Boot 1.4.1 中注册类而不是注册包:

@Component
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {

    @PostConstruct
    private void init() {
        registerClasses(GreetingResource.class);
    }
}

最后创建一个 Spring Boot 类来执行应用程序:

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

如果您想测试此 Web 服务,可以使用 JAX-RS Client API :

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class GreetingResourceTest {

    @LocalServerPort
    private int port;

    private URI uri;

    @Before
    public void setUp() throws Exception {
        this.uri = new URI("http://localhost:" + port);
    }

    @Test
    public void testGreeting() {

        Client client = ClientBuilder.newClient();
        Response response = client.target(uri).path("api").path("greetings")
                                  .request(MediaType.TEXT_PLAIN).get();

        String entity = response.readEntity(String.class);
        assertEquals("Hello, World!", entity);
    }
}

要编译并运行该应用程序,请按照下列步骤操作:

  • 打开命令行窗口或终端。
  • 导航到 pom.xml 所在的项目根目录。
  • 编译项​​目:mvn cleancompile
  • 打包应用程序:mvn package
  • 查看目标目录。您应该会看到具有以下名称或类似名称的文件:spring-jersey-1.0-SNAPSHOT.jar
  • 切换到目标目录。
  • 执行 JAR:java -jar spring-jersey-1.0-SNAPSHOT.jar
  • 该应用程序应可从 http://localhost:8080/api/greetings 获取。
<小时/>

注释 1: 查看 Spring Boot 文档。有一个section dedicated to Jersey .

注意 2: 生成 JSON 时,请确保您有 JSON provider registeredResourceConfig不过应该注意这一点(只需确保依赖项位于类路径上)。

关于java - JAX-RS 不适用于 Spring Boot 1.4.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39910500/

相关文章:

java - 如何禁用文本字段的自动聚焦

Java - 如何增加 JFileChooser 中文件夹名称的字体?

java - Maven - 在 intelliJ 中正确构建不同语言的模块

java.lang.NoSuchFieldError : INSTANCE in bitpay SDK 错误

java - SpringBoot 应用程序中的每个 @Service 类是否应该实现一个接口(interface)

java - SpringMVC hibernate "MappingNotFoundException"

Java : Genrics - Two similar codes, 一个不起作用

java - spring MVC欢迎程序中Bean配置错误

spring-boot - 关于将Clojure集成到springboot框架中

java - 如何使用两个 URL 映射