Dropwizard десериализует пользовательское исключение как JSON?

Я создал новый класс исключений в своем сервисе Dropwizard, который расширяет BadRequestException.

public class CustomBadRequestException extends BadRequestException {

    private static final long serialVersionUID = 1L;

    private List<ValidationFailureDto> validationFailures;

    public CustomBadRequestException() {
        super();
    }

    public CustomBadRequestException(final List<ValidationFailureDto> validationFailures) {
        super();
        this.validationFailures = validationFailures;
    }

    @ApiModelProperty(value = "List of validationFailures")
    public List<ValidationFailureDto> getValidationFailures() {
        return validationFailures;
    }
}

Когда я сначала выбрасывал это исключение, я возвращал только десериализованное исключение BadRequestException, за исключением дополнительного свойства (validationFailures)

{
code: "400",
message: "Bad request"
}

Это связано с тем, что внутренности Dropwizard имеют сопоставление исключений по умолчанию, которое позволяет Jetty/Jackson понимать исключения домена и как отправлять соответствующий HTTP-ответ.

Чтобы преодолеть это, вы можете реализовать свой собственный класс ExceptionMapper и зарегистрировать его в Dropwizard.

public class CustomBadRequestExceptionMapper implements ExceptionMapper<SamplePackOrderBadRequestException> {

/**
 * Allows jackson to deserialise custom exceptions and its properties to JSON response
 *
 * @param exception exception
 * @return response object
 */
@Override
public Response toResponse(final SamplePackOrderBadRequestException exception) {

    if (exception instanceof SamplePackOrderBadRequestException) {

        SamplePackOrderBadRequestException samplePackOrderBadRequestException
                = (SamplePackOrderBadRequestException) exception;
        return Response
                .status(400)
                .entity(samplePackOrderBadRequestException)
                .build();
    }
    return Response.status(400).build();
}
}

Однако эта проблема заключается в том, что он десериализует super (Throwable), поэтому в ответ добавляются все унаследованные свойства, которые я не хочу.

Чтобы бороться с этим, я попытался добавить аннотации Джексона, например, так:

@JsonIgnoreProperties(value = "stackTrace")

Это не оптимальное решение, так как есть несколько свойств, кроме stackTrace, которые мне нужно игнорировать.

Итак, подведем итог: как я могу заставить Dropwizard правильно десериализовать мой класс CustomException без всего лишнего беспорядка, который мне не нужен?

1 ответ

Решение

Я думаю, что более простой вариант - преобразовать исключение в Error боб и вернуть его, как показано ниже.

public class CustomBadRequestExceptionMapper implements ExceptionMapper<SamplePackOrderBadRequestException> {


@Override
public Response toResponse(final SamplePackOrderBadRequestException exception) {

    if (exception instanceof SamplePackOrderBadRequestException) {

        SamplePackOrderBadRequestException ex
            = (SamplePackOrderBadRequestException) exception;
         return Response
            .status(400)
            .entity(new ErrorBean(400,ex.getMessage,ex.getgetValidationFailures()))
            .build();
    }
    return Response.status(400).build();
}
}

И ErrorBean.java

    public static class ErrorBean{
    private int code;
    private String message;
    private List<ValidationFailureDto> failures;
    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public List<ValidationFailureDto> getFailures() {
        return failures;
    }
    public void setFailures(List<ValidationFailureDto> failures) {
        this.failures = failures;
    }
}
Другие вопросы по тегам