gpt4 book ai didi

java - Jersey Web 应用程序动态注册资源

转载 作者:行者123 更新时间:2023-11-28 22:07:37 26 4
gpt4 key购买 nike

我有一个 Web 应用程序,它将从 jar 文件动态加载其资源。

我开始使用org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory.createHttpServer设置我自己的服务器并通过 ServiceLoader 加载所有资源并通过 ResourceConfig#register 注册了他们.这工作得很好,但我总是有第二台服务器在运行。

现在我想创建一个简单的应用程序 war 并将其部署在例如 Tomcat 。这个想法是,当加载 war 时,资源也通过 ServiceLoader 加载。然后可用(与独立服务器相同)。

我必须如何重写加载和注册资源以及启动服务器的主类,以便它在 Web 应用程序中运行?

我目前有一个 javax.ws.rs.core.Application定义,在标有 @PostConstruct 的方法中加载资源。虽然这是可行的,但它会根据每个请求进行初始化。

我尝试添加 javax.inject.Singleton到应用程序,但这导致了错误:

java.lang.IllegalStateException: Unable to perform operation: post construct on com.test.server.IntegrationServer
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:392)
at org.jvnet.hk2.internal.SystemDescriptor.create(SystemDescriptor.java:471)
at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:83)
at org.jvnet.hk2.internal.SingletonContext$1.compute(SingletonContext.java:71)
at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture$1.call(Cache.java:97)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at org.glassfish.hk2.utilities.cache.Cache$OriginThreadAwareFuture.run(Cache.java:154)
at org.glassfish.hk2.utilities.cache.Cache.compute(Cache.java:199)
at org.jvnet.hk2.internal.SingletonContext.findOrCreate(SingletonContext.java:122)
at org.jvnet.hk2.internal.Utilities.createService(Utilities.java:2020)
at org.jvnet.hk2.internal.ServiceLocatorImpl.internalGetService(ServiceLocatorImpl.java:766)
at org.jvnet.hk2.internal.ServiceLocatorImpl.getService(ServiceLocatorImpl.java:705)
at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:385)
at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:342)
at org.glassfish.jersey.servlet.WebComponent.<init>(WebComponent.java:392)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:177)
at org.glassfish.jersey.servlet.ServletContainer.init(ServletContainer.java:369)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)

我的方法完全错误吗?或者我如何创建这样一个系统,作为可部署的 war 运行?

* 编辑 *

通过使用 ServletContextListener,我可以解决多个 init 调用,但我的资源没有加载。

所以,我有这样的资源

@Path("test")

公共(public)类 TestResource 实现 MarkerInterface { @得到 @Produces(MediaType.TEXT_PLAIN) @Path("得到") 公共(public)字符串获取(){ 返回“你好”; }}此资源打包在一个 jar 文件中,位于文件系统中。

应用程序现在加载此文件位置并通过 ServiceLoader 加载所有MarkerInterface类并应注册它们。

我有

@WebListener
public class IntegrationServer extends ResourceConfig implements ServletContextListener {

@Override
public void contextInitialized(ServletContextEvent sce) {
LOGGER.info(() -> "CONTEXT INIT");
try {
register(JacksonFeature.class);
// wrapper for the ServiceLoader implementation
this.serviceLoader = new IntegrationServiceLoader();
this.serviceLoader.loadIntegrations(MarkerInterface.class, gce -> {
LOGGER.info(() -> "Adding " + gce.getClass() + " to Server");
register(gce.getClass());
});
}
catch (IOException e) {
LOGGER.log(Level.SEVERE, e, () -> "Failed to init integration server");
}
}

我在日志中看到注册输出,将其部署为 server.war在 tomcat 上,但是当我调用 http://localhost:8080/server/test/get我收到 HTTP 状态 404 - 未找到。

我的 web.xml 看起来像

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>Jersey Web Application</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>

** 编辑 2***

有关此讨论,请参阅 Cássio Mazzochi Molin 的回答。

我使用构建器注册我的资源并打印出来

Builder{names=[com.test.server.TestResource], path='backend', methodBuilders=[], childResourceBuilders=[Builder{names=[[unnamed]], path='info', methodBuilders=[org.glassfish.jersey.server.model.ResourceMethod$Builder@819f71f], childResourceBuilders=[], childResources=[], resourceMethods=[], subResourceLocator=null, handlerClasses=[], handlerInstances=[], parentResource=Builder{names=[com.cetrea.qa.server.TestResource], path='backend'}, extended=false}], childResources=[Resource{"achievements", 3 child resources, 0 resource methods, 0 sub-resource locator, 1 method handler classes, 0 method handler instances},

这是其中的一部分。 TestResource 有一个方法 info , 所以我可以调用 http://localhost:8080/server/backend/info并得到正确的结果。资源achievements来自一个插件,例如一个all方法,所以我尝试了http://localhost:8080/server/backend/achievements/all (也没有 backend 部分),但这又给出了 404

最佳答案

Jersey 提供了一个用于以编程方式构建资源的 API。

根据documentation , Resource类是编程资源建模 API 的主要入口点,它提供了以编程方式扩展现有 JAX-RS 注释资源类或构建可由 Jersey 运行时使用的新资源模型的能力。

查看文档提供的示例:

@Path("hello")
public class HelloResource {

@GET
@Produces("text/plain")
public String sayHello() {
return "Hello!";
}
}
// Register the annotated resource.
ResourceConfig resourceConfig = new ResourceConfig(HelloResource.class);

// Add new "hello2" resource using the annotated resource class
// and overriding the resource path.
Resource.Builder resourceBuilder =
Resource.builder(HelloResource.class, new LinkedList<ResourceModelIssue>())
.path("hello2");

// Add a new (virtual) sub-resource method to the "hello2" resource.
resourceBuilder.addChildResource("world").addMethod("GET")
.produces("text/plain")
.handledBy(new Inflector<Request, String>() {
@Override
public String apply(Request request) {
return "Hello World!";
}
});

// Register the new programmatic resource in the application's configuration.
resourceConfig.registerResources(resourceBuilder.build());

下表说明了上面示例中配置的应用程序支持的请求和提供的响应:

 Request              |  Response        |  Method invoked
----------------------+------------------+--------------------------
GET /hello | "Hello!" | HelloResource.sayHello()
GET /hello2 | "Hello!" | HelloResource.sayHello()
GET /hello2/world | "Hello World!" | Inflector.apply()

有关更多详细信息,请查看 Jersey documentation .

关于java - Jersey Web 应用程序动态注册资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39697138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com