2017-04-05 85 views
1

我在扩展BadRequestException的Dropwizard服务中创建了一个新的异常类。Dropwizard将自定义异常反序列化为JSON?

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; 
    } 
} 

当我抛出该异常起初我只是找回了deserialised BadRequestException,减去附加属性(validationFailures)

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

这是因为Dropwizard的内部有一个默认的异常映射,允许码头/杰克逊了解域例外以及如何发送适当的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(); 
} 
} 

然而这一问题是,它反序列化超(Throwable的),所以你在哪,我不想响应加入每一个继承财产。

为了解决这个问题我尝试添加注释杰克逊像这样:

@JsonIgnoreProperties(value = "stackTrace") 

这不是因为有比堆栈跟踪其他几个属性,我将需要忽视了一个最佳的解决方案。

所以总结一下,我怎样才能让Dropwizard正确地反序列化我的CustomException类,而不需要所有额外的混乱,我不需要?

+0

您可以使用此:http://stackoverflow.com/questions/26945580/jackson-serialization-how-to-ignore-superclass-properties你必须小心,尽管你如何使用它。由DW提供的Objectmapper是共享的,所以确保你的其他对象不会受到这个:)我认为只是创建一个你使用的包装对象会更容易 – pandaadb

+0

Dropwizard实际上使用了下面答案中推荐的方法。他们使用[自定义ErrorMessage Java bean](https://github.com/dropwizard/dropwizard/blob/master/dropwizard-jersey/src/main/java/io/dropwizard/jersey/errors/ErrorMessage.java)并添加'@JsonInclude(JsonInclude.Include.NON_NULL)'注释:)。这是[ExceptionLoggingMapper}(https://github.com/dropwizard/dropwizard/blob/master/dropwizard-jersey/src/main/java/io/dropwizard/jersey/errors/LoggingExceptionMapper.java)的样子。 – zloster

回答

1

我认为更简单的选择是将异常转换为Error bean并返回它,如下所示。

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; 
    } 
} 
+0

你可能会提到,Dropwizard本身就是这样做的。看到我的意见下的问题:http://stackoverflow.com/questions/43231802/dropwizard-deserialising-custom-exception-as-json#comment73584583_43231802 – zloster