杰克逊有条件@JsonUnwrapped

时间:2014-08-21 11:39:43

标签: java json jackson

我可以有条件地使用@JsonUnwrapped吗?我不希望在序列化期间使用它,但想在反序列化对象时使用它。

实现它的一种方法是创建两个不同的类或创建一个子类,只覆盖该序列化和反序列化时需要表现不同的属性。这听起来不对。任何其他替代方案或杰克逊方式解决问题?

2 个答案:

答案 0 :(得分:2)

您可以使用MixIn feature。使用此功能POJO类与Jackson注释分离。您可以使用MixIn在运行时添加必要的注释。见下面的例子:

import com.fasterxml.jackson.annotation.JsonUnwrapped;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonTest {

    private static final String UNWRAPPED_JSON = "{\n" +
            "  \"age\" : 13,\n" +
            "  \"first\" : \"Huckleberry\",\n" +
            "  \"last\" : \"Finn\"\n" +
            "}";

    @Test
    public void test() throws IOException {
        System.out.println("### Serialize without unwrapped annotation ###");
        ObjectMapper serializer = new ObjectMapper();
        System.out.println(serializer.writerWithDefaultPrettyPrinter().writeValueAsString(createParent()));

        System.out.println("### Deserialize with unwrapped annotation ###");
        ObjectMapper deserializer = new ObjectMapper();
        deserializer.addMixInAnnotations(Parent.class, ParentMixIn.class);
        System.out.println(deserializer.readValue(UNWRAPPED_JSON, Parent.class));
    }

    private Parent createParent() {
        Name name = new Name();
        name.first = "Tom";
        name.last = "Sawyer";

        Parent parent = new Parent();
        parent.setAge(12);
        parent.setName(name);

        return parent;
    }
}

class Parent {

    private int age;
    private Name name;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Name getName() {
        return name;
    }

    public void setName(Name name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Parent{" +
                "age=" + age +
                ", name=" + name +
                '}';
    }
}

interface ParentMixIn {

    @JsonUnwrapped
    Name getName();
}

class Name {

    public String first, last;

    @Override
    public String toString() {
        return "Name{" +
                "first='" + first + '\'' +
                ", last='" + last + '\'' +
                '}';
    }
}

以上程序打印:

### Serialize without unwrapped annotation ###
{
  "age" : 12,
  "name" : {
    "first" : "Tom",
    "last" : "Sawyer"
  }
}

### Deserialize with unwrapped annotation ###
Parent{age=13, name=Name{first='Huckleberry', last='Finn'}}

答案 1 :(得分:2)

有一种更简单的方法可以实现仅基于注释的相同结果:

@JsonUnwrapped(prefix = "name_")
@JsonProperty(access = READ_ONLY)
private Name nameObject;

// method will deserialize original JSON and set it to unwrapped field
@JsonSetter
public void setName(Name name) {
  this.nameObject = name;
}

// simple getter
@JsonIgnore
public Name getName() {
  return this.nameObject;
}