2016-08-02 109 views
0

我使用Gson反序列化一些JSON字符串實例化接口(實際上這是JWT)通過由HTTP標頭。該json包含:GSON:從JSON字符串

[ 
    {"authority":"a1"}, 
    {"authority":"a2"}, 
    {"authority":"a3"}, 
      . 
      . 
      . 
    {"authority":"a4"}, 
] 

in JsonElement。 我想上面的部分被反序列化到現場(在某些類):

Set<GrantedAuthority> authorities 

哪裏GrantedAuthority是春天的接口,它有一個實現SimpleGrantedAuthoritySimpleGrantedAuthority有一個構造函數的字符串:

公共SimpleGrantedAuthority(字符串AU){this.au = AU}

我需要GSON知道實現類接口GrantedAuthority,以反序列化JSON的。我嘗試:

public class GrantedAuthorityInstanceCreator implements InstanceCreator<GrantedAuthority> { 
    @Override 
    public GrantedAuthority createInstance(Type type) { 
     // no such constructor 
     GrantedAuthority ga = new SimpleGrantedAuthority(); 
     return ga; 
    } 
} 

但由於SimpleGrantedAuthority沒有無參數的構造函數,我需要提供一個參數構造函數。我怎樣才能做到這一點?

+0

如何描述涉及到的稱號?你想達到什麼目的? – waltersu

+0

@waltersu我想反序列化json字符串到該字段,但它是一個接口類型,我不知道如何編程gson來實例化該接口使用實現'SimpleGrantedAuthority' –

+0

爲什麼不將它們反序列化爲'SimpleGrantedAuthority',並自己創建'Set '並將它們放入集合中? – waltersu

回答

0

InstanceCreator將無法​​正常工作。根據gson-user-guide。你有3個選項:

選項1:使用GSON解析器API(低電平流解析器或DOM解析器JsonParser)來解析該數組元素,然後在每個陣列元件使用Gson.fromJson()。這是首選的方法。以下是演示如何執行此操作的示例。

選項2:註冊Collection.class一個類型的適配器,着眼於各陣列成員並將其映射到適當的對象。這種方法的缺點是它會在Gson中搞亂其他集合類型的反序列化。

選項3:爲MyCollectionMemberType註冊一個類型適配器,並使用fromJson與Collection 只有當數組顯示爲頂級元素或者您可以將持有集合的字段類型更改爲類型Collection時,此方法纔是實用的。

你說

而且我想上面的部分被反序列化到現場(在某些類):

因此,假設「一些一流」是MyClassauthoritiesMyClass一個領域的JSON字符串(並有其他領域的MyClass)。下面是一個使用方法「選項3」的一個例子的代碼:

import com.google.gson.Gson; 
import com.google.gson.GsonBuilder; 
import com.google.gson.TypeAdapter; 
import com.google.gson.stream.JsonReader; 
import com.google.gson.stream.JsonWriter; 

import java.io.IOException; 
import java.util.Set; 

public class Test2 { 
    public static void main(String[] args) throws Exception { 
    String json = "{ authorities: [\n" + 
     " {\"authority\":\"a1\"},\n" + 
     " {\"authority\":\"a2\"},\n" + 
     " {\"authority\":\"a3\"},\n" + 
     " {\"authority\":\"a4\"}\n" + 
     "]}"; 

    GsonBuilder gsonBuilder = new GsonBuilder(); 
    gsonBuilder.registerTypeHierarchyAdapter(GrantedAuthority.class, new GrantedAuthorityTypeAdaptor()); 
    Gson gson = gsonBuilder.create(); 

    MyClass obj1 = gson.fromJson(json, MyClass.class); 
    for (GrantedAuthority au : obj1.authorities) { 
     SimpleGrantedAuthority sgau = (SimpleGrantedAuthority) au; 
     System.out.println(sgau.authority); 
    } 
    } 
} 


class MyClass { 
    Set<GrantedAuthority> authorities; 

    // other fields 
} 


interface GrantedAuthority { 
} 

class SimpleGrantedAuthority implements GrantedAuthority { 
    final String authority; 

    public SimpleGrantedAuthority(String au) { 
    this.authority = au; 
    } 
} 

class GrantedAuthorityTypeAdaptor extends TypeAdapter<GrantedAuthority> { 
    @Override 
    public void write(JsonWriter out, GrantedAuthority value) throws IOException { 
    new Gson().getAdapter(SimpleGrantedAuthority.class).write(out, (SimpleGrantedAuthority) value); 
    } 

    @Override 
    public GrantedAuthority read(JsonReader in) throws IOException { 
    return new Gson().getAdapter(SimpleGrantedAuthority.class).read(in); 
    } 
} 

的方法是使用SimpleGrantedAuthorityAdaptor作爲GrantedAuthority的適配器。

爲了不弄亂其他代碼,該GsonBuilder應該只在這裏使用。您應該在其他代碼中創建一個新的GsonBuilder

+0

我在'SimpleGrantedAuthority'中爲''權限'獲得了'NullPointerException'。看來該字段爲空。有一點需要注意的是我使用了'JsonElement'。 'jsonElement = gson.toJsonTree(body.get(「key」))''然後''gson.fromJson(jsonElement,Myclass.class)''。 'body.get(「key」)'實際上返回一個HashMap,我可以使用它來實例化Myclass。這有點複雜,因爲傳遞給我的令牌實際上是一個JWT令牌,我需要先解密它,這會產生一個HashMap。 –