首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对Jackson JSON属性名称如何序列化感到困惑

对Jackson JSON属性名称如何序列化感到困惑
EN

Stack Overflow用户
提问于 2022-11-02 15:17:16
回答 1查看 49关注 0票数 1

我读过杰克逊如何假设JavaBeans对象遵循JavaBeans约定,并且JSON属性名称将基于getter/setter方法(也就是说,如果存在getName,它将在JSON中查找名称属性,setName将将name类字段写入JSON字符串)。为什么它不是由类变量名称决定的?

我看了Baeldung教程,并试图寻找关于杰克逊为什么工作或如何工作的文档,但没有一个解释原因。它只展示了如何使用注释,或者如何解决您可能希望读取列表、HashMap、忽略字段等特定情况。

本教程解释了如何使用getter和setter方法使字段可序列化/反序列化,但是当使用不遵循JavaBeans约定的Java对象时,如何确定写入JSON字符串的内容?我使用以下注释读取包含书籍数组的.json文件:

代码语言:javascript
复制
 import com.fasterxml.jackson.annotation.JsonAlias;
    import com.fasterxml.jackson.annotation.JsonCreator;
    import com.fasterxml.jackson.annotation.JsonGetter;
    import com.fasterxml.jackson.annotation.JsonProperty;
    import com.fasterxml.jackson.annotation.JsonSetter;
    
    public class Book implements Comparable<Book>{
        private String title;
        private String author;
        //match a field in json string to pojo when names dont match
        @JsonSetter("isbn-10") 
    //  @JsonProperty("isbn")
    //  @JsonAlias("isbn-10")
        private String isbn;
        
        @JsonCreator
        public Book(@JsonProperty("title") String title,@JsonProperty("author") 
                                String author,@JsonProperty("isbn") String isbn) {
            this.title = title;
            this.author = author;
            this.isbn = isbn;
        }
    
        public String getTitle() {
            return title;
        }
    
        public String getAuthor() {
            return author;
        }
    
        @JsonGetter("isbn")
        public String getIsbn() {
            return isbn;
        }
        
        public int compareTo(Book book) {
            return this.getTitle().compareTo(book.getTitle());
        }
    }

示例json文件内容:

代码语言:javascript
复制
[
{
        "title":"Day Knight",
        "author":"Pun R. Good",
        "isbn-10":"830456394-2"
    }
]

但是,如果我不使用isbn指定JsonGetter注释,则会得到以下错误:

java.lang.IllegalStateException:相互冲突/模棱两可的属性名定义(隐式名称'isbn'):找到多个显式名称: isbn-10,isbn,但也包括隐式访问器:方法com.fdmgroup.jacksonexercise.Book#getIsbn()

但是,如果我使用注释掉的JsonAliasJsonProperties而不是getter和setter注释,这个问题根本不会发生。为什么它迫使我指定getter的注释,当getter是遵循约定的常规getter,而不是像getTheIsbn()这样奇怪的getter名称时。

为什么它不使用isbn-10isbn读入类字段isbn,并根据变量名和值写出属性(如果需要进一步调整名称,则使用JsonGetterJsonProperties )?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-11-02 15:46:36

但是,如果不使用isbn指定

注释,则会得到以下错误:

你把所有的东西都混合在一起,就会有很多冗余。

首先,由于您已经通过用@JsonCreator注释构造函数来定义创建者,所以杰克逊对setter不再感兴趣(只需要使用一个非args构造函数)。因此,您可以阅读@JsonSetter

因为您需要指定isbn属性的多个别名,所以@JsonAlias是正确的方法。这些名称只会在来自JSON的deserialization中考虑,并且不会对序列化产生影响。

代码语言:javascript
复制
@JsonAlias({"isbn", "isbn-10"})

而且,由于您对POJO中的字段名isbn很满意,杰克逊可以从getter名称getIsbn()中推断出这一点,所以使用@JsonGetter("isbn")是多余的。如果您需要更改它,例如@JsonGetter("ISBN")*或@JsonGetter("isbn-10") (方法名getIsbn-10()在Java中是非法的),这将是有用的。

话虽如此,你的课看起来可能是这样的:

代码语言:javascript
复制
public class Book implements Comparable<Book> {
    private String title;
    private String author;

    @JsonAlias({"isbn", "isbn-10"})
    private String isbn;
    
    @JsonCreator
    public Book(@JsonProperty("title") String title,
                @JsonProperty("author") String author,
                @JsonProperty("isbn-10") String isbn) {
        this.title = title;
        this.author = author;
        this.isbn = isbn;
    }
    
    public String getTitle() {
        return title;
    }
    
    public String getAuthor() {
        return author;
    }
    
    public String getIsbn() {
        return isbn;
    }
    
    public int compareTo(Book book) {
        return this.getTitle().compareTo(book.getTitle());
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74291562

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档