Java 如何序列化映射中对象值的类型属性?
我需要一些帮助。我必须获得下一个json:Java 如何序列化映射中对象值的类型属性?,java,serialization,jackson,Java,Serialization,Jackson,我需要一些帮助。我必须获得下一个json: { "433434" : { "type" : "MULTIPLE", "value" : [ { "type" : "NUMBER", "value" : 322332 }, { "type" : "NUMBER", "value" : 322332 } ] } } 但我有一个: { "433434" : { "value" : [ {
{
"433434" : {
"type" : "MULTIPLE",
"value" : [ {
"type" : "NUMBER",
"value" : 322332
}, {
"type" : "NUMBER",
"value" : 322332
} ]
}
}
但我有一个:
{
"433434" : {
"value" : [ {
"type" : "NUMBER",
"value" : 322332
}, {
"type" : "NUMBER",
"value" : 322332
} ]
}
}
我在用杰克逊。这是我的主课
package com.un1acker;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.un1acker.characteristic.AbstractCharacteristic;
import com.un1acker.characteristic.MultipleCharacteristic;
import com.un1acker.characteristic.NumCharacteristic;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
NumCharacteristic numCharacteristic = new NumCharacteristic();
numCharacteristic.setValue(BigInteger.valueOf(322332L));
List<AbstractCharacteristic<?>> list = new ArrayList<>();
list.add(numCharacteristic);
list.add(numCharacteristic);
StringWriter sw = new StringWriter();
MultipleCharacteristic multipleCharacteristic = new MultipleCharacteristic();
multipleCharacteristic.setValue(list);
Map<String, AbstractCharacteristic<?>> map = new HashMap<>();
map.put("433434", multipleCharacteristic);
mapper.writeValue(sw, map);
System.out.println(sw.toString());
}
}
package com.un1acker;
导入com.fasterxml.jackson.databind.ObjectMapper;
导入com.fasterxml.jackson.databind.SerializationFeature;
导入com.un1acker.characteristic.AbstractCharacteristic;
导入com.un1acker.characteristic.MultipleCharacteristic;
导入com.un1acker.characteristic.NumCharacteristic;
导入java.io.IOException;
导入java.io.StringWriter;
导入java.math.biginger;
导入java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
公共班机{
公共静态void main(字符串[]args)引发IOException{
ObjectMapper mapper=新的ObjectMapper();
configure(SerializationFeature.INDENT_输出,true);
NumCharacteristic NumCharacteristic=新的NumCharacteristic();
numCharacteristic.setValue(BigInteger.valueOf(322332L));
List>map=newhashmap();
map.put(“433434”,多特征);
mapper.writeValue(西南,地图);
System.out.println(sw.toString());
}
}
我有一个从抽象特征扩展而来的类多重特征和数字特征。计划我们有map>,它包含多个特性的值。
在NumberCharacteristic值的多特征集合列表中
package com.un1acker.characteristic;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({ @JsonSubTypes.Type(
value = NumCharacteristic.class,
name = "NUMBER"
), @JsonSubTypes.Type(
value = MultipleCharacteristic.class,
name = "MULTIPLE")})
public abstract class AbstractCharacteristic<T>{
private static final long serialVersionUID = -6524899961842198462L;
private T value;
public AbstractCharacteristic() {
}
public T getValue() {
return this.value;
}
protected void setValue(T value) {
this.value = value;
}
}
package com.un1acker.characteristic;
导入com.fasterxml.jackson.annotation.JsonSubTypes;
导入com.fasterxml.jackson.annotation.JsonTypeInfo;
@JsonTypeInfo(
use=JsonTypeInfo.Id.NAME,
include=JsonTypeInfo.As.PROPERTY,
property=“type”
)
@JsonSubTypes({@JsonSubTypes.Type(
值=NumCharacteristic.class,
name=“编号”
),@JsonSubTypes.Type(
值=MultipleCharacteristic.class,
name=“MULTIPLE”)})
公共抽象类抽象特征{
私有静态最终长serialVersionUID=-652489961842198462L;
私人T值;
公共抽象特征(){
}
公共T getValue(){
返回此.value;
}
受保护的无效设置值(T值){
这个值=值;
}
}
数字特征类
package com.un1acker.characteristic;
import java.math.BigInteger;
public class NumCharacteristic extends AbstractCharacteristic<BigInteger> {
private static final long serialVersionUID = 9220460768952701281L;
public NumCharacteristic() {
}
public void setValue(BigInteger value) {
super.setValue(value);
}
}
package com.un1acker.characteristic;
导入java.math.biginger;
公共类NumCharacteristic扩展了AbstractCharacteristic{
私有静态最终长serialVersionUID=9220460768952701281L;
公共NumCharacteristic(){
}
public void setValue(BigInteger值){
super.setValue(值);
}
}
多特征类
package com.un1acker.characteristic;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.un1acker.MyCustomSerializer;
import java.util.List;
public class MultipleCharacteristic extends AbstractCharacteristic<List<? extends AbstractCharacteristic<?>>> {
@Override
public void setValue(List<? extends AbstractCharacteristic<?>> value) {
super.setValue(value);
}
@Override
@JsonSerialize(using = MyCustomSerializer.class)
public List<? extends AbstractCharacteristic<?>> getValue() {
return super.getValue();
}
}
package com.un1acker.characteristic;
导入com.fasterxml.jackson.databind.annotation.JsonSerialize;
导入com.un1acker.MyCustomSerializer;
导入java.util.List;
公共类MultipleCharacteristic扩展AbstractCharacteristic>getValue(){
返回super.getValue();
}
}
我尝试使用重写方法serializeWithType为MultipleClass创建自定义序列化,但这不起作用。这看起来可能是Jackson的错误。您的MultipleCharacteristic类型可以很好地序列化,并在单独使用时包含该类型,但当它是一个映射值时则不包含该类型,我希望其工作方式与此相同:
@Test // passes
public void serialize_multiple_characteristic() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
assertThat(mapper.writeValueAsString(chr), equivalentTo("{ type: 'MULTIPLE', value: [] }"));
}
@Test // fails, got: {"xyzzy":{"value":[]}}
public void serialize_multiple_characteristic_in_map_value() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
Map<String, MultipleCharacteristic> map = new HashMap<>();
map.put("xyzzy", chr);
assertThat(mapper.writeValueAsString(map), equivalentTo("{ 'xyzzy': { type: 'MULTIPLE', value: [] } }"));
}
@Test//通过
public void serialize_multiple_characteristic()引发异常{
多重特征chr=新的多重特征();
chr.setValue(新的ArrayList());
ObjectMapper mapper=新的ObjectMapper();
assertThat(mapper.writeValueAsString(chr),等价于(“{type:'MULTIPLE',value:[]));
}
@测试//失败,得到:{“xyzy”:{“value”:[]}
public void serialize_multiple_characteristic_in_map_value()引发异常{
多重特征chr=新的多重特征();
chr.setValue(新的ArrayList());
ObjectMapper mapper=新的ObjectMapper();
Map Map=newhashmap();
地图放置(“xyzzy”,chr);
assertThat(mapper.writeValueAsString(map),等价于(“{xyzy':{type:'MULTIPLE',value:[]}”);
}
(从内部看,BeanSerializer从来没有被TypeWrappedSerializer包裹过)
如果映射嵌入到某个对象中,这对您来说可能不是问题,因为Jackson似乎知道映射的类型参数(例如,它通常从包含的bean中获取),它似乎做了正确的事情:
@Test // passes
public void serialize_multiple_characteristic_in_map_value_using_writer() throws Exception {
MultipleCharacteristic chr = new MultipleCharacteristic();
chr.setValue(new ArrayList<>());
ObjectMapper mapper = new ObjectMapper();
Map<String, AbstractCharacteristic<?>> map = new HashMap<>();
map.put("xyzzy", chr);
// Hint to Jackson what types will be in the map
TypeReference<?> mapType = new TypeReference<Map<String, AbstractCharacteristic<?>>>(){};
assertThat(mapper.writerFor(mapType).writeValueAsString(map), equivalentTo("{ 'xyzzy': { type: 'MULTIPLE', value: [] } }"));
}
@Test//通过
public void使用\u writer()在\u map\u value\u中序列化\u多个\u特征\u引发异常{
多重特征chr=新的多重特征();
chr.setValue(新的ArrayList());
ObjectMapper mapper=新的ObjectMapper();
Map mapType=new TypeReference这对我来说很有用:为多特征
添加自定义序列化程序:
public class MultipleCharacteristicValueSerializer extends JsonSerializer<MultipleCharacteristic> {
@Override
public void serialize(MultipleCharacteristic multipleCharacteristicValue, JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeFieldName("value");
jsonGenerator.writeStartArray();
for (AbstractCharacteristic<?> characteristicValue : multipleCharacteristicValue.getValue()) {
jsonGenerator.writeObject(characteristicValue);
}
jsonGenerator.writeEndArray();
}
@Override
public void serializeWithType(MultipleCharacteristic value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException {
typeSer.writeTypePrefixForObject(value, jgen);
serialize(value, jgen, provider);
typeSer.writeTypeSuffixForObject(value, jgen);
}
@Override
public Class<MultipleCharacteristic> handledType() {
return MultipleCharacteristic.class;
}
}
公共类MultipleCharacteristicValueSerializer扩展JsonSerializer{
@凌驾
public void serialize(MultipleCharacteristic multipleCharacteristicValue、JsonGenerator JsonGenerator、SerializerProvider SerializerProvider)引发IOException、JsonProcessingException{
jsonGenerator.writeFieldName(“值”);
jsongGenerator.writeStartArray();
for(AbstractCharacteristicValue:multipleCharacteristicValue.getValue()){
jsonGenerator.writeObject(特征值);
}
jsonggenerator.writeEndArray();
}
@凌驾
public void serializeWithType(多特征值,JsonGenerator jgen,SerializerProvider,TypeSerializer typeSer)引发IOException,JsonProcessingException{
typeSer.writeTypePrefixForObject(值,jgen);
序列化(值、jgen、提供程序);
typeSer.writeTypeSuffixForObject(值,jgen);
}
@凌驾
公共类handledType(){
返回MultipleCharacteristic.class;
}
}
我找到了决策。我正在通过SimpleModule为MultipleCharacteristic添加自定义序列化程序,并覆盖下一个方法:serialize、serializeWithType、handledType。但是AnyWare
public class MultipleCharacteristicValueSerializer extends JsonSerializer<MultipleCharacteristic> {
@Override
public void serialize(MultipleCharacteristic multipleCharacteristicValue, JsonGenerator jsonGenerator,SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeFieldName("value");
jsonGenerator.writeStartArray();
for (AbstractCharacteristic<?> characteristicValue : multipleCharacteristicValue.getValue()) {
jsonGenerator.writeObject(characteristicValue);
}
jsonGenerator.writeEndArray();
}
@Override
public void serializeWithType(MultipleCharacteristic value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, JsonProcessingException {
typeSer.writeTypePrefixForObject(value, jgen);
serialize(value, jgen, provider);
typeSer.writeTypeSuffixForObject(value, jgen);
}
@Override
public Class<MultipleCharacteristic> handledType() {
return MultipleCharacteristic.class;
}
}