2

In Dropwizard I use @Valid annotations for my resource methods:

public class Address {
  @NotNull
  String street
  ...
}

@Path("/address")
@Produces(MediaType.APPLICATION_JSON)
public class AddressResource {
  @POST
  public MyResponse addAddress(@Valid Address address) {
    if (address == null) {
      throw new WebApplicationException("address was null");
    }
    ...
  }
}

On application start I register a custom WebApplicationExceptionMapper which handles WebApplicationExceptions. Thus, for addresses with the value null, the exception is thrown and handled in the mapper which generates a useful response. However, if the address is not null but street is, Dropwizard automatically generates a response and sends it to the client (which I dislike).

How do I interfere this response so that in the end it is also handled by the mapper?

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
Bastian
  • 4,638
  • 6
  • 36
  • 55

2 Answers2

4

Dropwizard registers their own constraint violation exception mapper which you can override.

Since Jersey does not yet support the @Priority annotation on the exception mappers (https://java.net/jira/browse/JERSEY-2437), you should disable the registration of the Dropwizard's mappers before register your own. Here is an fragment of the Application's run method and an exception mapper:

@Override
public void run(
        final Configuration config,
        final Environment environment) throws Exception {
    ((DefaultServerFactory)config.getServerFactory()).setRegisterDefaultExceptionMappers(false);
    // Register custom mapper
    environment.jersey().register(new MyConstraintViolationExceptionMapper());
    // Restore Dropwizard's exception mappers
    environment.jersey().register(new LoggingExceptionMapper<Throwable>() {});
    environment.jersey().register(new JsonProcessingExceptionMapper());
    environment.jersey().register(new EarlyEofExceptionMapper());
    ...
}

@Provider
public class MyConstraintViolationExceptionMapper 
        implements ExceptionMapper<ConstraintViolationException> {

    @Override
    public Response toResponse(ConstraintViolationException exception) {
    ...
    }
}
Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
  • I believe this is correct approach (turn off default, add your own and then add back rest of defaults). I have recently seen, exception mappers being randomly pickedup (sometimes mine, sometimes defaults) if above is not done. And see this answer, [detailing the same behavior](https://stackoverflow.com/a/33746883/1229355); and [check this out](https://stackoverflow.com/a/29059976/1229355) as well. – Tyagi Akhilesh Mar 01 '18 at 09:28
4

In newer Dropwizard versions (for e.g. 0.9.2), I had to do:

env.jersey().register(new JsonProcessingExceptionMapper(true));

Gnana
  • 614
  • 1
  • 7
  • 18