我正在尝试使用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");
}
}
答案 0 :(得分:14)
重要说明:在最新版本的Spring Boot中看起来不存在此问题。但是,当您想要使用Spring Boot和Jersey创建应用程序时,此答案的内容仍可用作指南。
Spring Boot 1.4.1中的layout of executable jars has changed:应用程序的依赖项现在打包在BOOT-INF/lib
而不是lib
中,而应用程序自己的类现在打包在BOOT-INF/classes
而不是BOOT-INF/lib
中。罐子的根。它会影响泽西岛:
Jersey classpath scanning limitations
对可执行jar的布局的更改意味着limitation in Jersey’s classpath scanning现在影响可执行jar文件以及可执行war文件。要解决此问题,您希望由Jersey扫描的类应打包在jar中,并作为依赖项包含在
pom.xml
中。然后,Spring Boot启动程序应为configured to unpack those jars on start up,以便Jersey可以扫描其内容。
我发现注册类而不是包工作。请参阅下面使用Spring Boot和Jersey创建应用程序的步骤。
确保您的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>
您还需要以下依赖项:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Spring Boot Maven插件:
GET
出于示例目的,创建使用@Path
注释的Jersey资源类,并定义处理@Path("/greetings")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public Response getGreeting() {
return Response.ok("Hello, World!").build();
}
}
请求的资源方法,生成text/plain
:
@Component
@ApplicationPath("api")
public class JerseyConfig extends ResourceConfig {
@PostConstruct
private void init() {
registerClasses(GreetingResource.class);
}
}
然后创建一个扩展ResourceConfig
或Application
的类来注册Jersey资源并使用@ApplicationPath
对其进行注释。注册类而不是注册包与Spring Boot 1.4.1一起使用:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
最后创建一个Spring Boot类来执行应用程序:
@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);
}
}
如果您想测试此网络服务,可以使用JAX-RS Client API:
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文档。有section dedicated to Jersey。
注2:生成JSON时,请确保您拥有JSON provider registered。 ResourceConfig
应该注意这一点(只需确保依赖关系在类路径上)。
答案 1 :(得分:6)
虽然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()));
注意:请查看org.glassfish.jersey.server.internal.scanning.AnnotationAcceptingListener
的来源。这是库存解决方案,您可以看到它执行相同的操作:它会扫描使用@Path
或@Provider
注释的类(但由于扫描机制损坏,无法找到任何内容)。 / p>
<强>更新强>
我有一个自定义配置,它没有扩展ResourceConfig,但是将它的实例作为bean返回。
如果您查看官方Spring example,可以将上面的代码插入JerseyConfig()
构造函数(而不是两个register(...)
调用)。唯一的区别是,您只需在构造函数中调用config.registerClasses(...)
,而不是调用registerClasses(...)
。
答案 2 :(得分:0)
我认为您应该使用@Configuration
而不是@Component
对document.getElementById("parent").addEventListener("keyup", function (event){
if(event.target.className == 'inp') {
//your code
}
else{ //for other inner elements
event.preventDefault(); //prevents the default action
event.stopPropagation(); //stop bubbling up
}
}
进行注释。