0

DualHashBidiMapクラスを提供するApache CollectionのBidiMapを使用しています。このクラスをプロジェクトに使用する必要があります。カスタムマップをGSONでデシリアライズする方法

シリアル化に問題はありません。しかし、私は脱直列化に問題がある!ここで

は、サンプルクラスです:

package com.description; 

import org.apache.commons.collections4.BidiMap; 
import org.apache.commons.collections4.bidimap.DualHashBidiMap; 

public class Sample { 

    private String id; 
    private String adress; 

    BidiMap<Integer, String> items = new DualHashBidiMap<Integer, String>(); 


    public Sample() { 
    } 

    public String getId() { 
     return id; 
    } 

    public void setId(String id) { 
     this.id = id; 
    } 

    public String getAdress() { 
     return adress; 
    } 

    public void setAdress(String adress) { 
     this.adress = adress; 
    } 

    public BidiMap<Integer, String> getItems() { 
     return items; 
    } 

    public void setItems(BidiMap<Integer, String> items) { 
     this.items = items; 
    } 
} 

そして、メイン方法

Sample sample = new Sample(); 
     sample.setId("12312xoa01"); 
     sample.setAdress("Houston, 43.1"); 
     BidiMap<Integer, String> items = new DualHashBidiMap<Integer, String>(); 
     items.put(1, "gloves"); 
     items.put(90, "boots"); 
     sample.setItems(items); 

     try { 
      String result = gson.toJson(sample); 
      System.out.println("result : "+result); 
      Sample sample2 = gson.fromJson(result, Sample.class); 
      System.out.println("address : "+sample2.getAdress()); 

     }catch (Exception e){ 
      e.printStackTrace(); 
     } 

**


**

result : {"id":"12312xoa01","adress":"Houston, 43.1","items":{"1":"gloves","90":"boots"}} 
java.lang.IllegalArgumentException: Can not set org.apache.commons.collections4.BidiMap field com.description.Sample.items to java.util.LinkedHashMap 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) 
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) 
    at java.lang.reflect.Field.set(Field.java:741) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:118) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:216) 
    at com.google.gson.Gson.fromJson(Gson.java:879) 
    at com.google.gson.Gson.fromJson(Gson.java:844) 
    at com.google.gson.Gson.fromJson(Gson.java:793) 
    at com.google.gson.Gson.fromJson(Gson.java:765) 
    at Main.main(Main.java:79) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) 

答えて

0

ことは簡単ではありませんが、行うことができます。

public class BidiMapTypeAdapterFactory implements TypeAdapterFactory { 

    @Override 
    public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) { 
     if (!BidiMap.class.isAssignableFrom(type.getRawType())) { 
      return null; 
     } 
     final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type); 
     return new TypeAdapter<T>() { 
      @Override 
      public void write(JsonWriter out, T value) throws IOException { 
       delegate.write(out, value); 
      } 

      @Override 
      public T read(JsonReader in) throws IOException { 
       return (T) new DualHashBidiMap<>((Map) delegate.read(in)); 
      } 
     }; 
    } 
} 

TypeAdapterFactoryを登録します。

GsonBuilder b = new GsonBuilder().registerTypeAdapterFactory(new BidiMapTypeAdapterFactory()); 
Gson gson = b.create(); 

今、あなたはあなたのサンプルを実行することができ、それが動作するはずです。

0

なぜBidiMapを使用する必要がありますか?

これらをチェックしてください:

deserializing generics with gson

How to deserialize a ConcurrentMap with Gson

は、エラーが続くかどうかを確認するために、地図やのLinkedHashMapを使用して以降BidiMap型に地図から手動で解析してみます。 TypeAdapterを書くこともオプションになります。ところで

:あなたのJSONがMap<Integer,String>ではなく、Map<String,String>マップ{"1":"gloves","90":"boots"}

は、私が以前にGSONを試してみました、それはJavaでネイティブ型とうまく動作します。 TypeAdapterが必要だと思うので、他のライブラリの解析を試みたことはありませんでした。

関連する問題