【发布时间】:2016-01-02 00:42:00
【问题描述】:
我有一个奇怪的问题,当服务器通过 REST 接收到 JSON 时,Jackson 尝试将 String 转换为 Integer:
BlockquoSchwerwiegend:MappableContainerException 中包含的异常无法映射到响应,重新抛出到 HTTP 容器 com.fasterxml.jackson.databind.exc.InvalidFormatException:无法从字符串值“之前”构造 int 的实例:不是有效的整数值 在 [来源:org.apache.catalina.connector.CoyoteInputStream@3916f0;行:1,列:182](通过引用链:com.entities.SectionRelation["listLinkLabel"]->java.util.HashSet[0]->com.entities.LinkLabel["linkLabel"]) 在 com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:55) 在 com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:883) 在 com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseInteger(StdDeserializer.java:411) 在 com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:289) 在 com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:271) 在 com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeSetAndReturn(ObjectIdValueProperty.java:85) 在 com.fasterxml.jackson.databind.deser.impl.ObjectIdValueProperty.deserializeAndSet(ObjectIdValueProperty.java:77) 在 com.fasterxml.jackson.databind.deser.impl.BeanPropertyMap.findDeserializeAndSet(BeanPropertyMap.java:285) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:335) 在 com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeWithObjectId(BeanDeserializerBase.java:1045) 在 com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:140) 在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:240) 在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:212) 在 com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25) 在 com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:523) ...
这是应该出现错误的实体:
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
/**
* The label name is unique and is therefore the
* primary key.
*/
@Entity
@JsonIdentityInfo(
generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "linkLabel")
public class LinkLabel implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@JsonFormat(shape = JsonFormat.Shape.STRING)
@Column(name = "LinkLabel")
@GeneratedValue(strategy = GenerationType.AUTO)
private String linkLabel;
@JsonIgnore
@ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE })
@JoinTable(
name="LINKLABEL_LINKSET",
joinColumns={@JoinColumn(name="LINKLABEL_ID", referencedColumnName="LinkLabel")},
inverseJoinColumns={@JoinColumn(name="LINK_LABEL_SET_ID", referencedColumnName="id")})
private Set<LinkSet> linkSet = new HashSet();
public String getLinkLabel() {
return linkLabel;
}
public void setLinkLabel(String linkLabel) {
this.linkLabel = linkLabel;
}
public Set<LinkSet> getLinkSet() {
return linkSet;
}
public void addLinkSet(LinkSet linkSet) {
this.linkSet.add(linkSet);
}
}
这是一个由服务器发送的 JSON 示例:
{
"links": [{
"id": 2,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [{
"linkLabel": 1,
"linkLabel": "after"
}]
}, {
"id": 5,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [{
"linkLabel": 2,
"linkLabel": "before"
}, {
"linkLabel": 3,
"linkLabel": "overlap"
}, 1]
}, {
"id": 3,
"section1": {
...
},
"section2": {
...
},
"listLinkLabel": [3]
}
}
这是负责前端的sn-p:
this.addLink = function(source, target) {
var JSONTemplate = {
"id":null,
"section1":{
...
},
"section2":{
...
},
"listLinkLabel":[{
// "linkLabel": 1
// ,
"linkLabel": "before"
}]
};
$http.post('service/sectionrelation', JSON.stringify(JSONTemplate));
}
我不明白为什么杰克逊试图将“linkLabel”“之前”转换为整数,当类型定义为字符串时,即使@JsonFormat 也没有改变任何东西。只有 ""linkLabel": 1" 不会引起错误,但必须有可能只发送 ""linkLabel": "before""。这对我来说似乎非常基本和简单,因为这是实体的正常表示。
在 pom.xml 中,Jackson 使用 2.6.3,GlassFish 4.1 是应用服务器。
【问题讨论】: