aka*_*kr6 2 java jax-rs maven 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]
Run Code Online (Sandbox Code Playgroud)
这是我的计划详情 -
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>
Run Code Online (Sandbox Code Playgroud)
这里是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");
}
}
Run Code Online (Sandbox Code Playgroud)
cas*_*lin 14
重要提示:在最新版本的Spring Boot中看起来不存在此问题.但是,当您想要使用Spring Boot和Jersey创建应用程序时,此答案的内容仍可用作指南.
Spring Boot 1.4.1 中可执行jar的布局已经改变:应用程序的依赖项现在打包BOOT-INF/lib而不是lib,应用程序自己的类现在打包在BOOT-INF/classesjar而不是jar的根目录中.它会影响泽西岛:
对可执行jar的布局的更改意味着Jersey的类路径扫描中的限制现在会影响可执行jar文件以及可执行war文件.要解决此问题,您希望由Jersey扫描的类应打包在jar中并作为依赖项包含在其中
BOOT-INF/lib.然后应将Spring Boot启动程序配置为在启动时解压缩这些jar,以便Jersey可以扫描其内容.
我发现注册类而不是包工作.请参阅下面使用Spring Boot和Jersey创建应用程序的步骤.
确保您的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>
Run Code Online (Sandbox Code Playgroud)
您还需要以下依赖项:
<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>
Run Code Online (Sandbox Code Playgroud)
和Spring Boot Maven插件:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Run Code Online (Sandbox Code Playgroud)
例如,创建一个带有注释的Jersey资源类,@Path并定义一个资源方法来处理GET请求,从而产生text/plain:
@Path("/greetings")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response getGreeting() {
return Response.ok("Hello, World!").build();
}
}
Run Code Online (Sandbox Code Playgroud)
然后创建一个扩展ResourceConfig或Application注册Jersey资源并注释它的类@ApplicationPath.注册类而不是注册包与Spring Boot 1.4.1一起使用:
@Component
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {
@PostConstruct
private void init() {
registerClasses(GreetingResource.class);
}
}
Run Code Online (Sandbox Code Playgroud)
最后创建一个Spring Boot类来执行应用程序:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
Run Code Online (Sandbox Code Playgroud)
如果要测试此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);
}
}
Run Code Online (Sandbox Code Playgroud)
要编译并运行该应用程序,请按照下列步骤操作:
pom.xml.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应该注意这一点(只需确保依赖关系在类路径上).
虽然Jersey无法在新版本的胖启动jar中扫描你的类,但使用Spring类路径扫描工具可以达到同样的效果.这样您就可以扫描包类似于ResourceConfig.packages():
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(Provider.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(Path.class));
config.registerClasses(scanner.findCandidateComponents("your.package.to.scan").stream()
.map(beanDefinition -> ClassUtils.resolveClassName(beanDefinition.getBeanClassName(), config.getClassLoader()))
.collect(Collectors.toSet()));
Run Code Online (Sandbox Code Playgroud)
注意:请看一下源码org.glassfish.jersey.server.internal.scanning.AnnotationAcceptingListener.这是库存解决方案,您可以看到它执行相同的操作:它扫描用@Path或注释的类@Provider(但由于扫描机制损坏而无法找到任何内容).
更新:
我有一个自定义配置,它没有扩展ResourceConfig但返回它的实例作为bean.如果你看一下官方的Spring例子,你可以将上面的代码插入到JerseyConfig()构造函数中(而不是两个register(...)调用).唯一的区别是,不是config.registerClasses(...)简单地调用你只是registerClasses(...)在构造函数中调用.
| 归档时间: |
|
| 查看次数: |
7775 次 |
| 最近记录: |