响应不包含零整数

Response does not contain zero integers

我有 restful API 并使用 Jetty 作为服务器。我发送了一个 post 请求来创建我的对象,其中包含一些 skill 列表。技能包含 String idInteger value 字段。当我使用 0"0" 作为我的整数字段并获得响应时,我得到的技能数组根本没有 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();

get响应的正文是这样的:

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

使用其他值一切正常,但是,0 似乎很特别,它甚至不将此字段包含到对象中。

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

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

问题不在 Jetty、Jersey 或 YaaS 中。问题似乎出在杰克逊身上。 Jackson 做了 serialization/deserialization 并且似乎有一些优化,因此 zeros 被跳过了。

不幸的是,我还没有找到任何资源来确切说明为什么你会跳过 0,而且我没能在 Jackson 代码中找到发生这种情况的地方。

可能的解决方案:

  1. 为您的字段使用注释 @JsonInclude(JsonInclude.Include.ALWAYS),它不会被跳过。
  2. 您的 Integer 字段不允许使用零。
  3. 使用 String 类型代替 Integer

问题是我的对象是由 YaaS 生成的,因此,我不能只根据生成的对象进行更改,并且不确定 YaaS 是否有可能生成带有第 1 项注释的对象。我认为在这种情况下,选项 2 可能是最好的。

问题出在 Jackson 库的版本上。

当我们默认添加 JsonFeature 时,我们有 serializeJsonEmptyValues=false.

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

的地步

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

Compatibility note: Jackson 2.6 included a wider range of "empty" values than either earlier (up to 2.5) or later (2.7 and beyond) types; specifically: Default values of primitive types (like 0 for int/java.lang.Integer and false for bool/Boolean) Timestamp 0 for date/time types With 2.7, definition has been tightened back to only containing types explained above (null, absent, empty String, empty containers), and now extended definition may be specified using NON_DEFAULT.

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

我遇到了同样的问题,但我没有使用@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" }