2016-08-02 108 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。 –