如何将ASObject序列化为JSON

时间:2011-11-16 20:55:01

标签: json jackson

我正在尝试将flex.messaging.io.amf.ASObject序列化和反序列化为JSON。 ASObject扩展了HashMap并添加了一个额外的type属性。默认情况下,Jackson正确序列化对象下的所有键和值,但不保留ASObject.getType()

使用Jackson我已成功为ASObject创建自定义序列化程序,现在正在序列化为:

[{"@type":"org.me.MyClass","map":{"key":"value"}}]

这是通过添加一个额外的类型字段然后委托回java.util.Map的标准处理程序。但是,我不确定如何配置Jackson允许自定义反序列化以允许自定义处理。

也许我会以错误的方式解决这个问题!

2 个答案:

答案 0 :(得分:0)

也许你想创建自定义反序列化器?您可能不需要该类型字段,只要在反序列化(属性具有ASOBject类型)时从上下文中知道类型。

答案 1 :(得分:0)

这是一种方法。

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.Version;
import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility;
import org.codehaus.jackson.annotate.JsonMethod;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.module.SimpleModule;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    ASObject asObject = new ASObject();
    asObject.type = Bar.class;
    asObject.put("1", "alpha");
    asObject.put("TWO", "beta");

    SimpleModule module = new SimpleModule("SimpleModule", Version.unknownVersion());
    module.addSerializer(ASObject.class, new ASObjectSerializer());
    ObjectMapper mapper = new ObjectMapper().withModule(module).setVisibility(JsonMethod.FIELD, Visibility.ANY);

    String asObjectJson = mapper.writeValueAsString(asObject);
    System.out.println(asObjectJson);
    // output: {"type":"com.stackoverflow.q8158528.Bar","map":{"1":"alpha","TWO":"beta"}}

    module = new SimpleModule("SimpleModule", Version.unknownVersion());
    module.addDeserializer(ASObject.class, new ASObjectDeserializer());
    mapper = new ObjectMapper().withModule(module).setVisibility(JsonMethod.FIELD, Visibility.ANY);

    ASObject asObjectCopy = mapper.readValue(asObjectJson, ASObject.class);
    System.out.println(asObjectCopy.equals(asObject));
    // output: true
  }
}

class ASObjectDeserializer extends JsonDeserializer<ASObject>
{
  @Override
  public ASObject deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException
  {
    ASObject asObject = new ASObject();
    JsonNode tree = jp.readValueAsTree();
    try
    {
      asObject.type = Class.forName(tree.get("type").asText());
    }
    catch (ClassNotFoundException e)
    {
      System.exit(42);
    }
    asObject.putAll(jp.getCodec().treeToValue(tree.get("map"), Map.class));
    return asObject;
  }
}

class ASObjectSerializer extends JsonSerializer<ASObject>
{
  @Override
  public void serialize(ASObject value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
      JsonProcessingException
  {
    jgen.writeStartObject();
    jgen.writeStringField("type", value.type.getName());
    jgen.writeObjectField("map", new HashMap(value));
    jgen.writeEndObject();
  }
}

class ASObject extends HashMap
{
  Class type;

  @Override
  public boolean equals(Object o)
  {
    ASObject a = (ASObject) o;
    return type.equals(a.type) && super.equals(a);
  }
}

class Bar
{
}