我有宁静的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似乎是如此特殊,以至于它甚至不包括该字段到对象。
问题是为什么以及如何解决?
答案 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并且我没有设法找到杰克逊代码中发生这种情况的地方。
可能的解决方案:
@JsonInclude(JsonInclude.Include.ALWAYS)
,不会跳过它。Integer
字段添加零。String
类型代替Integer
。问题是我的对象是由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" }