Kotlin/Dropwizard 中的子资源定位器
Sub-resource locators in Kotlin/Dropwizard
我正在尝试使用 Kotlin 1.0.3 在 Dropwizard 1.0 中实现带有子资源的资源。我有一个示例资源:
package net.reznik.Whosebug.resources
import javax.ws.rs.Consumes
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.Produces
import javax.ws.rs.core.MediaType
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
class TestResource {
@Path("/{foo}/")
fun subresource(@PathParam("foo") foo: String): Any {
return TestSubResource()
}
}
还有一个子资源:
package net.reznik.Whosebug.resources
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response
class TestSubResource {
@POST
@Path("/bar")
fun bar(request: String): Response {
return Response.ok("entity received: $request", MediaType.TEXT_PLAIN_TYPE).build()
}
}
如果我将子资源函数的 return 类型从 Any
更改为 TestSubResource
,那么一切都会按预期进行。我想使用 Any
作为 return 类型,这样我就可以根据 {foo}
的值 return 不同的子资源。
当使用 Any
时,dropwizard 在启动时会崩溃并出现很长的堆栈跟踪...
WARN [2016-08-31 22:01:32,454] /: unavailable
! java.lang.NullPointerException: null
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:173)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:164)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:189)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:164)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:159)
! at io.dropwizard.jersey.DropwizardResourceConfig.getEndpointsInfo(DropwizardResourceConfig.java:130)
! at io.dropwizard.jersey.DropwizardResourceConfig.logComponents(DropwizardResourceConfig.java:80)
! at io.dropwizard.jersey.DropwizardResourceConfig$ComponentLoggingListener.onEvent(DropwizardResourceConfig.java:245)
! at org.glassfish.jersey.server.internal.monitoring.CompositeApplicationEventListener.onEvent(CompositeApplicationEventListener.java:74)
! at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:629)
! at org.glassfish.jersey.server.ApplicationHandler.access0(ApplicationHandler.java:184)
! at org.glassfish.jersey.server.ApplicationHandler.call(ApplicationHandler.java:350)
! at org.glassfish.jersey.server.ApplicationHandler.call(ApplicationHandler.java:347)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
! at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
! at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347)
! 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:244)
! at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:640)
! at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:419)
! at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:875)
! at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:349)
! at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:772)
! at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at com.codahale.metrics.jetty9.InstrumentedHandler.doStart(InstrumentedHandler.java:103)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.server.handler.gzip.GzipHandler.doStart(GzipHandler.java:231)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.server.handler.StatisticsHandler.doStart(StatisticsHandler.java:252)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.server.Server.start(Server.java:411)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.server.Server.doStart(Server.java:378)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at io.dropwizard.cli.ServerCommand.run(ServerCommand.java:53)
! at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:44)
! at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:85)
! at io.dropwizard.cli.Cli.run(Cli.java:75)
! at io.dropwizard.Application.run(Application.java:79)
有没有一种方法可以用 kotlin/dropwizard 实现子资源定位器,这样我就可以根据自己的自定义逻辑动态 return 多个子资源之一 - 即,使用 return 类型Any
?
当 Jersey 使用多态资源返回一个也可能是资源的类型时,它会在请求期间在运行时解析此子资源。 DropWizard 几乎按原样使用 Jersey,因此会支持这个用例。
但是,DropWizard 有一个功能可以记录正在创建的路由绑定的输出,它输出它在 Servlet 初始化期间确定的资源配置。这段代码有一个错误。我在这里报告了确切的错误:
https://github.com/dropwizard/dropwizard/issues/1716
我没有看到一个简单的解决方法,例如关闭此日志记录调用或注销事件。看来需要给 DropWizard 打个补丁了。
更新: 此问题已通过拉取请求 https://github.com/dropwizard/dropwizard/pull/1718 解决,如果您使用合并到 master
中跟踪下一个版本,它将包括此修复。
我正在尝试使用 Kotlin 1.0.3 在 Dropwizard 1.0 中实现带有子资源的资源。我有一个示例资源:
package net.reznik.Whosebug.resources
import javax.ws.rs.Consumes
import javax.ws.rs.Path
import javax.ws.rs.PathParam
import javax.ws.rs.Produces
import javax.ws.rs.core.MediaType
@Path("/test")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
class TestResource {
@Path("/{foo}/")
fun subresource(@PathParam("foo") foo: String): Any {
return TestSubResource()
}
}
还有一个子资源:
package net.reznik.Whosebug.resources
import javax.ws.rs.POST
import javax.ws.rs.Path
import javax.ws.rs.core.MediaType
import javax.ws.rs.core.Response
class TestSubResource {
@POST
@Path("/bar")
fun bar(request: String): Response {
return Response.ok("entity received: $request", MediaType.TEXT_PLAIN_TYPE).build()
}
}
如果我将子资源函数的 return 类型从 Any
更改为 TestSubResource
,那么一切都会按预期进行。我想使用 Any
作为 return 类型,这样我就可以根据 {foo}
的值 return 不同的子资源。
当使用 Any
时,dropwizard 在启动时会崩溃并出现很长的堆栈跟踪...
WARN [2016-08-31 22:01:32,454] /: unavailable
! java.lang.NullPointerException: null
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:173)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:164)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:189)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:164)
! at io.dropwizard.jersey.DropwizardResourceConfig$EndpointLogger.populate(DropwizardResourceConfig.java:159)
! at io.dropwizard.jersey.DropwizardResourceConfig.getEndpointsInfo(DropwizardResourceConfig.java:130)
! at io.dropwizard.jersey.DropwizardResourceConfig.logComponents(DropwizardResourceConfig.java:80)
! at io.dropwizard.jersey.DropwizardResourceConfig$ComponentLoggingListener.onEvent(DropwizardResourceConfig.java:245)
! at org.glassfish.jersey.server.internal.monitoring.CompositeApplicationEventListener.onEvent(CompositeApplicationEventListener.java:74)
! at org.glassfish.jersey.server.ApplicationHandler.initialize(ApplicationHandler.java:629)
! at org.glassfish.jersey.server.ApplicationHandler.access0(ApplicationHandler.java:184)
! at org.glassfish.jersey.server.ApplicationHandler.call(ApplicationHandler.java:350)
! at org.glassfish.jersey.server.ApplicationHandler.call(ApplicationHandler.java:347)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:315)
! at org.glassfish.jersey.internal.Errors.process(Errors.java:297)
! at org.glassfish.jersey.internal.Errors.processWithException(Errors.java:255)
! at org.glassfish.jersey.server.ApplicationHandler.<init>(ApplicationHandler.java:347)
! 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:244)
! at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:640)
! at org.eclipse.jetty.servlet.ServletHolder.initialize(ServletHolder.java:419)
! at org.eclipse.jetty.servlet.ServletHandler.initialize(ServletHandler.java:875)
! at org.eclipse.jetty.servlet.ServletContextHandler.startContext(ServletContextHandler.java:349)
! at org.eclipse.jetty.server.handler.ContextHandler.doStart(ContextHandler.java:772)
! at org.eclipse.jetty.servlet.ServletContextHandler.doStart(ServletContextHandler.java:262)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at com.codahale.metrics.jetty9.InstrumentedHandler.doStart(InstrumentedHandler.java:103)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:114)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.server.handler.gzip.GzipHandler.doStart(GzipHandler.java:231)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.server.handler.StatisticsHandler.doStart(StatisticsHandler.java:252)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:132)
! at org.eclipse.jetty.server.Server.start(Server.java:411)
! at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:106)
! at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:61)
! at org.eclipse.jetty.server.Server.doStart(Server.java:378)
! at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:68)
! at io.dropwizard.cli.ServerCommand.run(ServerCommand.java:53)
! at io.dropwizard.cli.EnvironmentCommand.run(EnvironmentCommand.java:44)
! at io.dropwizard.cli.ConfiguredCommand.run(ConfiguredCommand.java:85)
! at io.dropwizard.cli.Cli.run(Cli.java:75)
! at io.dropwizard.Application.run(Application.java:79)
有没有一种方法可以用 kotlin/dropwizard 实现子资源定位器,这样我就可以根据自己的自定义逻辑动态 return 多个子资源之一 - 即,使用 return 类型Any
?
当 Jersey 使用多态资源返回一个也可能是资源的类型时,它会在请求期间在运行时解析此子资源。 DropWizard 几乎按原样使用 Jersey,因此会支持这个用例。
但是,DropWizard 有一个功能可以记录正在创建的路由绑定的输出,它输出它在 Servlet 初始化期间确定的资源配置。这段代码有一个错误。我在这里报告了确切的错误:
https://github.com/dropwizard/dropwizard/issues/1716
我没有看到一个简单的解决方法,例如关闭此日志记录调用或注销事件。看来需要给 DropWizard 打个补丁了。
更新: 此问题已通过拉取请求 https://github.com/dropwizard/dropwizard/pull/1718 解决,如果您使用合并到 master
中跟踪下一个版本,它将包括此修复。