Reputation: 799
I'm trying to implement a custom gson serializer/deserialiser for some list of BasicNameValuePair objects.
I saw the partial solution code (for serialization) here: How do I get Gson to serialize a list of basic name value pairs?
However I wanted to implement also deserialization and I tried my chances and the code is here:
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;
}
}
Code to initialize and fill the list
ArrayList<BasicNameValuePair> postParameters=new ArrayList<BasicNameValuePair>();
postParameters.add(new BasicNameValuePair("some_key","some_value"));
And here is the code to use the new KeyValuePairSerializer class:
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);
The problem is that it throws an exception at the end and I don't know where exactly is the problem and still not sure how to write the last line to get the result back in the new postParameters2 ArrayList.
Upvotes: 8
Views: 10919
Reputation: 6250
Both JsonObject's and NameValuePair's behave in a similar way to dictionaries, I don't think you need to convert one into the other if the use case is similar. Additionally JsonObject allows you to treat your values even easier (instead of looping through the array of value pairs to find the key you need to get its value, JsonObject behaves similarly to a Map in a way that you can directly call the name of the key and it'll return the desired property):
jsonObject.get("your key").getAsString(); (getAsBoolean(), getAsInt(), etc).
For your case I'd create a JsonObject from your string, response or stream and then access it as a map (as shown above):
JsonParser parser = new JsonParser();
JsonObject o = (JsonObject)parser.parse("your json string");
Upvotes: 0
Reputation: 2680
I followed this blog for GSON Collection Examples . Link is simple to understand and implement.
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()));
}
Upvotes: -1
Reputation: 799
registerTypeAdapter seems to work only for the serializer not for deserializer.
The only way to call the overridden read function of the KeyValuePairSerializer is to call the:
gson1.fromJson(jsonUpdate, KeyValuePairSerializer.class);
without saving the result value in a variable. While it will process the function just fine, it will throw an error inside gson class because it will not be able to cast from the ArrayList to the KeyValuePairSerializer. And I kinda understand why (erasure I guess), just don't know how to do it properly.
Anyway I found a workaround to solve this issue.
It seems that instead of registering the gson object and calling registerTypeAdapter and then using gson1.toJson(Object src, Type typeOfSrc)
and gson1.fromJson(String json,Class <T> classOfT)
I can get away for deserialization with something simpler like:
KeyValuePairSerializer k= new KeyValuePairSerializer();
parametersList = (ArrayList<BasicNameValuePair>)k.fromJson(jsonUpdate);
Upvotes: 2
Reputation: 4248
Adapted from the GSON Collections Examples:
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);
Upvotes: 9