Подтвердить что ты не робот

Как развернуть и сериализовать java-карту в java с помощью jackson?

У меня есть bean, как этот

class Foo {
    private Map<String, Data> dataMap;
    private String fooFieldOne;
    private String fooFieldTwo;
}

class Data {
    private fieldOne;
    private fieldTwo;
}

Я хочу сериализовать как Json, как этот

{
    "key1": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key2": {
        "fieldOne": "some other value",
        "fieldTwo": "some other value"
    },
    "fooFieldOne":"valueone", 
    "fooFieldTwo":"valuetwo" 
}

Но я получаю результат как

{
    "dataMap": {
        "key1": {
            "fieldOne": "some value",
            "fieldTwo": "some value"
        },
        "key2": {
            "fieldOne": "some other value",
            "fieldTwo": "some other value"
        }
    },
    "fooFieldOne":"valueone", 
    "fooFieldTwo":"valuetwo" 
}

Как игнорировать слой dataMap в вышеупомянутом json? Для этого я использую библиотеку java jackson.

Код, который я пытался,

ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(myFOOObject)
4b9b3361

Ответ 1

Вы можете создать getter для dataMap и сериализовать dataMap вместо всего экземпляра Foo.

mapper.writeValueAsString(myFOOObject.getDataMap());

Другой метод использует аннотацию @JsonUnwrapped. Эта аннотация доступна в Jackson 1.9 +.

http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/annotate/JsonUnwrapped.html

Недостатком использования этой аннотации является невозможность использовать карты, указанные в ответе на ваш другой вопрос

Ответ 2

Вы получаете

{ "dataMap": ... } 

потому что Foo имеет поле, называемое dataMap внутри него. Здесь имя поля нельзя игнорировать, поскольку оно создаст конфликты, если Foo имеет несколько карт, что-то вроде

class Foo {
private Map<String, Data> dataMap1;
private Map<String, Data> dataMap2;
}

теперь без имени поля: в JSON JSON не знает, как десериализоваться, когда он получает некоторый JSON, например

{
    //belongs to dataMap1
    "key1": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key2": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    //belongs to dataMap2
    "key3": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key4": {
        "fieldOne": "some other value",
        "fieldTwo": "some other value"
    }
}

Теперь, когда имя поля делает его очень четким при десериализации

{
    "dataMap1" : {
    "key1": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key2": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    }
    },
    "dataMap2" : {
    "key3": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key4": {
        "fieldOne": "some other value",
        "fieldTwo": "some other value"
    }
  }
}

Сказав, что

Как игнорировать слой dataMap в json?

Вы можете просто сериализовать карту

ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(myFOOObject.getDataMap());

Ответ 3

На карте есть два объекта String и Data. JSON конвертирует объекты java в пару значений JSON, но если у вас уже есть карта, содержащая пару значений ключа, и конвертировать эту карту в документ JSON, тогда ключ карты также преобразуется в пару значений ключа JSON, а значение карты также имеет объект которые преобразуются в пару ключевых значений.

Ответ 4

Я нашел ответ - используя аннотацию @JsonAnyGetter с getter для карты. Чтобы избежать конфликтов во время десериализации, следует использовать аннотацию @JsonAnySetter с установщиком для этой карты.