Spring boot,Jackson Json 在序列化和反序列化时出现问题

Posted

技术标签:

【中文标题】Spring boot,Jackson Json 在序列化和反序列化时出现问题【英文标题】:Spring boot, Jackson Json Issue while serializing and deserializing 【发布时间】:2017-10-30 13:23:03 【问题描述】:

对于某些用例,我需要将一个 POJO 转换为具有不同字段名称的另一个 POJO。我尝试使用杰克逊对象映射器。它在某些方面起作用。然而最终结果并不是我所期望的。

public class JacksonTest 

    public static void main(String[] args) throws IOException
        ObjectMapper mapper = new ObjectMapper();
        User user = new User("Deepak", "111", "Singapore");
        UserMap newUser = mapper.convertValue(user, UserMap.class);
        System.out.println("SOUT: " + newUser);
        System.out.println("Jackson: " + mapper.writeValueAsString(newUser));
    


class User 

    User(String name, String id, String address)
        this.name = name;
        this.id = id;
        this.address = address;
    

    String name;
    String id;
    String address;

    public String getName() 
        return name;
    

    public void setName(String name) 
        this.name = name;
    

    public String getId() 
        return id;
    

    public void setId(String id) 
        this.id = id;
    

    public String getAddress() 
        return address;
    

    public void setAddress(String address) 
        this.address = address;
    


class UserMap implements Serializable 
    @JsonProperty("name")
    String name;

    private Map<String, Object> meta = new HashMap<>();

    @JsonAnyGetter
    public Map<String, Object> any() 
        return meta;
    

    @JsonAnySetter
    public void set(String name, Object value) 
        meta.put(name, value);
    

    @Override
    public String toString() 
        return "UserMap" +
                "name_new='" + name + '\'' +
                ", meta=" + meta.keySet().stream().map(x-> x+ ":: "+ meta.get(x)).collect(Collectors.joining(", ")) +
                '';
    

如果你运行,输出将是:

SOUT: UserMapname_new='Deepak', meta=address:: Singapore, id:: 111

杰克逊:"name":"Deepak","address":"Singapore","id":"111"

我正在使用内部使用杰克逊序列化程序的 Springboot。它将 newUser 对象再次转换为普通用户类。我想以类构造的方式序列化字符串。我想要 SOUT 格式的输出。

【问题讨论】:

【参考方案1】:

我认为您误解了 @JsonAnyGetter/@JsonAnySetter 对实际上会做什么。

它允许您创建一个几乎是动态的 bean,其中包含必填字段和自愿字段。在您的情况下,该名称是强制性的,所有其他字段都是自愿的。

幕后发生的事情不是您的UserMap 被转换为User。您看到的是一个序列化的 UserMap,但由于它与对应的 User 实例具有相同的字段和值,因此它们的序列化形式看起来相同。

【讨论】:

我了解它的工作原理。对于某些要求,我需要的方法是构造对象类。现在我正在创建一个 POJO,并在序列化之前感受所有这些数据。 @DeepakSharma 我不明白你所说的“我需要的方法是构造对象类”是什么意思。还有,在序列化之前创建POJO并填写数据有什么问题?【参考方案2】:

我无法使用默认的 Spring 引导 bean 使自动序列化和反序列化工作。最后,在包含 Project Lombok 和 apache BeanUtils 之后,这对我来说效果很好:

@ToString() @Getter() @Setter() @NoArgsConstructor()
public class User 
    private String email;
    private String bio;
    private String image;
    private String displayName;
    private String userId;
    private long lat;
    private long lng;

    public User(String json) throws JsonParseException, JsonMappingException, IOException, IllegalAccessException, InvocationTargetException 
        ObjectMapper om = new ObjectMapper();
        User u = om.readValue(json, User.class);
        BeanUtils.copyProperties(this, u);
    

http://commons.apache.org/proper/commons-beanutils/download_beanutils.cgi https://projectlombok.org/

【讨论】:

以上是关于Spring boot,Jackson Json 在序列化和反序列化时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

尝试通过 Spring Boot Rest 使用 Jackson 验证 JSON

Spring Boot (Jackson):如何避免类名被序列化为 JSON

Spring Boot—08Jackson处理JSON

Spring MVC 接收的 JSON 嵌套对象的 Spring Boot JACKSON 配置

Spring Boot的Jackson JSON映射器[关闭]

在 Jackson / Spring Boot 中测试自定义 Json Deserializer