使用Gson和抽象类 [英] Using Gson and Abstract Classes
问题描述
问题如下:
$ b 我试图在使用GSON的客户端和服务器之间交换消息。 $ b
我有这样的结构:
public class Message
{
private TypeOfContent type; //这是一个枚举
私人内容;
....
}
然后对象内容可以是各种
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;
}
}
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屋!