How to override the built-in exception collector in Jersey 2.23?

In one of my projects, I already updated Jersey from version 2.14 to 2.23 . But I struggle for many hours with one problem. My project defines its own ExceptionMapper for ValidationException , but unfortunately Jersey already has a built-in exception mapping module for this exception, and I cannot override it.

I correctly registered (I checked) my own cartographer, which is presented below:

 @Provider public class ValidationExceptionMapper implements ExceptionMapper<ValidationException> { @Override public Response toResponse(ValidationException exception) { return Response.status(Status.BAD_REQUEST).build(); } } 

but he is never called. Jersey always chooses org.glassfish.jersey.server.validation.internal.ValidationExceptionMapper . I also tried using the @Priority annotation for my custom @Priority , but unfortunately Jersey doesn't take that into account.

So what's going on? He did a great job with the previous version in Jersey, so it seems like this is a regression error.

I give up. Any clues?

+8
java jersey embedded-jetty weld2
source share
3 answers

It really turned out to be a regression error in Jersey that appeared in January 2015.

The error is related to two Jersey extensions: for validating and verifying beans. Because without starting the Weld container, my custom ValidationExceptionMapper has priority over the built-in provided by the jersey-bean-validation module, so my goal has been reached.

I filled out an error report under JERSEY-3153 , later switched under number 3425 .

To be honest, I will never use Weld + Jersey again ... I'm so tired of this combination. Over the past two years, I have already encountered 10 errors. I am really tired.

Anyway, I hope this helps someone.

UPDATE : As @Justin Jose noted in the comments below, there is another workaround for the error mentioned. We can use HK2 bindings to override the problematic inline converter:

 register(new AbstractBinder() { @Override protected void configure() { bind(my.custom.ValidationExceptionMapper.class).to(ExceptionMapper.class) .in(Singleton.class); } }); 
+5
source share

The Jersey-built ValidationExceptionMapper is registered through the ValidationFeature. Perhaps replacing the Jersey ValidationFeature with your own version might help. This can be done as follows.

First off, automatically detect ValidationFeature

 property(ServerProperties.BV_FEATURE_DISABLE, true); 

The next step is to register a clone of the Jersey validation function.

 public static class ValidationFeatureClone implements Feature { @Override public boolean configure(FeatureContext context) { context.register(new ValidationBinder()); context.register(NewValidationExceptionMapper.class); context.register(ValidationErrorMessageBodyWriter.class); return true; } } 

In the clone, you must specify your new ExceptionMapper.

Finally register your new feature

 register(ValidationFeatureClone.class) 

UPDATE:

Starting with version 2.20, the default ValidationExceptionMapper can be overwritten using the HK2 binding, as shown below.

 register(new AbstractBinder() { @Override protected void configure() { bind(NewValidationExceptionMapper.class).to(ExceptionMapper.class) .in(Singleton.class).ranked(10β€Œβ€‹); } }); 
+4
source share

I found a way to get it working again with new versions of Jersey, which I also posted under your error message.

You need to create a jersey locally with modified code, in particular the jersey-bean-validation artifact.

Find org.glassfish.jersey.server.validation.internal.ValidationBinder and comment out the following two lines in configure() :

 bind(ValidationExceptionMapper.class).to(ExceptionMapper.class).in(Singleton.class); bind(ValidationErrorMessageBodyWriter.class).to(MessageBodyWriter.class).in(Singleton.class); 

Paradoxically, the commentary on the source code above these lines suggests that they should allow users to register their own providers.

0
source share

All Articles