2015-11-02 26 views
1

我需要一些幫助。我必須讓未來的JSON:如何在map中序列化對象值的類型屬性?

{ 
    "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()); 
    } 
} 

而且我有從AbstractCharacteristic延伸的類MultipleCharateristic和NumberCharacteristic。計劃我們有map>,它包含值MultipleCharacteristic。 在NumberCharacteristic值的MultipleCharacteristic集列表中。

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; 
    } 
} 

NumCharacteristic類

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); 
    } 
} 

MultipleCharacteristic類

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(); 
    } 
} 

我試過了MultipleClass與重寫方法serializeWithType但這並不工作創建自定義序列化。

回答

0

這個工作對我來說:添加自定義序列化的MultipleCharacteristic

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; 
    } 
} 
0

這看起來可能是傑克遜的bug。你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: [] } }")); 
} 

(通過內部結構看,在BeanSerializer永遠不會被包裹在TypeWrappedSerializer)如地圖被嵌入的東西作爲

可能不是你一個問題,因爲如果傑克遜知道該地圖類型參數(它通常會從含豆獲得,例如)它似乎做的是正確的事情:

@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: [] } }")); 
} 

一個解決辦法,如果你只是需要獲得JSON生產,不能改變使用ObjectWrite的代碼,是用的,而不是地圖ObjectNode:

@Test 
public void serialize_multiple_characteristic_in_json_node() throws Exception { 
    MultipleCharacteristic chr = new MultipleCharacteristic(); 
    chr.setValue(new ArrayList<>()); 
    ObjectMapper mapper = new ObjectMapper(); 
    ObjectNode node = mapper.getNodeFactory().objectNode(); 
    node.putPOJO("xyzzy", chr); 
    assertThat(mapper.writeValueAsString(node), equivalentTo("{ 'xyzzy': { type: 'MULTIPLE', value: [] } }")); 
} 
+0

我找到了決定。我爲SimpleModule爲MultipleCharacteristic添加自定義序列化器,並覆蓋下一個方法:serialize,serializeWithType,handledType。但任何感謝您的答案!=) – Alexandr

相關問題