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

Отключить JSON в существующий объект (Java)

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

Или, если это невозможно, я хотел бы знать, могут ли какие-либо библиотеки десериализации Java JSON это сделать.

Это похоже на соответствующий вопрос для С#: Наложение данных из строки JSON в существующий экземпляр объекта. Кажется, у JSON.NET есть PopulateObject (строка, объект).

4b9b3361

Ответ 2

Если вы можете использовать другую библиотеку вместо Jackson, вы можете попробовать Genson http://owlike.github.io/genson/. В дополнение к некоторым другим приятным функциям (например, десериализация с использованием непустого конструктора без аннотации, десериализация для полиморфных типов и т.д.), Он поддерживает десериализацию JavaBean в существующий экземпляр. Вот пример:

BeanDescriptorProvider provider = new Genson().getBeanDescriptorFactory();
BeanDescriptor<MyClass> descriptor = provider.provide(MyClass.class, genson);
ObjectReader reader = new JsonReader(jsonString);
MyClass existingObject = descriptor.deserialize(existingObject, reader, new Context(genson));

Если у вас есть какие-либо вопросы, не стесняйтесь использовать свой список рассылки http://groups.google.com/group/genson.

Ответ 3

Если вы используете фреймворк spring, вы можете использовать библиотеку BeanUtils для этой задачи. Сначала десериализуйте свою строку json, а затем используйте BeanUtils, чтобы установить этот объект внутри родительского объекта. Он также ожидает, что переменное имя объекта будет установлено внутри родительского объекта. Вот фрагмент кода:

childObject = gson.fromJson("your json string",class.forName(argType))
BeanUtils.setProperty(mainObject, "childObjectName", childObject);

Ответ 4

Одним из решений является анализ нового объекта/дерева, а затем унификация-копирование в существующий граф объекта/дерево. Но это, конечно, менее эффективно и работает, особенно если конкретные типы отличаются из-за меньшей доступности информации о типе. (На самом деле это не ответ. Надеюсь, там лучший ответ, просто хочу, чтобы другие не ответили таким образом.)

Ответ 5

flexJson также может помочь вам сделать то же самое.

Вот пример, скопированный из FlexJson Doc

Функция deserializeInto принимает вашу строку и ссылается на существующий объект.

 Person charlie = new Person("Charlie", "Hubbard", cal.getTime(), home, work );
 Person charlieClone = new Person( "Chauncy", "Beauregard", null, null, null );
 Phone fakePhone = new Phone( PhoneNumberType.MOBILE, "303 555 1234");
 charlieClone.getPhones().add( fakePhone ); 
 String json = new JSONSerializer().include("hobbies").exclude("firstname", "lastname").serialize( charlie ); 
 Person p = new JSONDeserializer<Person>().deserializeInto(json, charlieClone);

Обратите внимание, что ссылка, возвращаемая в p, такая же, как charlieClone, только с обновленными значениями.

Ответ 6

Я использовал Jackson + Spring DataBinder, чтобы выполнить что-то подобное. Этот код обрабатывает массивы, но не вложенные объекты.

private void bindJSONToObject(Object obj, String json) throws IOException, JsonProcessingException {
    MutablePropertyValues mpv = new MutablePropertyValues();
    JsonNode rootNode = new ObjectMapper().readTree(json);
    for (Iterator<Entry<String, JsonNode>> iter = rootNode.getFields(); iter.hasNext(); ) {
        Entry<String, JsonNode> entry = iter.next();
        String name = entry.getKey();
        JsonNode node = entry.getValue();
        if (node.isArray()) {
            List<String> values = new ArrayList<String>();
            for (JsonNode elem : node) {
                values.add(elem.getTextValue());
            }
            mpv.addPropertyValue(name, values);
            if (logger.isDebugEnabled()) {
                logger.debug(name + "=" + ArrayUtils.toString(values));
            }
        }
        else {
            mpv.addPropertyValue(name, node.getTextValue());
            if (logger.isDebugEnabled()) {
                logger.debug(name + "=" + node.getTextValue());
            }
        } 
    }
    DataBinder dataBinder = new DataBinder(obj);
    dataBinder.bind(mpv);
}

Ответ 7

всегда может загружаться в фиктивный объект и использовать отражение для передачи данных. если ваше сердце установлено только с помощью gson

Пример. если этот код находится в объекте, который вы хотите скопировать данные в

    public void loadObject(){
Gson gson = new Gson();
//make temp object
YourObject tempStorage = (YourObject) gson.fromJson(new FileReader(theJsonFile), YourObject.class);
//get the fields for that class
ArrayList<Field> tempFields = new ArrayList<Field>();
ArrayList<Field> ourFields = new ArrayList<Field>();
getAllFields(tempFields, tempStorage.getClass());
getAllFields(thisObjectsFields, this.getClass());
for(Field f1 : tempFields){
    for(Field f2 : thisObjectsFields){
        //find matching fields
        if(f1.getName().equals(f2.getName()) && f1.getType().equals(f2.getType())){
            //transient and statics dont get serialized and deserialized.
            if(!Modifier.isTransient(f1.getModifiers())&&!Modifier.isStatic(f1.getModifiers())){
                //make sure its a loadable thing
                f2.set(this, f1.get(tempStorage));
            }
        }
    }
}

}

public static List<Field> getAllFields(List<Field> fields, Class<?> type) {
    for (Field field : type.getDeclaredFields()) {
        fields.add(field);
    }
    if (type.getSuperclass() != null) {
        fields = getAllFields(fields, type.getSuperclass());
    }
    return fields;
}