48

Jackson JSONライブラリを取得してJSONを既存のオブジェクトに逆シリアル化する方法を知りたいですか?私はこれを行う方法を見つけようとしました。しかし、それはクラスを取得してそれ自体をインスタンス化することしかできないようです。

または、不可能な場合は、JavaJSON逆シリアル化ライブラリで実行できるかどうかを知りたいです。

これは、C#の対応する質問のようです。JSON文字列から既存のオブジェクトインスタンスにデータをオーバーレイします。JSON.NETにはPopulateObject(string、object)があるようです。

4

8 に答える 8

83

あなたはジャクソンを使用してこれを行うことができます:

mapper.readerForUpdating(object).readValue(json);

Jacksonを使用した2つのJSONドキュメントのマージも参照してください。

于 2013-11-22T20:19:44.060 に答える
1

Jacksonの代わりに別のライブラリを使用できる場合は、Gensonhttp ://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をご利用ください。

于 2012-09-20T19:17:43.477 に答える
1

Spring Frameworkを使用している場合は、このタスクにBeanUtilsライブラリを使用できます。最初にjson文字列を通常どおり逆シリアル化し、次にBeanUtilsを使用してこのオブジェクトを親オブジェクト内に設定します。また、オブジェクトの変数名が親オブジェクト内に設定されていることも必要です。コードスニペットは次のとおりです。

childObject = gson.fromJson("your json string",class.forName(argType))
BeanUtils.setProperty(mainObject, "childObjectName", childObject);
于 2015-08-06T07:25:55.107 に答える
0

1つの解決策は、新しいオブジェクトグラフ/ツリーを解析してから、既存のオブジェクトグラフ/ツリーに統合コピーすることです。ただし、これはもちろん効率が低く、作業量が多くなります。特に、型情報の可用性が低いために具象型が異なる場合はなおさらです。(したがって、実際には答えではありません。より良い答えがあることを願っています。他の人がこのように答えるのを避けたいだけです。)

于 2012-09-20T18:25:19.523 に答える
0

flexJsonも同じことをするのを助けることができます。

これはFlexJsonDocからコピーされた例です

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と同じであることに注意してください。

于 2012-10-12T12:34:35.960 に答える
0

私は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);
}
于 2013-05-09T18:23:49.937 に答える
0

常にダミーオブジェクトにロードし、リフレクションを使用してデータを転送できます。あなたの心が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;
}

于 2014-09-16T20:44:15.680 に答える
0

あなたは私のリポジトリを使うことができます:)。

Object yo = //yourObject
String js = //json source

Map remote = Object$.remoteMap(yo, false); //or you can use Bean.forInstance(yo);
Reader reader = new StringReader(js);//you can replace this with any reader :)
AtomicReference buffer = new AtomicReference(remote);

try {
    JSON.global.parse(buffer, reader, null, null);
} catch (IOException ignored) {
    //If any exception got thrown by the reader
}

このようにして、JSONはバッファー内で検出したマップへの値を解析します。また、マップにリストが含まれていて、JSON値にもリストがある場合。マップ上のリストは置き換えられません。代わりに、値を含めるために使用されます。

返されたリモートマップを使用した場合Bean.forInstance(yo)、いくつかの追加機能があります。

リポジトリ:

util repo(必須):github.com/cufyorg/util

基本リポジトリ(必須):github.com/cufyorg/base

JSONリポジトリ(必須):github.com/cufyorg/json

Beansリポジトリ(オプション):github.com/cufyorg/beans

于 2020-02-19T04:38:03.527 に答える