The question Exception Handling/Mapping for a particular class brought me to the question of how to register an ExceptionMapper
to a particular resource Method .
I've tried to use a DynamicFeature
like this:
@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
}
The result was disillusioning:
WARNING: The given contract (interface javax.ws.rs.ext.ExceptionMapper) of class ...WebApplicationExceptionMapper provider cannot be bound to a resource method.
Then I was searching for other possibilities without luck and ended up with a AspectJ implementation, which you can see as a part of my answer to the linked question above.
So the complete question:
Is there a way to successfully register an ExceptionMapper to a resource Method?
And of course,
I'm curious about the answers :)
Please notice:
This question is not about to register an ExceptionMapper
to a resource Class like...
public class ApplicationResourceConfig extends ResourceConfig {
public ApplicationResourceConfig() {
register(WebApplicationExceptionMapper.class, TestResource.class);
}
}
and especially not about to register them at all.
It's not exactly what you asked, but it's the only way I've found to do something like you want:
@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();
}
}
It works for my purposes anyway.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.