如何在反序列化失败时自定义错误响应

时间:2017-04-25 01:09:08

标签: java-ee jersey jackson jax-rs

我有一个jaxrs端点服务,在我自己的ResourceConfig我注册了一个ExceptionMapper,所以当发生错误时,它会返回一个JSON { errorEnum: "something" }。服务类看起来像这样。

@POST
@Path("/query")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Response query(final QueryDefinition queryDefinition) {
    ...
}

但是,在我的有效载荷中,有一个字段是Enum。如果任何用户在该字段中输入了拼写错误,则错误消息将为

Can not deserialize value of type FIELD from String "AAA": value not
one of declared Enum instance names: [AAA, BBB, CCC]  at [Source:
org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@62ac814;
line: 15, column: 17] (through reference chain:
QueryDefinition["FIELD"])

我尝试使用自定义的EnumDeserializer,

public class EnumDeserializer extends JsonDeserializer<Enum   {
    @Override
    public Dimensions deserialize(JsonParser jp, DeserializationContext deserializationContext) throws IOException,
JsonProcessingException {
        JsonNode node = jp.getCodec().readTree(jp);
        String enumName = node.textValue();
        Enum e = Enums.fromString(enumName);
        if (e != null) { return e; }
        throw new CustomizedException("Not supported Enum");
    } }

然后响应变为Not supported Enum (through reference chain: QueryDefinition["FIELD"]),这仍然不是我想要的。

1 个答案:

答案 0 :(得分:3)

杰克逊提供商已经有ExceptionMapper s 1 ,只有在捕获到异常时才会返回异常消息。如果需要,您可以为这些例外创建自己的ExceptionMapper,例如JsonParseExceptionJsonMappingException,然后只返回您想要的消息。然后只需使用Jersey应用程序注册那些映射器。这应该优先于杰克逊注册的那些。

您的异常映射器不起作用的原因是因为来自Jackson的那些更具体。总是会调用更具体的一个。

1 - 即JsonParseExceptionMapperJsonMappingExceptionMapper