【问题标题】:Duplicate json property when converting java object to json string using jackson使用jackson将java对象转换为json字符串时重复json属性
【发布时间】:2012-10-27 02:13:04
【问题描述】:

我有 Pojo 对象,用 getAsJson 函数返回这个对象的 Json 字符串。 我使用 JsonProperty 在这个对象中定义 json 属性。 使用 ObjectMapper 的 writeValueAsString 为该对象写入 json 字符串。

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;

@JsonIgnoreProperties(ignoreUnknown=true)
public class LogLikeArticleDetail extends BaseObject {
    private static final long serialVersionUID = -2018373118257019033L;
    @JsonProperty("LikeArticleGUId")
    private String likeArticleGUId;
    @JsonProperty("UserId")
    private String userID;
    @JsonProperty("UserName")
    private String userName;
    @JsonProperty("IP") 
    private String ip;
    @JsonProperty("OS") 
    private String os;
    @JsonProperty("UserAgent") 
    private String userAgent;
    @JsonProperty("WebsiteCode") 
    private String websiteCode;
    @JsonProperty("ArticleId") 
    private String articleID;
    @JsonProperty("ATitle") 
    private String aTitle;
    @JsonProperty("CateAlias") 
    private String cateAlias;
    @JsonProperty("LikeStatus") 
    private String likeStatus;
    @JsonProperty("TimeStamp") 
    private Date timeStamp;
        //get, set....
        //....
        @JsonIgnore
    public String getAsJSON() throws JsonGenerationException, JsonMappingException,    IOException{
        ObjectMapper mapper = new ObjectMapper();
        return mapper.writeValueAsString(this) ; 
    }
}

现在,我得到了结果

public static void main(String[] args) throws JsonGenerationException, JsonMappingException, IOException {
        Calendar calendar =  Calendar.getInstance();
        LogLikeArticleDetail logLikeArticle = new LogLikeArticleDetail("1","2","3","4","5","6","7","8","what thing \"nothing\" show","10","11",calendar.getTime());
        System.out.println(logLikeArticle.getAsJSON());
    }

但结果的重复属性:

{"LikeArticleGUId":"1","UserId":"2","UserName":"3","IP":"4","OS":"5","UserAgent":"6","WebsiteCode":"7","ArticleId":"8","ATitle":"what thing \"nothing\" show","CateAlias":"10","LikeStatus":"11","TimeStamp":1352256727062,"_likeArticleGUId":"1","websiteCode":"7","likeStatus":"11","userID":"2","userName":"3","ip":"4","os":"5","userAgent":"6","articleID":"8","aTitle":"what thing \"nothing\" show","cateAlias":"10","timeStamp":1352256727062}

告诉我这个问题发生了什么?

【问题讨论】:

标签: java json properties duplicates jackson


【解决方案1】:

所以我确实遵循: how to specify jackson to only use fields - preferably globally

我加了

@JsonAutoDetect(fieldVisibility = Visibility.ANY, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE)

之前

public class LogLikeArticleDetail extends BaseObject

以及我想要的结果。

那么可以在 getAsJson() 函数中解决这个问题,例如:

ObjectMapper mapper  = new ObjectMapper();
mapper.setVisibilityChecker(mapper.getSerializationConfig().getDefaultVisibilityChecker()
                .withFieldVisibility(JsonAutoDetect.Visibility.ANY)
                .withGetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withSetterVisibility(JsonAutoDetect.Visibility.NONE)
                .withCreatorVisibility(JsonAutoDetect.Visibility.NONE));
return mapper.writeValueAsString(this) ;

感谢@Sean Carpenter 的问题和上面链接中的@kmb385 回答。

【讨论】:

【解决方案2】:

您也可以使用注释为每个 POJO 执行此操作。将此字符串添加到您不希望自动检测的类的顶部:

@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE, setterVisibility=JsonAutoDetect.Visibility.NONE, creatorVisibility=JsonAutoDetect.Visibility.NONE)

例如:

@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY, getterVisibility=JsonAutoDetect.Visibility.NONE,
        setterVisibility=JsonAutoDetect.Visibility.NONE, creatorVisibility=JsonAutoDetect.Visibility.NONE)
class Play {
    @JsonProperty("Name")
    private String name; 

    @JsonProperty("NickName")
    private String nickName; 

    public Play(){

    }

    public String getName() {
        return name;
    }

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

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }
}

这将返回我定义的属性,而不是自动检测字段名称并将它们添加到我返回的 JSON 结果中。

【讨论】:

    【解决方案3】:

    我们也可以直接在getter上使用@JsonProperty("Name")注解来避免重复。

    【讨论】:

    • 这可能是最简单的解决方案。当对象必须由消费者反序列化时,显然是调用 getter。谢谢@Gogol
    【解决方案4】:

    这实际上不是问题。所以,这里发生的事情是 Jackson 库无法自动匹配这些字段(没有大小写统一的假设),所以你最终得到的属性是你期望的两倍。

    解决这个问题的简单方法是向 getter/setter 中添加注释(任何一个都可以。)

    @JsonProperty("UserName")
    public String getUserName() {
            return this.userName;
    }
    

    Jackson Github 存储库中也提出了这个问题。您可以在以下链接中找到答案。

    https://github.com/FasterXML/jackson-databind/issues/1609

    【讨论】:

      猜你喜欢
      • 2018-07-19
      • 1970-01-01
      • 2021-01-16
      • 1970-01-01
      • 2018-06-26
      • 2013-03-25
      • 1970-01-01
      • 2016-09-24
      • 2020-01-30
      相关资源
      最近更新 更多