我试图序列化不可改变的POJO,并从JSON,使用杰克逊2.1.4,而无需编写自定义序列,并用尽可能少的注释越好。 我也很喜欢,以避免增加不必要的getter或默认构造正好满足了杰克逊库。
现在我卡除外上:
JsonMappingException:找到类型没有合适的构造[简单类型,类圆]:不能从JSON对象实例化(需要添加/启用类型信息?)
代码:
public abstract class Shape {}
public class Circle extends Shape {
public final int radius; // Immutable - no getter needed
public Circle(int radius) {
this.radius = radius;
}
}
public class Rectangle extends Shape {
public final int w; // Immutable - no getter needed
public final int h; // Immutable - no getter needed
public Rectangle(int w, int h) {
this.w = w;
this.h = h;
}
}
测试代码:
ObjectMapper mapper = new ObjectMapper();
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // Adds type info
Shape circle = new Circle(10);
Shape rectangle = new Rectangle(20, 30);
String jsonCircle = mapper.writeValueAsString(circle);
String jsonRectangle = mapper.writeValueAsString(rectangle);
System.out.println(jsonCircle); // {"@class":"Circle","radius":123}
System.out.println(jsonRectangle); // {"@class":"Rectangle","w":20,"h":30}
// Throws:
// JsonMappingException: No suitable constructor found.
// Can not instantiate from JSON object (need to add/enable type information?)
Shape newCircle = mapper.readValue(jsonCircle, Shape.class);
Shape newRectangle = mapper.readValue(jsonRectangle, Shape.class);
System.out.println("newCircle = " + newCircle);
System.out.println("newRectangle = " + newRectangle);
任何帮助非常感谢,谢谢!
你可以(根据API)注释与构造@JsonCreator并与参数@JsonProperty 。
public class Circle extends Shape {
public final int radius; // Immutable - no getter needed
@JsonCreator
public Circle(@JsonProperty("radius") int radius) {
this.radius = radius;
}
}
public class Rectangle extends Shape {
public final int w; // Immutable - no getter needed
public final int h; // Immutable - no getter needed
@JsonCreator
public Rectangle(@JsonProperty("w") int w, @JsonProperty("h") int h) {
this.w = w;
this.h = h;
}
}
编辑:也许你有注释Shape类@JsonSubTypes使形状的具体子类可以被确定。
@JsonSubTypes({@JsonSubTypes.Type(Circle.class), @JsonSubTypes.Type(Rectangle.class)})
public abstract class Shape {}
看看Genson库它的一些主要特性adressing您的具体问题:多态,不需要注解和最重要的不变的POJO。 一切正常,分别以0注释或重的conf你的榜样。
Genson genson = new Genson.Builder().setWithClassMetadata(true)
.setWithDebugInfoPropertyNameResolver(true)
.create();
String jsonCircle = genson.serialize(circle);
String jsonRectangle = genson.serialize(rectangle);
System.out.println(jsonCircle); // {"@class":"your.package.Circle","radius":123}
System.out.println(jsonRectangle); // {"@class":"your.package.Rectangle","w":20,"h":30}
// Throws nothing :)
Shape newCircle = genson.deserialize(jsonCircle, Shape.class);
Shape newRectangle = genson.deserialize(jsonRectangle, Shape.class);
Genson给你也使用别名(代替类名)的能力。
new Genson.Builder().addAlias("shape", Shape.class)
.addAlias("circle", Circle.class)
.create();
矩形有两个参数,和常见问题解答说:
反序列化简单类型
如果我想不是默认支持的反序列化简单的JSON值(字符串,整数/十进制数)转换成其他类型的,我需要写一个自定义解串器?
不必要。 如果类反序列化成了之一:
- 单个参数的构造与匹配的类型(字符串,整数/双),或
- 名为“的valueOf()”,和匹配参数类型单参数静态方法
杰克逊将使用这样的方法,传入JSON值匹配作为参数。
恐怕你必须写自己的解串器作为表演杰克逊文件中 :
ObjectMapper mapper = new ObjectMapper();
SimpleModule testModule =
new SimpleModule("MyModule", new Version(1, 0, 0, null))
.addDeserializer( MyType.class, new MyTypeDeserializer());
mapper.registerModule( testModule );