Java 使用MongoDB、Jackson和MongoJack的自定义序列化程序
我有一个类,当序列化时,应该在它的位置序列化它的一个成员。我的班级是:Java 使用MongoDB、Jackson和MongoJack的自定义序列化程序,java,json,mongodb,serialization,jackson,Java,Json,Mongodb,Serialization,Jackson,我有一个类,当序列化时,应该在它的位置序列化它的一个成员。我的班级是: @JsonSerialize(using = MyClassSerializer.class) public class MyClass implements Serializable { /** * A default ID for this class for serialization. */ private static final long serialVersionUID =
@JsonSerialize(using = MyClassSerializer.class)
public class MyClass implements Serializable {
/**
* A default ID for this class for serialization.
*/
private static final long serialVersionUID = 1L;
/**
* A member of this object.
*/
private final OtherClass otherClass;
...
/**
* Returns the instance of the member object.
*
* @return The instance of the member object.
*/
public OtherClass getOtherClass() {
return otherClass;
}
}
为此,我创建了一个非常简单的自定义序列化程序:
public class MyClassSerializer extends JsonSerializer<MyClass> {
/**
* Serializes only the OtherClass field.
*/
@Override
public void serialize(
final MyClass myClass,
final JsonGenerator generator,
final SerializerProvider provider)
throws IOException, JsonProcessingException {
// Write the schema.
generator.writeObject(myClass.getOtherClass());
}
}
我已经使用Jackson对MyClass的实例进行了序列化和反序列化测试,结果完全符合预期
我的应用程序代码有点复杂。我有一个container类
,其成员类型为MyClass
。我试图通过MongoJack序列化ContainerClass
的实例:
// Get the authentication token collection.
JacksonDBCollection<ContainerClass, Object> collection =
JacksonDBCollection
.wrap(
MongoBinController
.getInstance()
.getDb()
.getCollection(COLLECTION_NAME),
ContainerClass.class);
// Save it.
collection.insert(container);
如果我从MyClass
中删除@JsonSerialize
,我可以让它工作,但是这会导致整个MyClass
实例被序列化,这不是我想要的。这让我几乎可以肯定问题出在我的自定义序列化程序上,但我不确定我应该如何编写它
提前谢谢。一个可能有用的提示:当使用多态类型时,调用的方法是:
serializeWithType(...)
而不是序列化(…)
。因此,您需要实现该方法;通常情况下,它将是简单的:
typeSer.writeTypePrefixForObject(value, jgen);
// implement actual content serialization, or delegate here:
this.serialize(...);
typeSer.writeTypeSuffixForObject(value, jgen);
但您可能想看看标准的Jackson序列化程序。唯一真正的区别是,serialize
需要直接输出START\u对象和END\u对象,这里我们必须要求TypeSerializer
添加它们。这是必要的,因为类型id
包含实际上可能会改变这些(我可以详细说明,但现在这应该足够了)
然而,这里可能有更简单的解决方案。如果您可以在想要使用的成员上添加@JsonValue
注释,而不是整个对象(直接或通过mix-in),那么应该可以做到:
@JsonValue
public OtherClass getOtherClass()...
如果需要反序列化,可以使用@JsonCreator
如下:
@JsonCreator
public MyClass(OtherClass surrogate) { ... }
伟大的这回答了我最初的问题;我真不敢相信我从来都不知道
@JsonValue
。我试过@JsonCreator
,但有点麻烦。它抱怨说,抽象类型要么需要映射到具体类型(这是在抽象类的注释中完成的),要么需要自定义反序列化器(这可能就是我将要做的),要么需要用其他类型信息实例化(我不理解)。无论如何,如果您对如何解决这个问题有建议,那就太好了,但是,如果没有,自定义反序列化程序已经在工作了。再次感谢!在这里或邮件列表上可能值得再问一个问题:我现在不知道,但不管是什么问题,都应该可以解决。但对于自定义反序列化程序,此时可能不值得担心。
@JsonValue
public OtherClass getOtherClass()...
@JsonCreator
public MyClass(OtherClass surrogate) { ... }