按部署以编程方式配置JAX-RS基URI

时间:2012-11-12 04:28:15

标签: rest jax-rs cdi resteasy

我尝试使用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);
}

...然后在bootstrap之后,使用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());
}

......但这不起作用。 JAX-RS资源'jaxrsClass'的javax.ws.rs.Path未更改。

有什么问题?

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

我们正在使用该功能来使用Subresource定位器并充分利用guice。

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

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

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

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

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