Jersey 和 Jackson 子类的序列化不包含额外的属性

发布于 2024-11-15 13:09:53 字数 1342 浏览 1 评论 0原文

在 Jersey 中,当使用 Jackson 进行 JSON 序列化时,不包括实现子类的额外属性。例如,给定以下类结构

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="@class")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Foo.class, name = "foo")
}
public abstract class FooBase {
    private String bar;

    public String getBar() {
        return bar;
    }

    public void setBar( String bar ) {
        this.bar = bar;
    }
}

public class Foo extends FooBase {
    private String biz;

    public String getBiz() {
        return biz;
    }

    public void setBiz( String biz ) {
        this.biz = biz;
    }
}

和以下 Jersey 代码,

@GET
public FooBase get() {
   return new Foo();
}

我得到以下 json

{"@class" => "foo", "bar" => null}

但我真正想要的是

{"@class" => "foo", "bar" => null, "biz" => null}

另外,在我的 web.xml 中我启用了 POJOMappingFeature 解决此问题

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

编辑:修复了 Java 代码以正确设置 setter,而 Foo 则不设置抽象一点

In Jersey, when using Jackson for JSON serialization, the extra attributes of an implementing subclass are not included. For example, given the following class structure

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="@class")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Foo.class, name = "foo")
}
public abstract class FooBase {
    private String bar;

    public String getBar() {
        return bar;
    }

    public void setBar( String bar ) {
        this.bar = bar;
    }
}

public class Foo extends FooBase {
    private String biz;

    public String getBiz() {
        return biz;
    }

    public void setBiz( String biz ) {
        this.biz = biz;
    }
}

And the following Jersey code

@GET
public FooBase get() {
   return new Foo();
}

I get back the following json

{"@class" => "foo", "bar" => null}

But what I actually want is

{"@class" => "foo", "bar" => null, "biz" => null}

Also, in my web.xml I have enabled POJOMappingFeature to solve this issue

<init-param>
    <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
    <param-value>true</param-value>
</init-param>

Edit: Fixed the Java code to have the setters set properly and Foo to not be abstract

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

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

发布评论

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

评论(2

a√萤火虫的光℡ 2024-11-22 13:09:54

它应该像你展示的那样工作;但有一个可能的例外:如果您(仅)启用 JAXB 注释,则 JAXB 限制强制要求仅使用 getter/setter 对来检测属性。
因此,尝试为“biz”添加设置器,看看是否会改变它。

使用 Jackson 注释就不会发生这种情况;理想情况下,如果您将 Jackson 和 JAXB 注释结合起来,则不会(我认为 Jersey 启用了两者)。
如果还启用了 Jackson 注释处理,则在“getBiz”旁边添加 @JsonProperty 也应该可以解决问题。

最后,除非您需要 JAXB 注释,否则您可以恢复为仅使用 Jackson 注释 - 在我看来,JAXB 注释的主要用例是如果您需要生成 XML 和 JSON,并使用 JAXB(通过 Jersey)处理 XML。否则它们对 JSON 没有用处。

It should work as you show; with one possible exception: if you enable JAXB annotations (only), JAXB restrictions mandate that only getter/setter pairs are used to detect properties.
So try adding setter for 'biz' and see if that changes it.

This would not occur with Jackson annotations; and ideally not if you combine Jackson and JAXB annotations (I thought Jersey enabled both).
If Jackson annotation processing is also enabled, adding @JsonProperty next to 'getBiz' should also do the trick.

Finally unless you need JAXB annotations, you could just revert to using Jackson annotations only -- in my opinion, the main use case for JAXB annotations is if you need to produce both XML and JSON, and use JAXB (via Jersey) for XML. Otherwise they aren't useful with JSON.

栀梦 2024-11-22 13:09:54

使用 POJOMappingFeature 您还可以使用 JAXB 注释您的类:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class FooBase {
    private String bar;
}

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo extends FooBase {
    private String biz;
}

Using POJOMappingFeature you can also annotate your classes with JAXB:

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public abstract class FooBase {
    private String bar;
}

@XmlType
@XmlAccessorType(XmlAccessType.FIELD)
public class Foo extends FooBase {
    private String biz;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文