【问题标题】:Configure JAX-RS base URI programmatically per deployment每个部署以编程方式配置 JAX-RS 基本 URI
【发布时间】:2023-03-15 21:20:01
【问题描述】:

我正在尝试使用 CDI 扩展在运行时发现 JAX-RS 资源,并在 Java SE 环境中自动将它们发布到不同的基本 URI 下。如果可能,应用程序不需要自行扩展javax.ws.rs.core.Application

我已阅读 RestEasy 文档和 javadoc,但未能找到任何明显的方法来在运行时修改 @ApplicationPath

我正在探索的一个想法是尝试生成javax.ws.rs.core.Application 并以编程方式设置@ApplicationPath 基本URI,可能通过使用AnnotatedType CDI 扩展,并将其发布为* org.jboss.resteasy.spi.ResteasyDeployment`。

还有其他/更好的方法吗?

编辑:

尝试 CDI 扩展事件 ProcessAnnotatedType 更改 JAX-RS 资源的 @javax.ws.rs.Path

<X> void process(@Observes ProcessAnnotatedType<X> pat) {
  if (!pat.getAnnotatedType().isAnnotationPresent(javax.ws.rs.Path.class)) {
    return;
  }
  final AnnotatedType<X> org = pat.getAnnotatedType();
  AnnotatedType<X> wrapped = new AnnotatedType<X>() {
    @Override
    public <T extends Annotation> T getAnnotation(final Class<T> annotation) {
    if (javax.ws.rs.Path.class.equals(annotation)) {
      class PathLiteral extends AnnotationLiteral<javax.ws.rs.Path> implements javax.ws.rs.Path {
        @Override
        public String value() {
          return "change_me/" + (javax.ws.rs.Path) org.getAnnotation(annotation);
        }
      }
      return (T) new PathLiteral();
    } else {
      return org.getAnnotation(annotation);
    }
  }
  pat.setAnnotatedType(wrapped);
}

...然后在引导之后,使用javax.enterprise.inject.spi.BeanManager 构造bean 期望以下代码打印“change_me/....”

Set<Bean<?>> beans = beanManager.getBeans(jaxrsClass);
for (Bean<?> bean : beans) {
  CreationalContext cc = bm.createCreationalContext(bean);
  Object jaxrs = bean.create(cc);
  Path p = jaxrs.getClass().getAnnotation(Path.class);
  System.out.println(p.value());
}

...但这不起作用。 javax.ws.rs.Path 对于 JAX-RS 资源 'jaxrsClass' 保持不变。

怎么了?

【问题讨论】:

    标签: rest jax-rs cdi resteasy


    【解决方案1】:

    我怀疑这能否以可靠的方式完成。这可能都归结为首先发生的事情:CDI 引导程序或 JAX-RS,当然在未来或在其他应用程序服务器中,它们都可以并行完成。

    这当然是一个很酷的想法。他们在 RestEasy 论坛上说了什么?

    【讨论】:

    • 我想我快到了,已经设法使用这种方法部署了 jaxrs 端点。但是,是的,我不确定我是否在这里破解了 jaxrs 引导程序。我在 resteasy 用户邮件列表上发布了一个问题。
    【解决方案2】:

    我们已经在使用这种方法。

    我们正在使用该功能来使用子资源定位器并利用 guice 的力量。

    在启动时,我们在类路径中扫描所有带有@Path 注释的资源。之后,我们在 Names/@Named 的帮助下提取路径并绑定资源。因此,以后可以借助名称来注入资源。

    bind(..).annotatedWith(Names.named("path")).to(..)
    

    下一步是您需要一个带有子资源定位器的资源。

    @Path("{name}")
    public Object find(@PathParam("name") name){
        return injector.getInstance(..);
    }
    

    您可以使用这种方法在运行时绑定它们,也可以更改原始注释路径。

    【讨论】:

    • 非常有趣!我不熟悉 Guice 术语。这是否对 JAX-RS 资源提出了非标准要求?您有 JAX-RS 资源的简短示例吗?
    • 您不必更改您的资源。我将创建一个小项目并将其发布在此处,您可以看看它是如何工作的。
    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 2014-12-11
    • 2016-06-15
    相关资源
    最近更新 更多