泽西岛:当给出无效的请求体时,返回400错误而不是500

时间:2012-03-23 18:31:13

标签: jersey jax-rs

我正在使用Jersey的集成Jackson处理功能将传入的JSON转换为POJO,例如:

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response newCustomer( CustomerRepresentation customer)
{
...
}

如果客户端发送带有无效字段的JSON,则Jersey当前返回500 Internal Server Error。相反,我想返回一个400 Bad Request,最好有一些有意义的细节,说明哪些字段有误。

有关如何实现这一目标的任何见解? (至少返回一个通用的400而不是完全不合适的500?)

更新 这是在调用我的处理程序之前在服务器端生成的异常:

javax.servlet.ServletException: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
Unrecognized field "this_isnt_a_known"_field" (Class com.redacted....), not marked as ignorable

4 个答案:

答案 0 :(得分:18)

我终于能够通过实现ExceptionMapper来捕获杰克逊抛出的UnrecognizedPropertyException并将其映射到400 Bad Request响应来解决此问题:

@Provider
public class UnrecognizedPropertyExceptionMapper implements ExceptionMapper<UnrecognizedPropertyException>
{

    @Override
    public Response toResponse(UnrecognizedPropertyException exception)
    {
        return Response
                .status(Response.Status.BAD_REQUEST)
                .entity( "'" + exception.getUnrecognizedPropertyName() + "' is an unrecognized field.")
                .type( MediaType.TEXT_PLAIN)
                .build();
    }

}

答案 1 :(得分:3)

我尝试使用HolySamosa的答案将状态500 映射到状态400 ,但此映射器未捕获该异常,并且状态500 仍然存在被退回。

调试后发现 JsonParseException 被抛出而不是 UnrecognizedPropertyException 。这是因为我发送了一些垃圾文本(根本不是JSON)。

当我从客户端发送一个合适的JSON时,格式不适合我服务器端的DTO,那么我得到 UnrecognizedPropertyException 。 所以有两种情况:

  • 当您发送非JSON和
  • 的垃圾时
  • 当您发送JSON时,但它与您的DTO课程不匹配。

现在我正在为两者返回状态400

答案 2 :(得分:3)

在dropwizard land中有一个名为JsonProcessingExceptionMapperExceptionMapper,它具有与您要查找的内容类似的功能。也许你可以用它来获得如何在非dropwizard世界中解决你的特定问题的灵感。

答案 3 :(得分:1)

我遇到了同样的问题......不幸的是,我知道拦截杰克逊异常并生成自己的错误代码没有好方法。

您拥有的一个选项是使用@JsonIgnoreProperties,然后严格验证反序列化的对象。这不会告诉你发件人是否发送了垃圾邮件,但如果他们错过了必填字段,你就会发现它。

我找不到任何方法来访问传入的实际JSON,除了创建一个@Provider类来捕获JSON,验证它,然后将它传递给Jackson进行反序列化。