2014-10-01 127 views
8

我收到下面的日志输出。我猜drop wizard正在尝试错误,但它使用的Jersey JAX-RS实现不知道如何格式化错误?我如何查看它?来自Jersey的Dropwizard错误消息

ERROR [2014-10-01 08:08:55,875] com.sun.jersey.spi.container.ContainerResponse: A message body writer for Java class io.dropwizard.jersey.errors.ErrorMessage, and Java type class io.dropwizard.jersey.errors.ErrorMessage, and MIME media type text/plain was not found. 
The registered message body writers compatible with the MIME media type are: 
*/* -> 
    com.sun.jersey.core.impl.provider.entity.FormProvider 
    com.sun.jersey.core.impl.provider.entity.StringProvider 
    com.sun.jersey.core.impl.provider.entity.ByteArrayProvider 
    com.sun.jersey.core.impl.provider.entity.FileProvider 
    com.sun.jersey.core.impl.provider.entity.InputStreamProvider 
    com.sun.jersey.core.impl.provider.entity.DataSourceProvider 
    com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General 
    com.sun.jersey.core.impl.provider.entity.ReaderProvider 
    com.sun.jersey.core.impl.provider.entity.DocumentProvider 
    com.sun.jersey.core.impl.provider.entity.StreamingOutputProvider 
    com.sun.jersey.core.impl.provider.entity.SourceProvider$SourceWriter 
    com.sun.jersey.server.impl.template.ViewableMessageBodyWriter 
    com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General 
    com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General 
    com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider 
text/plain -> 
    com.sun.jersey.core.impl.provider.entity.StringProvider 
    com.sun.jersey.core.impl.provider.entity.ReaderProvider 

FWIW我打的方法签名是:

@POST 
@UnitOfWork 
@Path("/update") 
@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.TEXT_PLAIN) 
public String updateResults(ResultsUpdate results) {...} 

回答

9

您需要的ErrorMessage一个serialiszer。如果使用eclipse Strg + Shift + T并搜索“JsonProcessingExceptionMapper”。这个异常映射器想用实体ErrorMessage构建响应,但是你没有映射器。

你有两个选择:

  1. 删除此异常映射并没有实体
  2. 您创建一个邮件正文作家添加自定义的异常映射 。

选项1: 运行中的()添加这个方法:

private void removeDefaultExceptionMappers(boolean deleteDefault,Environment environment) 
{ 
    if(deleteDefault){ 
     ResourceConfig jrConfig = environment.jersey().getResourceConfig(); 
     Set<Object> dwSingletons = jrConfig.getSingletons(); 
     List<Object> singletonsToRemove = new ArrayList<Object>(); 

     for (Object singletons : dwSingletons) { 
      if (singletons instanceof ExceptionMapper && !singletons.getClass().getName().contains("DropwizardResourceConfig")) { 
       singletonsToRemove.add(singletons); 
      } 
     } 

     for (Object singletons : singletonsToRemove) { 
      LOG.info("Deleting this ExceptionMapper: " + singletons.getClass().getName()); 
      jrConfig.getSingletons().remove(singletons); 
     } 
    } 
} 

这将删除默认情况下,DW添加的所有exeption映射器。现在你可以添加你真正想要的所有exeption mappers。在我的情况:

environment.jersey().register(new ConstraintViolationExceptionMapper()); 
    environment.jersey().register(new CustomJsonProcessingExceptionMapper()); 
    environment.jersey().register(new EarlyEofExceptionMapper()); 

现在写自己的自定义CustomJsonProcessingExceptionMapper无实体:

@Provider 
public class CustomJsonProcessingExceptionMapper implements ExceptionMapper<JsonProcessingException> { 

    private static final Logger LOG = LoggerFactory.getLogger(CustomJsonProcessingExceptionMapper.class); 

    @Override 
    public Response toResponse(JsonProcessingException exception) { 
     /* 
     * If the error is in the JSON generation, it's a server error. 
     */ 
     if (exception instanceof JsonGenerationException) { 
      LOG.warn("Error generating JSON", exception); 
      return Response.serverError().build(); 
     } 

     final String message = exception.getOriginalMessage(); 

     /* 
     * If we can't deserialize the JSON because someone forgot a no-arg constructor, it's a 
     * server error and we should inform the developer. 
     */ 
     if (message.startsWith("No suitable constructor found")) { 
      LOG.error("Unable to deserialize the specific type", exception); 
      return Response.serverError().build(); 
     } 

     /* 
     * Otherwise, it's those pesky users. 
     */ 
     LOG.debug("Unable to process JSON (those pesky users...)", exception); 
     return Response.status(Response.Status.BAD_REQUEST) 
         .build(); 
    } 

} 

