[英]Exception while parsing json string with jackson library
这是我尝试使用Jackson
Java
库解析的json
。
它是BackgroundShape
s的Vector
。
BackgroundShape
子类包括:
BGRectangle
BGCircle
在这个json
片段中,有2个BGRectangle
,但也可能包含BGCircle
,它们与BGRectangle
的属性不同。
所以我想解析以便能够处理json
各种类类型
{
"bgShapes": [
{
"@class" : "com.code.test.BGRectangle",
"position": {
"x": -110.0,
"y": -28.0,
"z": -6.0
},
"angle": 0.0,
"width": 10.0,
"height": 10.0,
"textureSelection": "NUKE"
},
{
"@class" : "com.code.test.BGRectangle",
"position": {
"x": 10.0,
"y": 8.0,
"z": -6.0
},
"angle": 0.0,
"width": 1.0,
"height": 1.0,
"textureSelection": "NUKE"
}
]
}
Main.java
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(org.jbox2d.common.Vec3.class.class, Vec3Mixin.class);
Level zoo = mapper.readValue(new File("levels/level1.json"), Level.class);
现在得到这个异常:
Exception in thread "main" com.fasterxml.jackson.databind.JsonMappingException: Could not find creator property with name 'position' (in class com.code.test.BackgroundShape)
at [Source: levels/level1.json; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:584)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.addBeanProps(BeanDeserializerFactory.java:551)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:267)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:168)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:405)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:354)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:267)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:247)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:305)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.createContextual(CollectionDeserializer.java:23)
at com.fasterxml.jackson.databind.DeserializationContext.findContextualValueDeserializer(DeserializationContext.java:309)
at com.fasterxml.jackson.databind.deser.impl.PropertyBasedCreator.construct(PropertyBasedCreator.java:96)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:414)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:298)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:247)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:322)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:2990)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2884)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:1988)
at com.code.test.Main.main(Main.java:16)
Level.java
@JsonTypeInfo(use = JsonTypeInfo.Id.MINIMAL_CLASS, include = As.PROPERTY, property = "@class")
public class Level {
private Vector<BackgroundShape> bgShapes = new Vector<BackgroundShape>();
@JsonCreator
public Level(@JsonProperty("bgShapes") Vector<BackgroundShape> bgShapes) throws GLException, IOException {
this.bgShapes = bgShapes;
System.out.println("Level created");
}
}
Shape.java
public abstract class Shape{
@JsonProperty("textureSelection") protected String textureSelection;
@JsonCreator
public Shape(@JsonProperty("textureSelection") String textureSelection) {
this.textureSelection = textureSelection;
}
}
BackgroundShape.java
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "@class")
@JsonSubTypes({
@JsonSubTypes.Type(value = BGRectangle.class, name = "BGRectangle"),
@JsonSubTypes.Type(value = BGCircle.class, name = "BGCircle") })
public abstract class BackgroundShape extends Shape {
@JsonProperty("position") private Vec3 position;
@JsonProperty("angle") private float angle;
@JsonCreator
public BackgroundShape(
@JsonProperty("position") Vec3 position,
@JsonProperty("angle") float angle,
@JsonProperty("textureSelection") String textureSelection) {
super(textureSelection);
this.position = position;
this.angle = angle;
}
}
BGRectangle.java
public class BGRectangle extends BackgroundShape{
@JsonProperty("width") private float width;
@JsonProperty("height") private float height;
@JsonCreator
public BGRectangle (
@JsonProperty("position") Vec3 position,
@JsonProperty("angle") float angle,
@JsonProperty("width") float width,
@JsonProperty("height") float height,
@JsonProperty("textureSelection")String textureSelection) {
super(position, angle, textureSelection);
this.width = width;
this.height = height;
};
}
编辑:添加了mixin
抽象类到ObjectMapper
..
public abstract class Vec3Mixin {
public Vec3Mixin(
@JsonProperty("x") float x,
@JsonProperty("y") float y,
@JsonProperty("z") float z) {
}
}
我假设Vec3
是第三方类(可能来自Java库的OpenGL绑定),具有以下构造函数:
public Vec3(float x, float y, float z) {
// ...
}
当杰克逊在反序列化过程中遇到此类时,她想实例化它,但是此类仅具有三个参数的类就没有noarg构造函数。 由于参数名称在运行时不可用,因此Jackson无法确定应将JSON的哪些属性分配给哪个构造函数参数。 要解决此问题,通常可以使用@JSONProperty
注释构造函数参数(就像对其他类所做的那样),但是此类不受您控制。
在这种情况下,可以使用Jackson Mixin注释向Jackson提供必要的信息。 首先定义一个mixin抽象类:
public abstract class Vec3Mixin {
public Vec3Mixin(@JsonProperty("x") float x,
@JsonProperty("y") float y,
@JsonProperty("z") float z) {
}
}
最后,mixin类必须与原始类相关联:
ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(Vec3.class, Vec3Mixin.class);
Level zoo = mapper.readValue(new File("levels/level1.json"), Level.class);
为了完整起见,这是混合功能的正式文档: http : //wiki.fasterxml.com/JacksonMixInAnnotations (但在撰写本文时不起作用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.