如何用jackson-databind反序列化toplyrics为列表?空指针问题求助
反序列化JSON时toplyrics字段NullPointerException问题排查与解决
问题描述
使用jackson-databind解析JSON数据时,artist名称能正常解析,但解析toplyrics字段时出现NullPointerException,提示响应为null。
JSON结构
{"artist": {"id": "3ade68b5gd237eda3","desc": "Kiss","url": "/kiss/","pic_small": "/kiss/images/profile.jpg","pic_medium": "/kiss/images/kiss.jpg","rank": {"pos": "350","period": 202404,"views": "1372","uniques": "936","points": "5.0"},"genre": [{"name": "Hard Rock","url": "/browse/style/hard-rock.html"},{"name": "Heavy Metal","url": "/browse/style/heavy-metal.html"},{"name": "Rock","url": "/browse/style/rock.html"},{"name": "Classic Rock","url": "/browse/style/classic-rock.html"}],"related": [{"id": "3ade68b5gb2c7eda3","name": "Van Halen","url": "/van-halen/"},{"id": "3ade68b5g2cd6eda3","name": "Deep Purple","url": "/deep-purple/"},{"id": "3ade68b4gdda6eda3","name": "Black Sabbath","url": "/black-sabbath/"},{"id": "3ade68b5g0187eda3","name": "Ramones","url": "/the-ramones/"},{"id": "3ade68b3g0c86eda3","name": "Led Zeppelin","url": "/led-zeppelin/"},{"id": "3ade68b5gb1b8eda3","name": "Ozzy Osbourne","url": "/ozzy-osbourne/"},{"id": "3ade68b6g28c9eda3","name": "Rolling Stones","url": "/the-rolling-stones/"},{"id": "3ade68b5g1bf7eda3","name": "Queen","url": "/queen/"},{"id": "3ade68b5g2297eda3","name": "Scorpions","url": "/scorpions/"},{"id": "3ade68b5g8227eda3","name": "Iron Maiden","url": "/iron-maiden/"}],"toplyrics": {"item": [{"id": "3ade68b8gace4afa3","desc": "Danger Us","url": "/kiss/danger-us.html","turl": "/kiss/danger-us-traducao.html"},{"id": "3ade68b6gbfebeda3","desc": "Dark Light","url": "/kiss/dark-light.html","turl": "/kiss/dark-light-traducao.html"},{"id": "3ade68b8gb764efa3","desc": "Deadly Weapons (The Elder demo)","url": "/kiss/deadly-weapons-the-elder-demo.html"}]}}}}
原实体类代码
ApiResponse类
package com.pedruuv.sound.models; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public record ApiResponse(@JsonAlias("artist") ArtistData artist, @JsonAlias("toplyrics") SongData lyrics, @JsonAlias("albums") AlbumData album){ }
SongData类
package com.pedruuv.sound.models; import java.util.List; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public record SongData(@JsonAlias("item") List<Music> songs) { }
Music类
package com.pedruuv.sound.models; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public record Music(@JsonAlias("desc") String title) { }
问题根源
观察JSON结构可知,toplyrics字段并非根节点下的直接字段,而是嵌套在artist对象内部的子字段。但原ApiResponse类中直接将toplyrics映射为根级属性,Jackson无法在根节点找到该字段,导致lyrics变量被赋值为null,后续访问其内部属性时就会触发NullPointerException。
解决方案
调整实体类结构,将toplyrics字段移到ArtistData类中,使其与JSON的层级结构匹配:
修改后的ArtistData类(补充原缺失字段)
package com.pedruuv.sound.models; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import java.util.List; @JsonIgnoreProperties(ignoreUnknown = true) public record ArtistData( @JsonAlias("id") String id, @JsonAlias("desc") String name, @JsonAlias("url") String url, @JsonAlias("pic_small") String picSmall, @JsonAlias("pic_medium") String picMedium, @JsonAlias("rank") RankData rank, @JsonAlias("genre") List<GenreData> genres, @JsonAlias("related") List<RelatedArtistData> relatedArtists, @JsonAlias("toplyrics") SongData topLyrics // 添加toplyrics字段 ) {} // 补充所需辅助实体类 @JsonIgnoreProperties(ignoreUnknown = true) record RankData( @JsonAlias("pos") String position, @JsonAlias("period") int period, @JsonAlias("views") String views, @JsonAlias("uniques") String uniques, @JsonAlias("points") String points ) {} @JsonIgnoreProperties(ignoreUnknown = true) record GenreData( @JsonAlias("name") String name, @JsonAlias("url") String url ) {} @JsonIgnoreProperties(ignoreUnknown = true) record RelatedArtistData( @JsonAlias("id") String id, @JsonAlias("name") String name, @JsonAlias("url") String url ) {}
修改后的ApiResponse类
移除根级的toplyrics映射,因为该字段已归属到ArtistData内部:
package com.pedruuv.sound.models; import com.fasterxml.jackson.annotation.JsonAlias; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) public record ApiResponse( @JsonAlias("artist") ArtistData artist, @JsonAlias("albums") AlbumData album ) {}
验证
修改后,Jackson会正确识别嵌套在artist下的toplyrics字段,将其反序列化为ArtistData中的topLyrics属性,避免null值出现,后续访问artist.topLyrics().songs()时就不会触发NullPointerException。
内容的提问来源于stack exchange,提问作者PedroVitorGl
相关产品推荐
相关产品推荐

