Java 如何将JSON解析相关错误映射到jersey中的JSON响应

Java 如何将JSON解析相关错误映射到jersey中的JSON响应,java,rest,error-handling,jersey-2.0,exceptionmapper,Java,Rest,Error Handling,Jersey 2.0,Exceptionmapper,我定义了一个数据类型及其API: public class DataType { @Column private String name; } // API is: public class DataTypeAPI { @POST @Path("/") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) @ManagedAsync

我定义了一个数据类型及其API:

public class DataType {
    @Column
    private String name;
}

// API is:
public class DataTypeAPI {
    @POST
    @Path("/")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @ManagedAsync
    public void createDataType(
            final DataType dataType,
    ) {
        ...
        asyncResponse.resume(Response.status(Response.Status.CREATED)
                .entity(dataType)
                .build());
    }
}
如果我摆姿势,一切都好
{
“名称”:“xxx”
}

但是当我发布
{“name1”:“xxx”}
时,我得到了以下
text/plain
响应:

Unrecognized field "name1" (class com.xxx.datatypes.DataType), not marked as ignorable (1 known properties: "name"])
 at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@526e34b1; line: 2, column: 15] (through reference chain: com.xxx.datatypes.DataType["name1"])
我更愿意将上述错误转换为JSON响应。但我添加了以下异常映射程序,它不会返回JSON响应

@Provider

public class GenericExceptionMapper implements ExceptionMapper<Throwable> {
    public Response toResponse(Throwable ex) {
        System.out.println("GenericExceptionMapper");
        ex.printStackTrace();
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity(new ErrorBody(500, ex.getMessage()))
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}
现在,我可以得到json响应:
{
“代码”:500,
“消息”:“无法识别的字段\”name1\”(class com.xxx.datatypes.DataType),未标记为可忽略(1个已知属性:\“name\”)\n位于[来源:org.glassfish.jersey.message.internal.ReaderInterceptorExecutor]$UnCloseableInputStream@1d8cd12a;行:2,列:15](通过引用链:class com.xxx.datatypes.DataType[\“name1\]”)
}

我还有两个问题:

1,为什么我的通用异常映射程序无法捕获它。

2,json映射异常映射程序无法映射以下异常
意外字符('}'(代码125)):应在字段名开头加上双引号
在[来源:org.glassfish.jersey.message.internal.ReaderInterceptorExecutor]$UnCloseableInputStream@7615743c;第3行,第2列]
{“name”:“xxxx”}
发布时(逗号,添加用于测试)

无法识别的字段“name1”(类com.xxx.datatypes.DataType),未识别 标记为可忽略(1个已知属性:“名称”])

如果查看引发的异常,很明显,POJO类的属性名为
name
而不是
name1

{ "name1": "xxx" }
并且,您正试图发布带有属性名
name1
的JSON

{ "name1": "xxx" }
而且,它没有被识别为
name1
,而是没有定义
name

public class DataType {
    @Column
    private String name;
}
这就是原因,在另一种情况下,当您将JSON发布为

{ "name": "xxx" }
为什么我的通用异常映射程序无法捕获它

因为Jackson JAXRS模块已经随附

json映射异常映射程序无法映射以下异常


我没有测试这个,但很可能是因为它不是映射异常,而是解析异常。Jackson同时拥有
JsonParseException
JsonMappingException
。您可以在前面的链接中看到,Jackson为
JsonMappingException
JsonParseException
都提供了一个ExceptionMapper。您只是覆盖了
JsonMappingException

的映射程序。我遇到了同样的问题,我已经解决了。我试图解释你的问题:

JsonMappingException
JsonParseException
extend
JsonProcessingException
。泽西岛为
jsonmappingexceptionapper
定义了
jsonmappingexceptionapper
,为
jsonparseexceptionapper
定义了
jsonparseexceptionapper

  • 如果为
    JsonProcessingException
    (或更广泛的异常映射器)定义自己的映射器,则它无法捕获
    JsonMappingException
    JsonParseException
    ,因为这两个异常都有自己的映射器。如果他们没有,你的地图绘制者可以捕捉到
  • 如果您为
    JsonMappingException
    定义自己的映射器(比如为
    JsonMappingException
    定义自己的映射器
    XxxJsonMappingExceptionMapper
    和为
    JsonParseException
    定义自己的映射器),您可能会发现有时可以捕捉到这些异常,有时则无法捕捉到,这取决于您自己的映射器正在工作或jersey的映射器正在工作现在,您可以将
    @Priority(1)
    (javax.annotation.Priority)添加到映射器中,以确保映射器正常工作。
    请参阅
  • 回到你的问题:

  • 您的通用异常映射程序无法捕获它,因为这些异常有自己的异常映射程序(
    JsonMappingExceptionMapper
    JsonParseExceptionMapper
    ,它们具有更高的优先级)
  • 您可能无法捕获异常,因为您自己的映射程序被
    jsonparseexceptionapper
    隐藏。通过将
    @Priority(1)
    添加到您自己的映射器中,尝试找出答案

  • 也许我没有把我的问题解释清楚。我已经更新了我的帖子。Thanks@BAE您是否有try-catch块,我在您的代码中没有看到。如果是,那么您需要在catch块中构建JSON响应。如果您希望这将隐式完成。那么你错了。我认为解析是由jersey隐式完成的。而且它没有到达我的api代码。@BAE是的,jersey负责(反)序列化,具体取决于您的POJO。如果您想在所有情况下忽略上述异常。然后您可以将其标记为Ignorable.但是在我添加了自己的JsonMappingExceptionMapper之后,我可以得到JSON响应。我试图在mapper中映射
    JsonParseException
    ,但它不起作用。所以,我很困惑。是的,我不确定这一点。@BAE可能是球衣的
    JsonParseExceptionMapper
    shadows你的。在节目开始时是随机的。看看我的答案。