我正在尝试使用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"); } }
重要提示: 看来最新版本的Spring Boot中没有这个问题。但是,当您要使用Spring Boot和Jersey创建应用程序时,此答案的内容仍可以用作指导。
可执行jar的布局在Spring Boot 1.4.1中已更改:现在将应用程序的依赖项打包在BOOT-INF/lib而不是中lib,并且将应用程序自己的类打包在BOOT- INF/classesjar的根中。它影响泽西岛:
BOOT-INF/lib
lib
BOOT- INF/classes
Jersey类路径扫描限制 可执行jar布局的更改意味着,Jersey的类路径扫描中的限制现在会影响可执行jar文件以及可执行war文件。要变通解决此问题,您希望Jersey扫描的类应打包在一个jar中,并作为一个依赖项包含在中BOOT- INF/lib。然后,应将Spring Boot启动器配置为在启动时解压缩这些jar,以便Jersey可以扫描其内容。
Jersey类路径扫描限制
可执行jar布局的更改意味着,Jersey的类路径扫描中的限制现在会影响可执行jar文件以及可执行war文件。要变通解决此问题,您希望Jersey扫描的类应打包在一个jar中,并作为一个依赖项包含在中BOOT- INF/lib。然后,应将Spring Boot启动器配置为在启动时解压缩这些jar,以便Jersey可以扫描其内容。
BOOT- INF/lib
我发现注册类而不是包是可行的。请参阅以下步骤,使用Spring Boot和Jersey创建应用程序。
确保您的pom.xml文件声明spring-boot-starter-parent为父项目:
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
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可以注册类而不是注册软件包:
ResourceConfig
Application
@ApplicationPath
@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); } }
要编译和运行该应用程序,请按照下列步骤操作:
mvn clean compile
mvn package
spring-jersey-1.0-SNAPSHOT.jar
java -jar spring-jersey-1.0-SNAPSHOT.jar
http://localhost:8080/api/greetings
注意1: 请查看Spring Boot文档。有专门针对泽西岛的部分。
注意2: 产生JSON时,请确保您已注册JSON提供程序。ResourceConfig不过应该注意这一点(只需确保依赖项在类路径上)。