选项2: 您创建一个串行器/邮件正文作家的ErrorMessage。这样做试试这个:

@Provider 
@Produces(MediaType.TEXT_PLAIN) 
public class ErrorMessageBodyWriter implements MessageBodyWriter<ErrorMessage> { 

    private static final Logger LOG = LoggerFactory.getLogger(ErrorMessageBodyWriter.class); 

    @Override 
    public boolean isWriteable(
     Class<?> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType) 
    { 
     return ValidationErrorMessage.class.isAssignableFrom(type); 
    } 

    @Override 
    public long getSize(
     ErrorMessage t, 
     Class<?> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType) 
    { 
     return -1; 
    } 

    @Override 
    public void writeTo(
     ErrorMessage t, 
     Class<?> type, 
     Type genericType, 
     Annotation[] annotations, 
     MediaType mediaType, 
     MultivaluedMap<String, Object> httpHeaders, 
     OutputStream entityStream) throws IOException, WebApplicationException 
    {  
     String message = t.getMessage();   
     entityStream.write(message.getBytes(Charsets.UTF_8)); 
     LOG.info(message); 
    } 

} 

添加在你的run():

// Serializer 
environment.jersey().register(new ErrorMessageBodyWriter());  

希望这有助于:-)

+1

选项2,工作对我来说,除了isWriteable()方法我不得不将其更改为'return type == ErrorMessage.class;' – 2014-12-01 13:23:17

2

这是愚蠢的,但我点击的dropwizard从主类运行,因此你可以把一个断点的ErrorMessage并运行它在(例如)Eclipse中。

顺便在这种情况下,潜在的错误是:

Can not deserialize instance of java.util.ArrayList out of START_OBJECT token 
4

只是需要让dropwizard了解你的资源来指定这些头哪个错误消息生成器用于响应:

@Consumes(MediaType.APPLICATION_JSON) 
@Produces(MediaType.APPLICATION_JSON) 
+1

我已经指定了这两个注释。 – rich 2014-11-07 19:03:08

+0

我得到了完全相同的错误,并修复了它。你做了什么来解决你的问题?编写自定义异常映射程序或错误消息主体编写器似乎不正确。 – SameeraGupta 2014-11-09 03:12:50

1

我最近碰到过这几次,所以提交编辑(现在接受的)拉取请求,以在发出警告而不是调试时记录底层错误。

https://github.com/dropwizard/dropwizard/commit/ebdfcb47a030730233cf0984aadae155ec138ff3

+0

看起来像它恢复:https://github.com/dropwizard/dropwizard/commit/9f2df976b2b1fda7dfb19fbdfd0c670914791f8a 这是因为有一个首选的替代? – Lorrin 2015-09-03 14:58:42

+0

不知道。对提交有帮助没有解释。 – rich 2015-09-03 21:00:19

2

Dropwizard将记录在DEBUG级别的基本错误,这样你就可以反过来说,在你的日志配置,看看这里的原因:

io.dropwizard.jersey.jackson.JsonProcessingExceptionMapper: DEBUG 
+0

这是最好,最简单和最持久的答案。在你的config.yml文件中(或者任何名字),在“logging:”下,添加上面的行。目前在此页面上没有其他解决方案正常工作。 – Adrien 2017-09-12 21:29:55

相关问题