问题Exception Handling/Mapping for a particular class让我想到了如何将ExceptionMapper
注册到特定资源方法的问题。
我尝试过这样的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);
}
}
尤其不是要注册它们。
答案 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();
}
}
无论如何它都适用于我的目的。