java - 傑克遜-反序列化泛型類變量




json jackson (3)

我錯誤地發布了這個問題。 我在這裡發布的問題正確...

我得到一個JSON字符串作為HTTP響應。 我知道它的結構。 具體如下:

public class Json<T> {
    public Hits<T> hits;
}
public class Hits<T> {
    public int found;
    public int start;
    public ArrayList<Hit<T>> hit;
}
public class Hit<T> {
    public String id;
    public Class<T> data;
}

“數據”字段可以屬於任何類別。 我只會在運行時才知道它。 我將把它作為一個參數。 這就是我的反序列化。

public <T> void deSerialize(Class<T> clazz {
    ObjectMapper mapper = new ObjectMapper();
    mapper.readValue(jsonString,  new TypeReference<Json<T>>() {});
}

但是我得到一個錯誤 -

不能從java.lang.class中訪問private java.lang.class.Class()。 無法設置訪問權限。 無法訪問java.lang.Class構​​造函數


反序列化泛型類變量

...

我怎麼把它告訴傑克遜? gson會做得更好嗎?

Gson的用戶指南中包含了一個關於我正在嘗試完成的內容的部分,儘管這個記錄的示例可能仍然不完整。

在博客文章中,我更詳細地介紹了使用Gson 1.7.1的解決方案。 以下是相關的代碼示例。

使用傑克遜(1.8.2)的類似(但更多參與)的解決方案也在同一篇博文中被展示和描述。 (不同的方法和示例使用了數百行代碼,所以我忽略了在這裡重新發布它們。)

public class GsonInstanceCreatorForParameterizedTypeDemo  
{  
 public static void main(String[] args)  
 {  
  Id<String> id1 = new Id<String>(String.class, 42);  

  Gson gson = new GsonBuilder().registerTypeAdapter(Id.class,  
    new IdInstanceCreator()).create();  
  String json1 = gson.toJson(id1);  
  System.out.println(json1);  
  // actual output: {"classOfId":{},"value":42}  
  // This contradicts what the Gson docs say happens.  
  // With custom serialization, as described in a  
  // previous Gson user guide section,   
  // intended output may be   
  // {"value":42}  

  // input: {"value":42}  
  String json2 = "{\"value\":42}";  

  Type idOfStringType=new TypeToken<Id<String>>(){}.getType();  
  Id<String> id1Copy = gson.fromJson(json2, idOfStringType);  
  System.out.println(id1Copy);  
  // output: classOfId=class java.lang.String, value=42  

  Type idOfGsonType = new TypeToken<Id<Gson>>() {}.getType();  
  Id<Gson> idOfGson = gson.fromJson(json2, idOfGsonType);  
  System.out.println(idOfGson);  
  // output: classOfId=class com.google.gson.Gson, value=42  
 }  
}  

class Id<T>  
{  
 private final Class<T> classOfId;  
 private final long value;  

 public Id(Class<T> classOfId, long value)  
 {  
  this.classOfId = classOfId;  
  this.value = value;  
 }  

 @Override  
 public String toString()  
 {  
  return "classOfId=" + classOfId + ", value=" + value;  
 }  
}  

class IdInstanceCreator implements InstanceCreator<Id<?>>  
{  
 @SuppressWarnings({ "unchecked", "rawtypes" })  
 public Id<?> createInstance(Type type)  
 {  
  Type[] typeParameters =   
    ((ParameterizedType) type).getActualTypeArguments();  
  Type idType = typeParameters[0];  
  return new Id((Class<?>) idType, 0L);  
 }  
} 

你正在序列化和反序列化JSON類對象? 也許在Hit中保持它為String,並創建額外的啟動Class.forName的getter,例如

public class Hit {
    public String id;
    public String data;
    public Class<?> getDataClass() throws Exception {
       return Class.forName(data);
    }
}

示例通用反序列化接口:

public interface Deserializable<T> {
    static final ObjectMapper mapper = new ObjectMapper();

    @SuppressWarnings("unchecked")
    default T deserialize(String rawJson) throws IOException {
        return mapper.readValue(rawJson, (Class<T>) this.getClass());
    }
}




generics