Gson Custom Deserializer is not working for String Array - android

I am using Realm as database but it cannot save String Array directly.So, I have to convert it into custom object before save. That's why I am writing custom deserializer. However, I find that the deserializer didn't catch the json during debug. (But I change the String[].class to String.class, it catches "Peter")
Now my json from server is
{
"name":"Peter",
"role":[
"user",
"admin"
]
}
Code of registering deserializer for handling String Array:
Gson gson =
new GsonBuilder()
.registerTypeHierarchyAdapter(String[].class, new ListStringResponseDeserializer())

You can try using http://realmgenerator.eu - paste your JSON there and you will get your custom object to store strings (but you have to check the "use classes RealmInt and RealmString for primitive arrays" checkbox).
Then create Gson object using GsonBuilder like here https://gist.github.com/jocollet/91d78da9f47922dc26d6

Your response is not an array of strings, it's an object containing an array of strings. You can deserialize it like this:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
class Test {
class Root {
String name;
String[] role;
}
public static void main(String args[]) {
// JSON from question
String json = "{\n"+
"\n"+
" \"name\":\"Peter\",\n"+
" \"role\":[\n"+
"\n"+
" \"user\",\n"+
" \"admin\"\n"+
" ]\n"+
"}\n"+
"\n";
Gson gson = new GsonBuilder().create();
Root root = gson.fromJson(json, Root.class);
System.out.println(root.name);
for (String s: root.role) {
System.out.println(s);
}
}
}
Output
Peter
user
admin

Related

Gson make firebase-like json from objects

In the past a manually created as list of data, which was stored locally in a database. Now I would like to parse those data and put them through import json option into firebase dbs, but what I get doesn't look like firebase generated json.
What I get is:
[
{
"id":"id_1",
"text":"some text"
},
{
"id":"id_2",
"text":"some text2"
},
...
]
what I want is something like this:
{
"id_1": {
"text":"some text",
"id":"id_1"
},
"id_2":{
"text":"some text2",
"id":"id_1"
},
...
}
my Card class
class Card{
private String id;
private String text;
}
retrieving data
//return list of card
List<Card> cards =myDatabase.retrieveData();
Gson gson = new Gson();
String data = gson.toJson(cards);
So how I can I achieve this (it looks to me) dynamically named properties for json that look like those generated by firebase ?
EDIT:
I found that gson has FieldNamingStrategy interface that can change names of fields. But it looks to me it's not dynamic as I want.
EDIT2
my temp fix was to just override toString()
#Override
public String toString() {
return "\""+id+"\": {" +
"\"text\":" + "\""+text+"\","+
"\"id\":" +"\""+ id +"\","+
"\"type\":"+ "\""+ type +"\""+
'}';
}
Your "temp fix" will store each object as a string not a object.
You need to serialize an object to get that data, not a list.
For example, using a Map
List<Card> cards = myDatabase.retrieveData();
Map<Map<String, Object>> fireMap = new TreeMap<>();
int i = 1;
for (Card c : cards) {
Map<String, Object> cardMap = new TreeMap<>();
cardMap.put("text", c.getText());
fireMap.put("id_" + (i++), cardMap);
}
Gson gson = new Gson();
String data = gson.toJson(fireMap);

Custom GSON parser exclude object instances based on property value

When parsing JSON in Android using the GSON parser, I'd like to implement a rule that will exclude any objects from being created based on property value. For example:
{"people": [
{"first_name": "Bob"},
{"first_name": "Bob", "last_name": "Loblaw"}]}
I want to exclude the first person object because it doesn't have a last name property.
Is this possible at parse time?
It is possible with JsonDeserializer.
Suppose you would have POJOs like
public class Response {
#Getter
private List<Person> people = new ArrayList<>();
}
and
public class Person {
#Getter #Setter
private String first_name, last_name;
}
Creating JsonDeserializer like
public class PersonResponseDeserializer implements JsonDeserializer<Response> {
// Create a new gson to make the default parsing for response object
private final Gson gson = new Gson();
#Override
public Response deserialize(JsonElement json, Type typeOfT
, JsonDeserializationContext context) throws JsonParseException {
Response r = gson.fromJson(json, typeOfT);
// Remove all persons from R that have last name null
r.getPeople().removeAll(
r.getPeople().stream().filter( p -> p.getLast_name() == null )
.collect(Collectors.toSet())
);
return r;
}
}
could then be used like
Gson gson = new GsonBuilder()
.registerTypeAdapter(Response.class, new PersonResponseDeserializer())
.create();
Response r = gson.fromJson(s, Response.class);
So this is if it is required to be done at the parse time. Maybe it is otherwise better to loop the People after parsing and exclude Persons without last name then.

how to check value in JSON

i have this JSON i want check in this JSON has "song" or "fun" and then get value and key "price":
{
"has_error": false,
"response": {
"song": {
"price": "2000"
},
"jok": {
"price": "free_for_now"
}
},
"state_code": 200
}
JSONObject class have a has a method.
Ref Link : http://developer.android.com/reference/org/json/JSONObject.html#has(java.lang.String)
Returns true if this object has a mapping for the name. The mapping may be NULL.
for example
if (json.has("song")) {
JSONObject song = jsonObject.getJSONObject("song");
}
if (json.has("fun")) {
JSONObject fun = jsonObject.getJSONObject("fun");
}
Using the gson only thing you must to do is to create a java class to mapping your json string.
class ModelObject{
boolean has_error;
Response response; // here you have the two objects: Song (with price attribute) and Jok (with price attribute); for these you must create another two classes
int status_code;
}
class Response{
Song song;
Jok jok;
}
class Song{
String price;
}
class Jok{
String price;
}
Be careful to use the same name for every attribute and class name and also generate getters and setters
Then you must use import GSON in your gradle file:
compile 'com.google.code.gson:gson:2.2.4'
Finally only thing you must to do is to use the methods from gson:
final Gson gson = new Gson();
//to deserialize
ModelObject obj = gson.fromJson(yourJson, ModelObject.class);
//to serialize
String toJson = gson.toJson(obj);
In obj you have all information to handle...
use this and right work
JSONObject jsonObject = new JSONObject(response).getJSONObject("response");
if (jsonObject.has("song")) {
JSONObject song = jsonObject.getJSONObject("song");
}

POJO arraylist to String

I'm using retrofit 2 and i defined some POJO to be able to parse my response from ws
public class mPojo
{
public List<mPojo2> field;
}
How can i get the field as a string ?
The answer that fits my needs:
Gson gson = new GsonBuilder().create();
String json = gson.toJson(mPojo.field.get(i));

Parse Json containing a list

I have a trouble finding a way how to parse this JSON.
{
"token":"3c7dbdc69c02eb365b2900d3e5027a08c79fce43",
"profiles":["User","PartnerUser"],
"status":"OK"
}
Plz,i need your hepl. I find atrouble with this "profiles":["User","PartnerUser"]
create a class that represent that json file and then parse it via GSon library:
Possible scenario:
Result.class
public class Result{
String token;
List<String> profiles;
String status;
//getter and setter
}
to parse json:
Gson gson = new Gson();
Result result = gson.fromJson(json, Result.class);
ArrayList<String> profiles = new ArrayList();
profiles = result.getProfiles();
check this
Are you using some library to perform JSON parsing?
If not, you can use the getJSONArray(..) method passing "profiles" as name of the array

Categories

Resources