在内部,我使用地图快速查找值,例如private Map<String, CustomObject> lookupTable
,其中CustomObject
有一些id
字段被用作lookupTable
中的关键字。序列化地图的键是愚蠢的,所以我想注释内部变量以仅序列化值。这显然不起作用:
@JsonSerialize(as = List.class)
private final Map<String, CustomObject> lookupTable;
为什么自定义序列化程序无法正常工作
我创建了一个自定义序列化程序,如:
public static class MapValuesJsonSerializer extends JsonSerializer<Map<?, ?>> {
@Override
public void serialize(
Map<?, ?> value,
JsonGenerator generator,
SerializerProvider provider)
throws IOException, JsonProcessingException {
generator.writeObject(value.values());
}
}
然后,我相应地注释了该字段:
@JsonSerialize(using = MapValuesJsonSerializer.class)
public Map<String, CustomObject> lookupTable;
这适用于一些Java测试代码,但在使用MongoDB的驱动程序和MongoJack时会中断。我得到一些无用的异常,我相信这是因为它实际上并没有序列化返回的对象,而是试图将该原始对象传递给BSON序列化器:
Caused by: java.lang.IllegalArgumentException: can't serialize class CustomObject
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:270)
at org.bson.BasicBSONEncoder.putIterable(BasicBSONEncoder.java:295)
at org.bson.BasicBSONEncoder._putObjectField(BasicBSONEncoder.java:234)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:174)
at org.bson.BasicBSONEncoder.putObject(BasicBSONEncoder.java:120)
at com.mongodb.DefaultDBEncoder.writeObject(DefaultDBEncoder.java:27)
at com.mongodb.OutMessage.putObject(OutMessage.java:289)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:239)
at com.mongodb.DBApiLayer$MyCollection.insert(DBApiLayer.java:204)
at com.mongodb.DBCollection.insert(DBCollection.java:148)
at com.mongodb.DBCollection.insert(DBCollection.java:91)
at org.mongojack.JacksonDBCollection.insert(JacksonDBCollection.java:255)
// My code (not the serializer)...
答案 0 :(得分:2)
当然,一旦我问,我就找到了解决方案。
使用上面的序列化程序,使用provider
直接序列化值而不是generator
。这是代码:
/**
* <p>
* Serializes the values of some map into a list.
* <p>
*
* @author John Jenkins
*/
public class MapValuesJsonSerializer extends JsonSerializer<Map<?, ?>> {
/*
* (non-Javadoc)
* @see com.fasterxml.jackson.databind.JsonSerializer#serialize(java.lang.Object, com.fasterxml.jackson.core.JsonGenerator, com.fasterxml.jackson.databind.SerializerProvider)
*/
@Override
public void serialize(
final Map<?, ?> value,
final JsonGenerator generator,
final SerializerProvider provider)
throws IOException, JsonProcessingException {
provider.defaultSerializeValue(value.values(), generator);
}
}