如何将派生属性添加到Jackson 2序列化类?

时间:2015-10-29 07:53:43

标签: java json serialization jackson

我使用Jackson 2.22序列化一些现有对象,使用MixIn功能将真实对象与Jackson注释配置分离。

实际上我的mixin是一个接口,它声明目标类的相同方法并注释它们,这是一个例子。

目标类:

public class Product {

    // ...

    public String getName();

    public String getDescription();

    public String getPrice();

    public String getFinalPrice();

    public String getDiscount();

    // ...

}

和mixin:

public interface ProductApi {

    @JsonProperty
    public String getName();

    @JsonProperty("price")
    public String getFinalPrice();

}

我的JSON应该有一些更多的信息,可以从目标类的几个方法或字段计算出来。

杰克逊甚至可以这样做吗?

我尝试在课堂上调试mixin并在那里添加一个新方法,但那不起作用。

public class ProductApi {

    @JsonProperty
    public String getName();

    @JsonProperty("price")
    public String getFinalPrice();

    @JsonProperty("images")
    public List<String> getImages() { /* ... */ }

}

我想这是因为mixin只为目标类提供注释,但后者是为序列化而读取的。

当然,如果我用一个包含我需要的新方法的新子类更改要序列化的对象,那就可以了,但是这些对象来自我们的服务层,这意味着我必须重写所有这些方法。

我和泽西岛一起使用杰克逊,所以不想用另一个图书馆改变杰克逊。

2 个答案:

答案 0 :(得分:0)

这是我的表现。

解决方案是为字段getter指定自定义JsonSerializer实现。

首先,我将mixin interface更改为扩展实体(目标)类的class,以便它可以访问目标类数据。

public class ProductApi extends Product {

    @JsonProperty
    @Override
    public String getName() {
        return super.getName();
    };

    // ...

}

接下来,我实现了JsonSerializer,它将创建我想要的派生属性:

public static class ImagesSerializer extends JsonSerializer<String> {

    @Override
    public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
        Product p = (Product) jgen.getCurrentValue();

        int num = p.getNumberOfImages();

        List<String> imgs = new ArrayList<String>(num);

        for(int i = 0; i < num; i++) {
            String src = "/include/images/showImage.jsp?"+"id="+p.getId()+"&number="+i;
            imgs.add(src);
        }

        provider.defaultSerializeValue(imgs, jgen);
    }

}

这是一个非常简单的实现,应该进行更多的安全检查。

这样做基本上是从JSON生成器检索整个实体实例,构建一个自定义对象,然后让Jackson序列化它。
我在我的ProductApi中将其作为静态类实现,但为了简单起见。

最后,序列化程序需要绑定到JsonProperty带注释的字段:

public class ProductApi extends Product {

    @JsonProperty
    @Override
    public String getName() {
        return super.getName();
    };

    // ...

    @JsonSerialize(using=ImagesSerializer.class)
    @JsonProperty("images")
    @Override
    public String getImage() { // in my entity this returns an image number, whereas in my JSON I want a list of URLs
        return "";
    }

    // ...

}

作为旁注,似乎没有使用getImage()方法的返回值。

答案 1 :(得分:-1)

为什么不制作一些字段,应该序列化并使用Gson呢?