0

Ich verwende Apache Collection BidiMap, die DualHashBidiMap Klasse bietet. Ich muss diese Klasse für das Projekt verwenden.So entschlüsseln Sie benutzerdefinierte Karte mit GSON

Es gibt kein Problem mit der Serialisierung mit ihm. Aber ich habe ein Problem mit der Deserialisierung !.

Hier eine Beispielklasse:

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; 
    } 
} 

und wichtigste Methode

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) 

Antwort

0

Das ist nicht so einfach ist, aber getan werden kann.

0

Warum brauchen Sie BidiMap?

überprüfen diese:

deserializing generics with gson

How to deserialize a ConcurrentMap with Gson

Versuchen Karte oder LinkedHashMap oder manuell von Map-Parsing später BidiMap eingeben, um zu überprüfen, um, wenn der Fehler weiterhin auftritt. Das Schreiben eines TypeAdapter wäre ebenfalls eine Option.

By the way: Ihre JSON ist keine Map<Integer,String> aber ein Map<String,String> Karte {"1":"gloves","90":"boots"}

Ich habe zuvor versucht Gson und es funktioniert gut mit einheimischen Arten in Java. Ich habe nie versucht, andere Bibliotheken zu analysieren, da ich denke, dass Sie einen TypeAdapter benötigen würden.

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

Jetzt ist Ihre Probe laufen und es sollten Sie arbeiten können:

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)); 
      } 
     }; 
    } 
} 

die TypeAdapterFactory registrieren: