bgr*_*ves 3 java serialization json dictionary jackson
类似于 @JsonAppend 的简化版本
public class Bean {
@JsonAppend(key = [...], value = [...])
public Map<?, ?> map = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
那就太好了-有什么简单的方法可以实现这一点吗?
我读过很多 SO 条目,例如。
但没有找到符合我需求的东西。
我的请求的原因是无法区分某些给定的 JSON 是源自 Map 还是 POJO 序列化。如果有必要(在极少数情况下),向地图添加魔法额外字段将是实现此目的的简单方法。
好问题!是的,这是(以某种方式)可能的。以下公开的方法维护标准序列化行为,同时在其之上添加注释定义的键值对。
创建自定义注释。我会称之为MapAppender
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MapAppender {
String[] keys();
String[] values();
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,我们定义了键值数组,它将按索引进行匹配。
我们被迫使用String
字段而不是更通用的字段Object
,但这是根据注释设计的。
创建自定义JsonSerializer<Map>
. 我会称之为MapAppenderSerializer
public class MapAppenderSerializer
extends StdSerializer<Map>
implements ContextualSerializer {
private static final long serialVersionUID = 1L;
private final String[] keys;
private final String[] values;
// No-arg constructor required for Jackson
MapAppenderSerializer() {
super(Map.class);
keys = new String[0];
values = new String[0];
}
MapAppenderSerializer(
final String[] keys,
final String[] values) {
super(Map.class);
this.keys = keys;
this.values = values;
}
@Override
public void serialize(
final Map value,
final JsonGenerator jsonGenerator,
final SerializerProvider serializerProvider) throws IOException {
// Create a copy Map to avoid touching the original one
final Map hashMap = new HashMap<>(value);
// Add the annotation-specified key-value pairs
for (int i = 0; i < keys.length; i++) {
hashMap.put(keys[i], values[i]);
}
// Serialize the new Map
serializerProvider.defaultSerializeValue(hashMap, jsonGenerator);
}
@Override
public JsonSerializer<?> createContextual(
final SerializerProvider serializerProvider,
final BeanProperty property) {
MapAppender annotation = null;
if (property != null) {
annotation = property.getAnnotation(MapAppender.class);
}
if (annotation != null) {
return new MapAppenderSerializer(annotation.keys(), annotation.values());
}
throw new UnsupportedOperationException("...");
}
}
Run Code Online (Sandbox Code Playgroud)
现在,使用您的Bean
类示例,使用注释该Map
字段并@MapAppender
使用定义自定义序列化器@JsonSerialize
public class Bean {
public String simpleField;
@MapAppender(keys = {"test1", "test2"}, values = {"value1", "value2"})
@JsonSerialize(using = MapAppenderSerializer.class)
public Map<Object, Object> simpleMap = new HashMap<>();
}
Run Code Online (Sandbox Code Playgroud)
就是这样。序列化一个实例Bean
final ObjectMapper objectMapper = new ObjectMapper();
final String string = objectMapper.writeValueAsString(new Bean());
Run Code Online (Sandbox Code Playgroud)
结果是
{"simpleField":null,"simpleMap":{"test2":"value2","test1":"value1"}}
Run Code Online (Sandbox Code Playgroud)
另一个例子,Map
在序列化之前填充值
final ObjectMapper objectMapper = new ObjectMapper();
final Bean value = new Bean();
value.simpleMap.put("myKey", "myValue");
final String string = objectMapper.writeValueAsString(value);
Run Code Online (Sandbox Code Playgroud)
结果是
{"simpleField":null,"simpleMap":{"test1":"value1","test2":"value2","myKey":"myValue"}}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1627 次 |
最近记录: |