使用Gson和抽象类 [英] Using Gson and Abstract Classes

查看:213
本文介绍了使用Gson和抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



问题如下:
$ b
我试图在使用GSON的客户端和服务器之间交换消息。 $ b

我有这样的结构:

  public class Message 
{
private TypeOfContent type; //这是一个枚举
私人内容;
....
}

然后对象内容可以是各种



我找到2个教程 here 此处,但没有一个能解决问题。



Edit1:

类Message是这个:






  public class Mensagem 
{
private TipoMensagem类型;

private Conteudo conteudo;

私人Cliente作者;
私人客户destino; // null - >到所有(广播)
}






内容是这样的:



  public class Conteudo 
{

protected TipoConteudo typeConteudo;

保护字符串texto;

保护Posicao posicao;

public Conteudo(TipoConteudo typeConteudo,String texto,Posicao posicao)
{
this.texto = texto;
this.posicao = posicao;
this.typeConteudo = typeConteudo;
}
}



contedo的扩展类的一个例子是1:

  public class ConteudoTweet extends Conteudo 
{

保护字符串pathImagem;


public ConteudoTweet(TipoConteudo typeConteudo,String tweet,Posicao location,String picturePath)
{
super(typeConteudo,tweet,location);

this.pathImagem = picturePath;

}



}






最后我做的是这样的:String strObject = new Gson()。toJson(mensage);哪些工作,但反序列化它并不是因为它假定它始终是从内容类

解决方案

我终于解决了它!

  // GSON 

GsonBuilder gsonBilder = new GsonBuilder();
gsonBilder.registerTypeAdapter(Conteudo.class,new InterfaceAdapter< Conteudo>());
gsonBilder.setPrettyPrinting();

Gson gson = gsonBilder.create();

String str2send = gson.toJson(message);

Mensagem msg_recv = gson.fromJson(str2send,Mensagem.class);

请注意:registerTypeAdapter( AbstractClass.class ,new InterfaceAdapter() );



通过 AbstractClass.class ,我的意思是你正在实现的类是Conteúdo,可以是ConteudoTweet或ConteudoUserSystem,等等......



InterfaceAdapter 的实现是:

  import java.lang.reflect.Type; 

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class InterfaceAdapter< T>
实现了JsonSerializer< T>,JsonDeserializer< T> {

@Override
public final JsonElement serialize(final T object,final Type interfaceType,final JsonSerializationContext context)
{
final JsonObject member = new JsonObject();

member.addProperty(type,object.getClass()。getName());

member.add(data,context.serialize(object));

返回成员;

$ b @Override
public final T反序列化(final JsonElement elem,final Type interfaceType,final JsonDeserializationContext context)
throws JsonParseException
{
final JsonObject member =(JsonObject)elem;
final JsonElement typeString = get(member,type);
final JsonElement data = get(member,data);
final类型actualType = typeForName(typeString);

return context.deserialize(data,actualType);

$ b $ private类型typeForName(final JsonElement typeElem)
{
try
{
return Class.forName(typeElem.getAsString() );
}
catch(ClassNotFoundException e)
{
throw new JsonParseException(e);



private JsonElement get(final JsonObject wrapper,final String memberName)
{
final JsonElement elem = wrapper.get(memberName);

if(elem == null)
{
抛出新的JsonParseException(
no+ memberName +'json文件中找到的成员。
}
return elem;
}

}

这个InterfaceAdapter是通用的,所以它应该一般工作......



就是这样!

I'm trying to exchange messages between a client and a server using GSON.

The problem is the following:

I have this structure:

public class Message 
{
    private TypeOfContent type; //  It's a enum 
    private Content       content;
    ....
}

Then the object content can be a various set of Classes.

I found 2 tutorials here and here, but none of them solves the problem.

Edit1:

The class Message is this one:


public class Mensagem
{
private TipoMensagem    type;

    private Conteudo        conteudo;

    private Cliente         autor;
    private Cliente         destino;    // null -> to all(broadcast)
}


And Content is this one:

public class Conteudo
{

protected   TipoConteudo typeConteudo; 

protected   String      texto;

protected   Posicao     posicao;

public Conteudo(TipoConteudo typeConteudo, String texto, Posicao posicao)
{
    this.texto   = texto;
    this.posicao = posicao;  
    this.typeConteudo = typeConteudo;
}    
} 

And an example of a extend class from contedo is this one:

public class ConteudoTweet extends Conteudo 
{

protected   String      pathImagem;


public ConteudoTweet(TipoConteudo typeConteudo, String tweet, Posicao location, String picturePath) 
{
    super(typeConteudo,tweet, location);

    this.pathImagem = picturePath;

}



}


Finaly what i do is like : "String strObject = new Gson().toJson(mensage);" which works but on deserialization it doesnt because it assumes always that it is from Content class

解决方案

I finally solved it!

    // GSON

    GsonBuilder gsonBilder = new GsonBuilder();
    gsonBilder.registerTypeAdapter(Conteudo.class, new InterfaceAdapter<Conteudo>());
    gsonBilder.setPrettyPrinting();

    Gson gson =gsonBilder.create();

    String str2send = gson.toJson(message);

    Mensagem msg_recv = gson.fromJson(str2send,Mensagem.class);

Note that: "registerTypeAdapter(AbstractClass.class, new InterfaceAdapter());"

by AbstractClass.class i mean the class that you are implementing in my case it was Conteúdo that could be ConteudoTweet or ConteudoUserSystem and so on...

The implementation of InterfaceAdapter is :

import java.lang.reflect.Type;

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;

public class InterfaceAdapter<T>
    implements JsonSerializer<T>, JsonDeserializer<T> {

    @Override
    public final JsonElement serialize(final T object, final Type interfaceType, final JsonSerializationContext context) 
    {
        final JsonObject member = new JsonObject();

        member.addProperty("type", object.getClass().getName());

        member.add("data", context.serialize(object));

        return member;
    }

    @Override
    public final T deserialize(final JsonElement elem, final Type interfaceType, final JsonDeserializationContext context) 
            throws JsonParseException 
    {
        final JsonObject member = (JsonObject) elem;
        final JsonElement typeString = get(member, "type");
        final JsonElement data = get(member, "data");
        final Type actualType = typeForName(typeString);

        return context.deserialize(data, actualType);
    }

    private Type typeForName(final JsonElement typeElem) 
    {
        try 
        {
            return Class.forName(typeElem.getAsString());
        } 
        catch (ClassNotFoundException e) 
        {
            throw new JsonParseException(e);
        }
    }

    private JsonElement get(final JsonObject wrapper, final String memberName) 
    {
        final JsonElement elem = wrapper.get(memberName);

        if (elem == null) 
        {
            throw new JsonParseException(
                "no '" + memberName + "' member found in json file.");
        }
        return elem;
    }

}

And this InterfaceAdapter is generic so it should work in general...

That's it!

这篇关于使用Gson和抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