我正在尝试为一些BasicNameValuePair对象列表实现自定义gson序列化器/反序列化器。
我在这里看到了部分解决方案代码(用于序列化): How do I get Gson to serialize a list of basic name value pairs?
但是我想实现反序列化,我尝试了机会,代码就在这里:
package dto;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.message.BasicNameValuePair;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
public class KeyValuePairSerializer extends TypeAdapter<List<BasicNameValuePair>> {
@Override
public void write(JsonWriter out, List<BasicNameValuePair> data) throws IOException {
out.beginObject();
for(int i=0; i<data.size();i++){
out.name(data.get(i).getName());
out.value(data.get(i).getValue());
}
out.endObject();
}
@Override
public List<BasicNameValuePair> read(JsonReader in) throws IOException {
ArrayList<BasicNameValuePair> list=new ArrayList<BasicNameValuePair>();
in.beginObject();
while (in.hasNext()) {
String key = in.nextName();
String value = in.nextString();
list.add(new BasicNameValuePair(key,value));
}
in.endObject();
return list;
}
}
初始化和填写列表的代码
ArrayList<BasicNameValuePair> postParameters=new ArrayList<BasicNameValuePair>();
postParameters.add(new BasicNameValuePair("some_key","some_value"));
以下是使用新KeyValuePairSerializer类的代码:
GsonBuilder gsonBuilder= new GsonBuilder();
gsonBuilder.registerTypeAdapter(KeyValuePairSerializer.class, new KeyValuePairSerializer());
Gson gson1=gsonBuilder.create();
//serialization works just fine in the next line
String jsonUpdate=gson1.toJson(postParameters, KeyValuePairSerializer.class);
ArrayList<BasicNameValuePair> postParameters2 = new ArrayList<BasicNameValuePair>();
//postParameters2 = gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class); //? how to cast properly
//deserialization throws an error, it can't cast from ArrayList<BasicNameValuePair> to KeyValuePairSerializer
gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class);
问题是它最后抛出一个异常,我不知道究竟是什么问题,仍然不知道如何编写最后一行来将结果返回到新的postParameters2 ArrayList中。
答案 0 :(得分:9)
GsonBuilder gsonBuilder= new GsonBuilder();
gsonBuilder.registerTypeAdapter(KeyValuePairSerializer.class, new KeyValuePairSerializer());
Gson gson1=gsonBuilder.create();
Type collectionType = new TypeToken<ArrayList<BasicNameValuePair>>(){}.getType();
ArrayList<BasicNameValuePair> postParameters2 = gson1.fromJson(jsonUpdate, collectionType);
答案 1 :(得分:2)
registerTypeAdapter似乎仅适用于序列化程序而不适用于反序列化程序。
调用 KeyValuePairSerializer 的重写读取功能的唯一方法是调用:
gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class);
而不将结果值保存在变量中。虽然它会很好地处理函数,但它会在gson类中抛出一个错误,因为它无法从ArrayList转换为KeyValuePairSerializer。我有点理解为什么(我猜是擦除),只是不知道如何正确地做到这一点。
无论如何,我找到了解决此问题的解决方法。
似乎不是注册gson对象并调用registerTypeAdapter然后使用gson1.toJson(Object src, Type typeOfSrc)
和gson1.fromJson(String json,Class <T> classOfT)
,而是可以通过更简单的方式来反序列化:
KeyValuePairSerializer k= new KeyValuePairSerializer();
parametersList = (ArrayList<BasicNameValuePair>)k.fromJson(jsonUpdate);
答案 2 :(得分:0)
JsonObject和NameValuePair的行为方式与字典类似,如果用例相似,我认为您不需要将其中一个转换为另一个。另外,JsonObject允许您更容易地处理您的值(而不是循环遍历值对的数组以找到获取其值所需的键,JsonObject的行为类似于Map,您可以直接调用键的名称并且它将返回所需的属性):
jsonObject.get("your key").getAsString(); (getAsBoolean(), getAsInt(), etc).
对于您的情况,我将从您的字符串,响应或流创建一个JsonObject,然后将其作为地图访问(如上所示):
JsonParser parser = new JsonParser();
JsonObject o = (JsonObject)parser.parse("your json string");
答案 3 :(得分:-1)
我关注GSON Collection Examples的博客。 链接很容易理解和实现。
public class TimeSerializer implements JsonSerializer<time> {
/**
* Implementing the interface JsonSerializer.
* Notice that the the interface has a generic
* type associated with it.
* Because of this we do not have ugly casts in our code.
* {@inheritDoc}
*/
public JsonElement serialize(
final Time time,
final Type type,
final JsonSerializationContext jsonSerializationContext) {
/**
* Returning the reference of JsonPremitive
* which is nothing but a JSONString.
* with value in the format "HH:MM"
*/
return new JsonPrimitive(String.format("%1$02d:%2$02d",
time.getHour(), time.getMinute()));
}