来自泽西岛的Dropwizard错误消息

问题描述 投票:8回答:5

我得到以下日志输出。我想drop向导试图错误,但它使用的Jersey JAX-RS实现不知道如何格式化错误?我怎么看呢?

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) {...}
error-handling jersey jax-rs dropwizard
5个回答
9
投票

你需要一个用于ErrorMessage的序列化器。如果你使用eclipse Strg + Shift + T并搜索“JsonProcessingExceptionMapper”。此异常映射器希望使用实体ErrorMessage构建响应,但您没有此映射器。

您有两种选择:

  1. 删除此异常映射器并添加没有实体的自定义异常映射器
  2. 您创建一个消息正文编写器。

选项1:在run()中添加此方法:

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中默认添加的所有异常映射器。现在您可以添加您真正想要的所有异常映射器。就我而言:

    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());    

希望这可以帮助 :-)


6
投票

只需要为您的资源指定这些标头,以便dropwizard了解用于响应的错误消息构建器:

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

3
投票

Dropwizard将在DEBUG级别记录底层错误,因此您可以在日志配置中打开它以查看原因:

io.dropwizard.jersey.jackson.JsonProcessingExceptionMapper: DEBUG

2
投票

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

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

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

1
投票

我最近遇到过这种情况,因此提交了一个(现已接受的)pull请求来记录警告而不是调试的基础错误。

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

© www.soinside.com 2019 - 2024. All rights reserved.