проблема десериализации JSON - PullRequest
3 голосов
/ 07 марта 2011

Имеет массив, когда размер равен 1, полученные данные json НЕ содержат [];как

{"firstname":"tom"}

, если размер больше 1, полученные данные содержат [], например

[{"firstname":"tom"},{"firstname":"robert"}]

В настоящее время мой класс содержит свойство массива

String[] firstname;
//getter setter omit here

Код для обработки подобных лайков

ObjectMapper mapper = new ObjectMapper();    
MyClass object = mapper.readValue(json, MyClass.class);

Когда размер больше 1, десериализация работает.Однако, когда размер равен 1, десериализация не удалась.

В настоящее время я использую Джексона, какое-либо решение этой проблемы?

Мне интересно, может ли Джексон / Гсон или любая другая библиотека справиться с этим?1019 *

Ответы [ 5 ]

3 голосов
/ 07 марта 2011

В частности, для Джексона лучше всего сначала связать с JsonNode или объектом, например:

Object raw = objectMapper.readValue(json, Object.class); // becomes Map, List, String etc

и затем проверьте, что у вас есть, свяжите снова:

MyClass[] result;
if (raw instanceof List<?>) { // array
  result = objectMapper.convertValue(raw, MyClass[].class);
} else { // single object
  result = objectMapper.convertValue(raw, MyClass.class);
}

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

2 голосов
/ 07 марта 2011

Вот как это сделать с GSON.Давайте предположим, что структура объекта:

public class Group{

    public Group(final List<Person> members){
        this.members = members;
    }

    private final List<Person> members;
}

public class Person{

    public Person(final String firstName, final String lastName){
        this.firstName = firstName;
        this.lastName = lastName;
    }

    private final String firstName;
    private final String lastName;
}

Вот десериализатор, который понимает отдельные записи Person, а также их массивы:

public class GroupDeserializer implements JsonDeserializer<Group>{

    @Override
    public Group deserialize(final JsonElement json,
        final Type typeOfT,
        final JsonDeserializationContext context) throws JsonParseException{
        List<Person> members;
        if(json.isJsonArray()){
            final JsonArray array = json.getAsJsonArray();
            members = new ArrayList<Person>(array.size());
            for(final JsonElement personElement : array){
                members.add(getSinglePerson(personElement, context));
            }
        } else{
            members =
                Collections.singletonList(getSinglePerson(json, context));
        }
        return new Group(members);
    }

    private Person getSinglePerson(final JsonElement element,
        final JsonDeserializationContext context){
        final JsonObject personObject = element.getAsJsonObject();
        final String firstName =
            personObject.getAsJsonPrimitive("firstname").getAsString();
        final String lastName =
            personObject.getAsJsonPrimitive("lastname").getAsString();
        return new Person(firstName, lastName);
    }

}

И здесь вы можете найти необходимую конфигурациюиспользовать это

1 голос
/ 23 июля 2012

Я столкнулся с той же проблемой, когда пытался десериализовать объект JSON, созданный из XML.(XML-JSON).После недолгих исследований выяснилось, что у нас есть простое решение.

Просто установите функцию: ACCEPT_SINGLE_VALUE_AS_ARRAY.

ObjectMapper mapper = new ObjectMapper ();mapper.configure (DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);

Для получения дополнительной информации: http://fasterxml.github.com/jackson-databind/javadoc/2.0.0/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY

1 голос
/ 07 марта 2011

edit: Полагаю, вы бы просто извлекли JsonElement и проверили его isJsonArray() и / или isJsonObject(). Затем просто позвоните getAsJsonArray() или getAsJsonObject().

Старый ответ: Почему бы просто не попытаться извлечь массив и поймать JsonParseException, если он потерпит неудачу. Вместо этого попробуйте извлечь объект в блоке catch.

Я знаю, что это не красиво, но должно работать.

0 голосов
/ 07 марта 2011

В первом случае это выглядит как объект, а во втором - как массив объектов (что звучит так, как вы ожидаете).

В библиотеках кодирования JSON обычно есть опция «принудительный массив» для подобных случаев. В противном случае на вашем клиенте вы можете проверить ответ JSON и, если это не массив, вставить возвращаемый объект возражения в новый массив.

...