我正在使用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
答案 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 。 所以有两种情况:
现在我正在为两者返回状态400 。
答案 2 :(得分:3)
在dropwizard land中有一个名为JsonProcessingExceptionMapper的ExceptionMapper
,它具有与您要查找的内容类似的功能。也许你可以用它来获得如何在非dropwizard世界中解决你的特定问题的灵感。
答案 3 :(得分:1)
我遇到了同样的问题......不幸的是,我知道拦截杰克逊异常并生成自己的错误代码没有好方法。
您拥有的一个选项是使用@JsonIgnoreProperties
,然后严格验证反序列化的对象。这不会告诉你发件人是否发送了垃圾邮件,但如果他们错过了必填字段,你就会发现它。
我找不到任何方法来访问传入的实际JSON,除了创建一个@Provider类来捕获JSON,验证它,然后将它传递给Jackson进行反序列化。