响应不包含零整数

时间:2016-04-14 14:00:28

标签: java json rest jersey jackson

我有宁静的API并使用Jetty作为服务器。我发送一个帖子请求来创建我的对象,其中包含一些skill列表。技能包含String id Integer 字段。当我使用0"0"将我的整数字段与get响应一起使用时,我得到的技能数组根本没有 value 字段。

@XmlRootElement
@JsonAutoDetect(isGetterVisibility = Visibility.NONE, getterVisibility = Visibility.NONE, setterVisibility = Visibility.NONE,
        creatorVisibility = Visibility.NONE, fieldVisibility = Visibility.NONE)
public class Skill
{

    @com.fasterxml.jackson.annotation.JsonProperty(value="id")
    @javax.validation.constraints.NotNull
    private java.lang.String _id;

    @com.fasterxml.jackson.annotation.JsonProperty(value="value")
    @javax.validation.constraints.NotNull
    private java.lang.Integer _value;

    // getters and setters
}

我的请求主体是这样的:

{
  // some other fields
  "skills": [{
    "id":"Swedish",
    "value":0
  },{
    "id":"Finnish",
    "value":"0"
  }]
}

对我的对象进行必要的更改后,我将其传递给通过以下行返回:

Response.ok().entity(myObject).build();

获得回复的主体是这样的:

{
  // some other fields
  "skills" : [ {
    "id" : "Finnish"
  }, {
    "id" : "Swedish"
  } ]
}

对于其他值,一切正常,但是,0似乎是如此特殊,以至于它甚至不包括该字段到对象。

问题是为什么以及如何解决?

4 个答案:

答案 0 :(得分:1)

问题出在Jackson库的版本中。

默认情况下,当我们添加JsonFeature时,我们会serializeJsonEmptyValues=false

在方法JsonFeature#initDefaultObjectMapper的情况下,我们将会到达objMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);

的位置

如果我们查看NON_EMPTY字段的javaDoc,我们会看到以下内容:

  

兼容性说明:杰克逊2.6包括更广泛的空白"   值比早先(最多2.5)或更晚(2.7及以上)   类型;特别是:基本类型的默认值(如0表示   int / java.lang.Integer和false for bool / Boolean)时间戳0为   日期/时间类型使用2.7时,定义已经收回   包含上面解释的类型(null,absent,空String,空   容器),现在可以使用指定扩展定义   NON_DEFAULT。

所以,这意味着如果使用版本2.6,则零将消失。这恰好在我们的项目中,因为我们使用Redisson,它使用2.6版本。杰克逊图书馆。

答案 1 :(得分:0)

您有类似键的不同值类型: int 0表示“Swedish”的“value”,字符串“0”表示“芬兰语”的“value”。 如果涉及按字段构建的某种对象,这可能会导致问题。

答案 2 :(得分:0)

问题不在于Jetty,Jersey或YaaS。问题似乎出现在杰克逊身上。 Jackson执行序列化/反序列化并且似乎有一些优化,因此跳过zeros

不幸的是我还没有找到任何资源,而且说明为什么你会跳过0并且我没有设法找到杰克逊代码中发生这种情况的地方。

可能的解决方案:

  1. 对您的字段使用注释@JsonInclude(JsonInclude.Include.ALWAYS),不会跳过它。
  2. 不允许为Integer字段添加零。
  3. 使用String类型代替Integer
  4. 问题是我的对象是由YaaS生成的,因此,我不能仅仅根据生成的对象进行更改,也不确定YaaS是否有可能使用1项中的注释生成对象。我假设在这种情况下,2选项可能是最好的。

答案 3 :(得分:0)

我遇到了同样的问题,但是我没有使用@ javax.validation.constraints.NotNull。

我曾经是

ObjectMapper objectMapper = new org.codehaus.jackson.map.ObjectMapper();
objectMapper.setSerializationInclusion(Include.NON_EMPTY);

MyClass myClass = new MyClass();
myClass.setStringField("some value");
myClass.setIntField(0);

String json = objectMapper.writeValueAsString(myClass);

System.out.println(json);    // --> { "stringField" : "some value" }

它没有打印零值的intField。我要做的就是更改NON_EMPTY规则:

objectMapper.setSerializationInclusion(Include.NON_ABSENT);
String json = objectMapper.writeValueAsString(myClass);
System.out.println(json);    // --> { "stringField" : "some value" }