小编典典

JAX-RS不适用于Spring Boot 1.4.1

spring-boot

我正在尝试使用Spring Boot版本1.4.1.RELEASE开发一个简单的基于JAX-RS的Web服务。但是得到这个例外-

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");
    }
}

阅读 283

收藏
2020-05-30

共1个答案

小编典典

重要提示: 看来最新版本的Spring Boot中没有这个问题。但是,当您要使用Spring
Boot和Jersey创建应用程序时,此答案的内容仍可以用作指导。


在Spring Boot 1.4.1中更改了JAR的布局

可执行jar布局在Spring Boot 1.4.1中已更改:现在将应用程序的依赖项打包在BOOT-INF/lib而不是中lib,并且将应用程序自己的类打包在BOOT- INF/classesjar的根中。它影响泽西岛:

Jersey类路径扫描限制

可执行jar布局的更改意味着,Jersey的类路径扫描中的限制现在会影响可执行jar文件以及可执行war文件。要变通解决此问题,您希望Jersey扫描的类应打包在一个jar中,并作为一个依赖项包含在中BOOT- INF/lib。然后,应将Spring Boot启动器配置为在启动时解压缩这些jar,以便Jersey可以扫描其内容。

我发现注册类而不是包是可行的。请参阅以下步骤,使用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>

出于示例目的,创建带有批注的Jersey资源类,@Path并定义用于处理GET请求的资源方法,产生text/plain

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

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

然后创建一个扩展ResourceConfigApplication注册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 clean compile
  • 打包应用程序: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文档。有专门针对泽西岛部分

注意2:
产生JSON时,请确保您已注册JSON提供程序ResourceConfig不过应该注意这一点(只需确保依赖项在类路径上)。

2020-05-30