8

Map (非文字列キー) とその他のフィールドを含むクラスがあります。

public class MyClass() {
    private Map<KeyObject, OtherObject> map;
    private String someField;

    public MyClass(Map<KeyObject, OtherObject> map, String someField) {
        this.map = map;
        this.someField = someField;
    }

    // Getters & Setters
}

Jackson を使用して、このクラスをシリアライズおよびデシリアライズしたいと思います。私はそれを行う別の方法を見て、 jackson モジュールを使用してみることにしました。

この投稿に従って、JsonDeserializer と JsonSerializer を拡張しました。問題は、これらのクラスを型付けする必要があることです。したがって、次のようになります。

public class keyDeserializer extends JsonDeserializer<Map<KeyObject, OtherObject>> {
...
}

KeySerializer についても同様です。

次に、モジュールに追加します。

module.addSerializer(new keySerializer());
module.addDeserializer(Map.class, new keyDeserializer());

しかし、例外が発生しているため、これは明らかに間違っています:

keySerializer does not define valid handledType() -- must either register with method that takes type argument  or make serializer extend 'org.codehaus.jackson.map.ser.std.SerializerBase'

シリアライザーとデシリアライザーをMyClassに入力することもできましたが、そのすべてを手動で解析する必要があり、これは合理的ではありません。

アップデート:

注釈を使用して、コード内でモジュールの作成を回避することができました

@JsonDeserialize(using = keyDeserializer.class)
@JsonSerialize(using = keySerializer.class)
private Map<KeyObject, OtherObject> map;

しかし、toString() 出力から自分でマップ構造全体をシリアライズ/デシリアライズする必要があります。そこで、別の注釈を試しました:

@JsonDeserialize(keyUsing = MyKeyDeserializer.class)
private Map<KeyObject, OtherObject> map;

MyKeyDeserializer が拡張org.codehaus.jackson.map.KeyDeserializerされ、メソッドをオーバーライドする場所

public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {...}

次に、キークラスの toString() 出力から手動でキーをデシリアライズします。

これは最適ではありません (この toString() メソッドへの依存関係)。より良い方法はありますか?

4

1 に答える 1

13

このシリアライザーを使用して終了しました:

public class MapKeySerializer extends SerializerBase<Object> {
    private static final SerializerBase<Object> DEFAULT = new StdKeySerializer();
    private static final ObjectMapper mapper = new ObjectMapper();

    protected MapKeySerializer() {
    super(Object.class);
    }

    @Override
    public JsonNode getSchema(SerializerProvider provider, Type typeHint) throws JsonMappingException {
    return DEFAULT.getSchema(provider, typeHint);
    }

    @Override
    public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException {
    if (null == value) {
        throw new JsonGenerationException("Could not serialize object to json, input object to serialize is null");
    }
    StringWriter writer = new StringWriter();
    mapper.writeValue(writer, value);
    jgen.writeFieldName(writer.toString());
    }
}

そして、このデシリアライザー:

public class MapKeyDeserializer extends KeyDeserializer {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public Object deserializeKey(String key, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    return mapper.readValue(key, MyObject.class);
    }
}

私の地図に注釈を付けました:

@JsonDeserialize(keyUsing = MapKeyDeserializer.class)
@JsonSerialize(keyUsing = MapKeySerializer.class)
private Map<KeyObject, OtherObject> map;

これは私のために働いた解決策です。これが他の人に役立つことを願っています。

于 2014-08-19T09:33:11.163 に答える