Java杰克逊|如何序列化指定具体接口的对象

时间:2016-02-20 18:59:35

标签: java json interface jackson polymorphism

假设我们已经给出了Java接口:

public interface UserA {
    String getLogin();
    void setLogin(final String login);
}

public interface UserB {
    String getPassword();
    void setPassword(final String password);
}

public interface UserC {
    String getEmail();
    void setEmail(final String email);
}

接口扩展以上所有内容:

public interface User extends UserA, UserB, UserC {
}

实现用户界面的类:

public class UserImpl implements User {
    // implementation omitted
}

现在,我想序列化UserImpl对象,选择一个“小”接口(UserA,UserB,UserC)或“大”接口(用户)。

Exmaples:

  • UserA界面的预期结果

    {“login”:“John”}

  • UserB界面的预期结果

    {密码:“JohnSnow”}

  • 用户界面的预期结果

    {“login”:“John”,密码:“JohnSnow”,“email”:“john@snow.com”}

是否有任何方法可以通过将对象的一个​​接口传递给Jackson映射器来获得上述结果(通过切换接口来更改JSON)?

1 个答案:

答案 0 :(得分:2)

使用ObjectMapper#writerFor选择序列化时应使用的接口。这是一个显示此功能的通过测试。如果您使用的是没有writerFor的旧版杰克逊,那么您可以使用writerWithType

public interface A {
    String getStringA();
}

public interface B {
    String getStringB();
}

public class AB implements A, B {

    @Override
    public String getStringA() {
        return "value a";
    }

    @Override
    public String getStringB() {
        return "value b";
    }
}

@Test
public void t() throws JsonProcessingException {
    final ObjectMapper mapper = new ObjectMapper();

    final String a = mapper.writerFor(A.class).writeValueAsString(new AB());
    assertThat(a).isEqualTo("{\"stringA\":\"value a\"}");

    final String b = mapper.writerFor(B.class).writeValueAsString(new AB());
    assertThat(b).isEqualTo("{\"stringB\":\"value b\"}");
}