Jersey - 为资源方法注册ExceptionMapper

时间:2016-04-02 16:01:12

标签: java rest jersey jax-rs jersey-2.0

问题Exception Handling/Mapping for a particular class让我想到了如何将ExceptionMapper注册到特定资源方法的问题。

我尝试过这样的DynamicFeature

DynamicFeature

@Provider
public class ExceptionMapperDynamicFeature implements DynamicFeature {

    @Override
    public void configure(final ResourceInfo resourceInfo, final FeatureContext context) {
        if(!resourceInfo.getResourceMethod().isAnnotationPresent(BindExceptionMapper.class))
            return;
        BindExceptionMapper bem = resourceInfo.getResourceMethod().getAnnotation(BindExceptionMapper.class);
        context.register(bem.mapper());
    }

}

注释

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BindExceptionMapper {
    Class<? extends ExceptionMapper<?>> mapper() default WebApplicationExceptionMapper.class;
}

资源

@GET
@Produces(MediaType.APPLICATION_JSON)
@BindExceptionMapper 
public Response test() {
    // do something that throws an exception
}

结果是幻想破灭:

  

警告:类的给定契约(接口javax.ws.rs.ext.ExceptionMapper)... WebApplicationExceptionMapper提供程序不能绑定到资源方法。

然后我在没有运气的情况下寻找其他可能性,最后得到了一个AspectJ实现,您可以看到上面链接问题的part of my answer

完整的问题:

有没有办法成功将ExceptionMapper注册到资源方法?

当然,

  • 如果是,那么:怎么样?
  • 如果没有那么:为什么?

我很好奇答案:)

请注意:
这个问题不是要将ExceptionMapper注册到资源,就像......

public class ApplicationResourceConfig extends ResourceConfig {
    public ApplicationResourceConfig() {
        register(WebApplicationExceptionMapper.class, TestResource.class);
    }
}

尤其不是要注册它们。

1 个答案:

答案 0 :(得分:1)

这不是完全你问的是什么,但这是我发现做你想做的事情的唯一方法:

@Provider
public class ErrorExceptionHandler implements ExceptionMapper<Throwable> {

    @Context
    private ResourceInfo resourceInfo;

    @Override
    public Response toResponse(final Throwable exception) {
        // this is an example of how to do something custom based on an annotation
        if(!resourceInfo.getResourceClass().isAnnotationPresent(SomeCustomAnnotation.class) && !resourceInfo.getResourceMethod().isAnnotationPresent(SomeCustomAnnotation.class))
            return null; // do some custom thing here based on your annotation, maybe call another ExceptionMapper not annotated with @Provider ?
        return Response.status(500).entity("ERROR").build();
    }
}

无论如何它都适用于我的目的。