我正在尝试使用 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 registered 。 ResourceConfig
不过应该注意这一点(只需确保依赖项位于类路径上)。
关于java - JAX-RS 不适用于 Spring Boot 1.4.1,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39910500/