如果我在没有请求正文的情况下发送JSON:
POST /stuff
Content-Type: application/json
Content-Length: 0
<---- Body missing!
...到我的DropWizard(泽西岛)资源,
private class PostBody { public String a };
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response create(@Valid PostBody body)
{ … }
现在,我只在日志中找到一行:
127.0.0.1 - - [04/May/2015:13:21:25 +0000] "POST /stuff HTTP/1.1" 422 370 232 232
HTTP 422不是一个不合理的提示,但我必须相信这里有更详细的信息。同样,如果标题丢失或路径组件与提供的格式不匹配,我希望看到一条日志行,如#34; Header ____无法解析&#34;。
127.0.0.1 - - [04/May/2015:13:21:25 +0000] Received "POST /stuff HTTP/1.1"
127.0.0.1 - - [04/May/2015:13:21:25 +0000] Error: Body could not be parsed (Failure while deserializing field "a")
127.0.0.1 - - [04/May/2015:13:21:25 +0000] "POST /stuff HTTP/1.1" 422 370 232 232
DropWizard中是否内置了此类日志记录?我该如何启用它?
答案 0 :(得分:1)
在这种情况下,您需要覆盖异常映射器。在422的情况下,您需要为ConstraintViolationException实现异常映射器。
答案 1 :(得分:0)
默认情况下,Dropwizard / Jersey将异常映射到响应(默认异常映射器),在某些情况下,日志记录是有限的,因此不是很有用;因为简单或只是强迫开发人员自己做更好的记录。供参考,更完整的描述:
“泽西岛,或者我应该说JAX-RS,公开了一种机制,允许您将抛出的Exception或Throwable映射到REST响应,而不是未处理并作为某些堆栈跟踪呈现给用户或错误文本。(这个机制要求你实现通用的ExceptionMapper接口,然后注册它。)这对于那些喜欢在使用API时将错误返回给客户端的REST API来说非常好,比如返回异常的JSON表示可以在客户端上解析和处理。“(source)
以编程方式,可以通过以下步骤创建自己的自定义异常映射器。代码正在考虑Dropwizard 0.9.x,以及你问题中的具体情况;但是,为了解决其他案例/例外,这个过程是类似的。为简单起见,也省略了一些行:
禁用默认的异常映射器:
通过您的Application子类:
AbstractServerFactory sf = (AbstractServerFactory) config.getServerFactory();
sf.setRegisterDefaultExceptionMappers( false );
通过您的应用程序配置:
server:
registerDefaultExceptionMappers: false
创建自定义异常映射器,通过添加日志记录(JSON和验证异常)来扩展原始异常映射器:
public class CustomConstraintViolationExceptionMapper extends ConstraintViolationExceptionMapper
{
@Override
public Response toResponse( ConstraintViolationException exception )
{
Response superResponse = super.toResponse( exception );
ValidationErrorMessage validationErrorMessage = (ValidationErrorMessage) superResponse.getEntity();
log.error( String.format( "%s\t%s",
exception.getMessage(),
String.join( ";", validationErrorMessage.getErrors() ) ) );
return superResponse;
}
}
public class CustomJsonProcessingExceptionMapper extends JsonProcessingExceptionMapper
{
@Override
public Response toResponse( JsonProcessingException exception )
{
log.error( String.format( "%s", exception.getOriginalMessage() ) );
return super.toResponse( exception );
}
}
注册您创建的自定义异常映射器:
environment.jersey().register( new CustomConstraintViolationExceptionMapper() );
environment.jersey().register( new CustomJsonProcessingExceptionMapper() );
不要忘记添加其他默认的异常映射器(如果需要 - check Dropwizard's code):
environment.jersey().register( new LoggingExceptionMapper<Throwable>(){} );
environment.jersey().register( new EarlyEofExceptionMapper() );
最终结果将记录为:
ERROR [2016-07-05 13:06:36,690] x.y.CustomConstraintViolationExceptionMapper: The request entity had the following errors: field may not be empty
ERROR [2016-07-05 13:19:41,326] x.y.CustomJsonProcessingExceptionMapper: Unrecognized field "UnknownField" (class x.y.z.Xyz), not marked as ignorable
有关该主题的更多信息,您还可以遵循以下参考: