JAX-RS:基于方法注释的map方法实体

时间:2014-03-25 20:43:56

标签: java rest jersey jax-rs

我正在使用JAX-RS 2.0和Jersey 2.6。我想知道是否有可能有这样的事情:

@GET
@Path("/get/{id}")
@MapTo(type = MyObjectDTO.class)
public MyObject getMyObject(@PathParam("id") String id){
  MyObject o = ...
  return o;
}

在上面的方法中,我将返回MyObject的实例。但是,我已定义MapTo注释以指示我要将此对象映射到MyObjectDTO。我认为这种方式可行的方法是在ContainerResponseFilter中尽早处理响应,检测注释MapTo,并假设没有发生错误,将响应中的实体替换为{{1从现有实体(类型MyObjectDTO)中适当地创建。

但是,我找不到一种方法来获取请求进入后刚刚调用的资源中的MyObject,即Method方法,以便我可以扫描getMyObject注释。

有没有办法以JAX-RS-y的方式实现这一目标?

2 个答案:

答案 0 :(得分:0)

这是一个严重的原因,你不能返回dto对象?听起来很奇怪......你可能会使用AOP,但我猜它会很糟糕 这里是Spring AOP的例子 http://docs.spring.io/spring/docs/2.5.4/reference/aop.html

答案 1 :(得分:0)

我认为我通过阅读this SO找到了解决方案。我创建了一个类似这样的类:

@Provider // or register in the configuration...
public class DTOMapperFeature implements DynamicFeature {
  @Override
  public void configure(ResourceInfo resourceInfo, FeatureContext context) {
    for (Annotation annotation : resourceInfo.getResourceMethod().getAnnotations()) {
      if (annotation instanceof MapTo) {
        MapTo mapTo = (MapTo) annotation;
        // Note: additional validation (return type shouldn't be void, 
        // collections are out etc.) is required before creating this,
        // or should be pushed in the DTOMapperFilter.
        // You get the gist: this filter will map the entity to an instance
        // of the specified class (using a constructor in this case).
        context.register(new DTOMapperFilter(
          resourceInfo.getResourceMethod().getReturnType(), 
          mapTo.getResponseType());
      }
    }
  }
  @Priority(/* appropriate priority here! */)
  public final static class DTOMapperFilter implements ContainerResponseFilter {
    public DTOMapperFilter(Class<?> declaredReturnType, Class<?> responseType) { 
      // implementation omitted: find DTO constructor etc.
      // throw if responseType does NOT have a constructor that takes an instance
      // of declaredReturnType: catch errors at application bootstrap!
    }
    @Override
    public void filter(
      ContainerRequestContext requestContext, 
      ContainerResponseContext responseContext) throws IOException {
        // implementation omitted: create instance of DTO class using constructor
      }
  }
}

如果从DTOMapperFilter的构造函数或上面的configure方法抛出合理的异常,这应该非常强大,并且在测试时可以检测到错误。