如何序列化/值序列化(JSON)具有一个属性的类

发布于 2025-01-19 20:04:54 字数 1077 浏览 2 评论 0原文

我想序列化/反序列化(json)一个包含接口属性的类,但底层类没有任何属性。以下是我最简化的案例,也是我的最佳尝试。

尝试反序列化时会抛出错误No合适的构造函数找到类型[简单类型,类com.example.Bar]:无法从JSON对象实例化(需要添加/启用类型信息?)在[来源:java .io.StringReader@301ec38b;行:1,列:2]

public interface FooInterface {
    String doThing();
}

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@EqualsAndHashCode
public class Foo implements FooInterface {
    @Override
    public String doThing() {
        return "foo";
    }
}

@Getter
@Setter
@EqualsAndHashCode
public class Bar {
    FooInterface foo;

    public Bar(FooInterface foo) {
        this.foo = foo;
    }
}
    @Test
    public void fooTest() throws IOException {
        Foo foo = new Foo();
        Bar bar = new Bar(foo);

        String serialized = new ObjectMapper().writeValueAsString(bar); // = {"foo":{}}
        Bar deserialized = new ObjectMapper().readValue(serialized, Bar.class);
        Assert.assertEquals(bar, deserialized);
    }

I'd like to serialize/deserialize (json) a class that contains an attribute that is an interface, but the underlying class doesn't have any attributes. The below is my most simplified case and my best attempt at what to do.

This throws an error when trying to deserialize No suitable constructor found for type [simple type, class com.example.Bar]: can not instantiate from JSON object (need to add/enable type information?) at [Source: java.io.StringReader@301ec38b; line: 1, column: 2]

public interface FooInterface {
    String doThing();
}

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
@EqualsAndHashCode
public class Foo implements FooInterface {
    @Override
    public String doThing() {
        return "foo";
    }
}

@Getter
@Setter
@EqualsAndHashCode
public class Bar {
    FooInterface foo;

    public Bar(FooInterface foo) {
        this.foo = foo;
    }
}
    @Test
    public void fooTest() throws IOException {
        Foo foo = new Foo();
        Bar bar = new Bar(foo);

        String serialized = new ObjectMapper().writeValueAsString(bar); // = {"foo":{}}
        Bar deserialized = new ObjectMapper().readValue(serialized, Bar.class);
        Assert.assertEquals(bar, deserialized);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

爱,才寂寞 2025-01-26 20:04:54

请将默认构造函数添加到 Bar 类中,我想您的问题应该得到解决。

@Getter
@Setter
@EqualsAndHashCode
public class Bar {
    FooInterface foo;
    
    public Bar() {}

    public Bar(FooInterface foo) {
        this.foo = foo;
    }
}

如果这不能解决您的问题,请告诉我,我会尝试更深入地挖掘。

Please add default constructor to class Bar and I guess your issue should be resolved.

@Getter
@Setter
@EqualsAndHashCode
public class Bar {
    FooInterface foo;
    
    public Bar() {}

    public Bar(FooInterface foo) {
        this.foo = foo;
    }
}

Do let me know if this doesn't solve your problem, I will try to dig deeper.

碍人泪离人颜 2025-01-26 20:04:54

正如@aditya提到的那样,我缺少默认构造函数,这导致了我遇到的错误,但是新错误使我找到了问题是这个问题问的问题的关键。

看来我误解了jsonautodetect注释做了什么。以下是最终为我工作的代码。

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Foo.class),
})
public interface FooInterface {
    String doThing();
}

@EqualsAndHashCode
public class Foo implements FooInterface {
    @Override
    public String doThing() {
        return "foo";
    }
}

@Getter
@Setter
@EqualsAndHashCode
public class Bar {
    FooInterface foo;

    public Bar() {}

    public Bar(FooInterface foo) {
        this.foo = foo;
    }
}

    @Test
    public void fooTest() throws IOException {
        Foo foo = new Foo();
        Bar bar = new Bar(foo);

        String serialized = new ObjectMapper().writeValueAsString(bar); // {"foo":{"type":"Foo"}}
        Bar deserialized = new ObjectMapper().readValue(serialized, Bar.class);
        Assert.assertEquals(bar, deserialized);
    }

As @Aditya mentioned I was missing the default constructor which was causing the error I was having, but then the new error led me to finding this question which was the crux of the problem that this question was asking about.

Looks like I misunderstood what the JsonAutoDetect annotation did. Below is the code that ended up working for me.

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        include = JsonTypeInfo.As.PROPERTY,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Foo.class),
})
public interface FooInterface {
    String doThing();
}

@EqualsAndHashCode
public class Foo implements FooInterface {
    @Override
    public String doThing() {
        return "foo";
    }
}

@Getter
@Setter
@EqualsAndHashCode
public class Bar {
    FooInterface foo;

    public Bar() {}

    public Bar(FooInterface foo) {
        this.foo = foo;
    }
}

    @Test
    public void fooTest() throws IOException {
        Foo foo = new Foo();
        Bar bar = new Bar(foo);

        String serialized = new ObjectMapper().writeValueAsString(bar); // {"foo":{"type":"Foo"}}
        Bar deserialized = new ObjectMapper().readValue(serialized, Bar.class);
        Assert.assertEquals(bar, deserialized);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文