Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/396.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用JSON-B/Yasson将JSON反序列化为多态POJO_Java_Resteasy_Quarkus_Jsonb Api_Yasson - Fatal编程技术网

Java 使用JSON-B/Yasson将JSON反序列化为多态POJO

Java 使用JSON-B/Yasson将JSON反序列化为多态POJO,java,resteasy,quarkus,jsonb-api,yasson,Java,Resteasy,Quarkus,Jsonb Api,Yasson,我在一个资源类中有一个补丁端点,其中有一个抽象类作为请求主体。 我得到以下错误: 22:59:30 SEVERE [or.ec.ya.in.Unmarshaller] (on Line: 64) (executor-thread-63) Can't create instance 因为我声明为参数的身体模型是抽象的,所以它无法反序列化 我希望得到元素A或元素B 如何声明主体是多态的 这是元素层次结构 public abstract class BaseElement { public

我在一个资源类中有一个补丁端点,其中有一个抽象类作为请求主体。 我得到以下错误:

22:59:30 SEVERE [or.ec.ya.in.Unmarshaller] (on Line: 64) (executor-thread-63) Can't create instance
因为我声明为参数的身体模型是抽象的,所以它无法反序列化

我希望得到元素A或元素B

如何声明主体是多态的

这是元素层次结构

public abstract class BaseElement {
    public String name;
    public Timestamp start;
    public Timestamp end;
}

public class Element_A extends BaseElement{
    public String A_data;
}

public class Element_B extends BaseElement{
    public long B_data;
}
这是具有我的端点的资源类

@Path("/myEndpoint")
public class ResourceClass {

    @PATCH
    @Path("/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.TEXT_PLAIN)
    public Response updateEvent(@Valid BaseElement element, @Context UriInfo uriInfo, @PathParam long id) {
        if (element instanceof Element_A) {
            // Element_A logic
        } else if (element instanceof Element_B) {
            // Element_B logic
        }
        return Response.status(Response.Status.OK).entity("working").type(MediaType.TEXT_PLAIN).build();
    }
}

这是我发送补丁请求的请求主体

{
  "name": "test",
  "startTime": "2020-02-05T17:50:55",
  "endTime": "2020-02-05T17:51:55",
  "A_data": "it's my data"
}
我还尝试添加@JsonbTypeDeserializer和一个自定义的反序列化程序,但没有成功

@JsonbTypeDeserializer(CustomDeserialize.class)
public abstract class BaseElement {
    public String type;
    public String name;
    public Timestamp start;
    public Timestamp end;
}
抛出此错误:

02:33:10 SEVERE [or.ec.ya.in.Unmarshaller] (executor-thread-67) null
02:33:10 SEVERE [or.ec.ya.in.Unmarshaller] (executor-thread-67) Internal error: null
My pom.xml包括:

<dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
      <groupId>io.quarkus</groupId>
      <artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>

夸克斯
夸克斯轻松
夸克斯
quarkus resteasy jsonb

JSON-B还没有对多态反序列化的理想支持,所以现在您最多可以做一些变通。我们这里有一个设计问题有待解决:,所以请给它一个
+1

您对自定义反序列化程序的想法是正确的,但问题是您无法解析当前的
JsonObject
,然后用同一个解析器调用
context.deserialize()
,因为解析器已经超过了读取JSON对象的状态。(JSONParser是一个只向前的解析器,因此没有“倒带”它的方法)

因此,您仍然可以在自定义反序列化程序中调用
parser.getObject()
,但在确定特定JSON字符串的具体类型后,需要使用单独的
Jsonb
实例来解析该字符串

公共静态类CustomDeserialize实现JsonbDeserializer{
私有静态final Jsonb Jsonb=JsonbBuilder.create();
@凌驾
公共BaseElement反序列化(JsonParser解析器,反序列化上下文,类型rtType){
JsonObject jsonObj=parser.getObject();
字符串jsonString=jsonObj.toString();
字符串类型=jsonObj.getString(“类型”);
开关(类型){
案例“A”:
返回jsonb.fromJson(jsonString,Element_A.class);
案例“B”:
返回jsonb.fromJson(jsonString,Element_B.class);
违约:
抛出新的JSONBEException(“未知类型:+类型”);
}
}
}

旁注:您需要将基本对象模型更改为以下内容:

@JsonbTypeDeserializer(CustomDeserialize.class)
公共抽象静态类BaseElement{
公共字符串类型;
公共字符串名称;
@JsonbProperty(“开始时间”)
公共LocalDateTime启动;
@JsonbProperty(“结束时间”)
公共LocalDateTime结束;
}
  • 假设您不能或不想更改JSON模式,您可以更改java字段名(
    start
    end
    )以匹配JSON字段名(
    startTime
    endTime
    ),也可以使用
    @JsonbProperty
    注释重新映射它们(我在上面已经做过)
  • 由于您的时间戳是ISO_LOCAL_DATE_TIME格式,我建议使用
    java.TIME.LocalDateTime
    而不是
    java.sql.Timestamp
    ,因为
    LocalDateTime
    处理时区,但考虑到您提供的示例数据,这两种方法最终都可以工作
  • 02:33:10 SEVERE [or.ec.ya.in.Unmarshaller] (executor-thread-67) null
    02:33:10 SEVERE [or.ec.ya.in.Unmarshaller] (executor-thread-67) Internal error: null
    
    <dependency>
          <groupId>io.quarkus</groupId>
          <artifactId>quarkus-resteasy</artifactId>
    </dependency>
    <dependency>
          <groupId>io.quarkus</groupId>
          <artifactId>quarkus-resteasy-jsonb</artifactId>
    </dependency>