0

Я использую Apache Collection BidiMap, который предлагает класс DualHashBidiMap. Я должен использовать этот класс для проекта.Как десериализовать пользовательскую карту с помощью 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.

 Смежные вопросы

  • Нет связанных вопросов^_^