You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Codehaus Jackson映射MongoDB JSON时votedUsers字段映射失败

解决Codehaus Jackson映射MongoDB返回的votedUsers字段问题

我看你现在遇到的问题是MongoDB返回的JSON里,其他字段都能正常映射到你的DTO,但votedUsers始终是null对吧?这问题出在你对votedUsers的结构定义和Jackson的映射逻辑不匹配上,咱们一步步来解决:

问题根源

先看你的JSON里votedUsers的结构:

"votedUsers": [ { "mng\39999": 4 }, { "abc\bis@cdf.com": 4 } ]

这是一个数组,每个元素是单个动态键值对的对象——也就是说每个对象的key是不固定的(比如第一个是mng\39999,第二个是abc\bis@cdf.com)。而你定义的VotedUsersDTO里用了private Map<String, String> votedUser;,Jackson默认会把每个数组元素当成一个Bean,去寻找名为votedUser的属性,但显然JSON里没有这个属性,所以就映射成null了。

几种可行的解决方案

方案1:让VotedUsersDTO直接继承Map

这种方式最简单,直接把VotedUsersDTO变成一个Map的实现类,这样Jackson会自动把每个动态键值对对象映射到这个Map里:

@JsonIgnoreProperties(ignoreUnknown = true)
public class VotedUsersDTO extends HashMap<String, Object> implements Serializable {
    private static final long serialVersionUID = 1L;
    // 不需要额外定义属性,直接用HashMap的get/put方法即可
}

注意这里用Object而不是String,因为JSON里的value是整数(比如4),用String会导致类型转换异常,如果你确定value都是整数,也可以用Integer。

方案2:用@JsonAnySetter注解处理动态属性

如果你不想让DTO继承Map,想保留自己的结构,可以用Jackson的@JsonAnySetter注解来捕获所有动态键值对:

@JsonIgnoreProperties(ignoreUnknown = true)
public class VotedUsersDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private Map<String, Object> votedUser = new HashMap<>();

    // 这个方法会接收所有JSON对象里的动态键值对
    @JsonAnySetter
    public void addVotedUserEntry(String key, Object value) {
        votedUser.put(key, value);
    }

    // Getter方法
    public Map<String, Object> getVotedUser() {
        return votedUser;
    }
}

这种方式更符合DTO的封装性,后续如果要扩展VotedUsersDTO的其他属性也很方便。

方案3:直接在MaterialReviewsDTO里用List<Map<String, Object>>

如果votedUsers不需要额外的业务逻辑处理,也可以直接去掉VotedUsersDTO,简化MaterialReviewsDTO的定义:

@JsonIgnoreProperties(ignoreUnknown = true)
public class MaterialReviewsDTO implements Serializable {
    private static final long serialVersionUID = 1L;
    private String _id;
    private int rates;
    private List<ReviewsDTO> reviews;
    // 直接用List of Map,省去中间DTO
    private List<Map<String, Object>> votedUsers;
    private int rating;
    
    // Getter和Setter方法
}

这种方式最简洁,适合不需要对votedUsers做额外封装的场景。

额外提醒

记得把原来VotedUsersDTO里的Map<String, String>改成Map<String, Object>或者Map<String, Integer>,因为JSON里的value是数字类型,用String会触发Jackson的类型转换错误。

内容的提问来源于stack exchange,提问作者Sumit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 09:20:17