java 如何将JSON解析相关错误Map到Jersey中的JSON响应

jv2fixgn  于 2023-02-07  发布在  Java
关注(0)|答案(4)|浏览(150)

我定义了一个数据类型及其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());
    }
}

如果我摆出{ "name": "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响应。但事件我添加了以下异常Map器,它不返回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();
    }
}

为什么我上面的异常Map器不能捕获jersey解析错误。有人能给我解释一下吗?谢谢

    • 更新**

我有两个问题:
1、如何使响应变为application/json而不是text/plain
2,为什么我的异常Map器没有捕捉到引发的异常并将其Map到JSON响应?

    • 更新**

我添加了以下Map器:

public class JsonMappingExceptionMapper implements ExceptionMapper<JsonMappingException> {
    public Response toResponse(JsonMappingException ex) {
        return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                .entity(new ErrorBody(500, ex.getMessage()))
                .type(MediaType.APPLICATION_JSON)
                .build();
    }
}

现在,我可以得到json响应:{ "code": 500, "message": "Unrecognized field \"name1\" (class com.xxx.datatypes.DataType), not marked as ignorable (1 known properties: \"name\"])\n at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@1d8cd12a; line: 2, column: 15] (through reference chain: class com.xxx.datatypes.DataType[\"name1\"])" }
我还有两个问题:
1,为什么我的泛型异常Map器无法捕获它。
2,jsonMap异常Map器无法在发布{"name": "xxxx",}时Map以下异常Unexpected character ('}' (code 125)): was expecting double-quote to start field name at [Source: org.glassfish.jersey.message.internal.ReaderInterceptorExecutor$UnCloseableInputStream@7615743c; line: 3, column: 2](逗号,添加用于测试)

nhhxz33t

nhhxz33t1#

我遇到了同样的问题,我已经解决了。我试着解释你的问题:
JsonMappingExceptionJsonParseException都是JsonProcessingException的扩展,Jersey为JsonMappingException定义了JsonMappingExceptionMapper,为JsonParseException定义了JsonParseExceptionMapper
1.如果您为JsonProcessingException定义了自己的Map器(或更宽的异常Map器),它将无法捕获JsonMappingExceptionJsonParseException,因为这两个异常有自己的Map器。
1.如果定义自己的Map器(比如XxxJsonMappingExceptionMapper对应JsonMappingExceptionYyyJsonParseExceptionMapper对应JsonParseException),您可能会发现有时候可以捕获这些异常,有时候不能,这取决于您自己的Map器是否正常工作。**现在,你可以添加@Priority(1)(javax.annotation.priority)到你的Map器来确保你的Map器工作正常。
回到你的问题:
1.您的通用异常Map器无法捕获它,因为这些异常有自己的异常Map器(JsonMappingExceptionMapperJsonParseExceptionMapper,它们具有更高的优先级)。
1.您无法捕获异常,可能是因为您自己的Map器被JsonParseExceptionMapper隐藏了。请尝试通过将@Priority(1)添加到您自己的Map器中来解决此问题

ix0qys7i

ix0qys7i2#

为什么我的通用异常Map器不能捕获它。
因为Jackson-JAXRS模块已经附带了ExceptionMappers for Jackson exceptions
jsonMap异常Map器无法Map以下异常
我没有测试这个,但很可能是因为它不是一个 mapping 异常,而是一个 parsing 异常。Jackson同时有JsonParseExceptionJsonMappingException。你可以在前面的链接中看到Jackson为JsonMappingExceptionJsonParseException提供了一个ExceptionMapper。你只覆盖了JsonMappingException的Map器。

mbzjlibv

mbzjlibv3#

无法识别的字段“名称1”(类com.xxx.datatypes.DataType),未标记为可忽略(1个已知属性:“姓名”])
如果您查看所引发的异常,可以很清楚地看到,POJO类具有名称为name而不是name1的属性。
而且,您正尝试发布属性名为name1的JSON。

{ "name1": "xxx" }

而且,它没有被识别为name1,没有被定义为name

public class DataType {
    @Column
    private String name;
}

这就是原因,在其他情况下,当您将JSON发布为

{ "name": "xxx" }
m1m5dgzv

m1m5dgzv4#

我正在使用org.glassfish.jersey-jackson-2.33。当你用"withoutExceptionMappers())"注册负责默认Jackson响应的JacksonFeature时。那么如果你有一些Throwable异常Map器,它将被捕获,而不是默认的JacksonMap器。如果你不使用ThrowableMap器,你也可以编写你的JsonParseExceptionMap器。

import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.media.multipart.MultiPartFeature;
import org.glassfish.jersey.process.internal.RequestScoped;
import org.glassfish.jersey.server.ResourceConfig;

public class JerseyApplication extends ResourceConfig {
    //register(JacksonFeature.class);
    register(JacksonFeature.withoutExceptionMappers());
}
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

import com.fasterxml.jackson.core.JsonParseException;

@Provider
public class JsonExceptionsMapper implements ExceptionMapper<JsonParseException> {
    @Override
    public Response toResponse(JsonParseException exception) {
         //replace with your custom response
         return Response.status(Response.Status.BAD_REQUEST).entity(exception.getMessage()).type("text/plain").build();
    }
}

相关问题