deserializing a JSON file with GSON - java

I develop an Android application and I have to deserialize a JSON file.
I have these classes:
public class Medicine {
#SerializedName("substanta_activa")
private List<String> active_substance;
#SerializedName("produse")
private List<Product> product;
#SerializedName("dozaj")
private Dosage dosage;
#SerializedName("mentiuni")
private List<String> notes;
#SerializedName("cuvinte_cheie")
private List<String> keyword;
/* + getters and setters */
}
public class Product {
#SerializedName("denumire_comerciala")
private String productName;
#SerializedName("forme_de_prezentare")
private List<String> form;
/* + getters and setters */
}
public class Dosage {
#SerializedName("nounascuti")
private String newborn;
#SerializedName("copii")
private String child;
#SerializedName("adulti")
private String adult;
/* + getters and setters */
}
And I have the following JSON file:
[
{
"substanta_activa": [
"trimebutinum"
],
"produse": [
{
"denumire_comerciala": "Debridat",
"forme_de_prezentare": [
"susp. buvabilă",
"susp. 24mg/5ml în flac 250ml",
"compr 100mg"
]
},
{
"denumire_comerciala": "Ibutin",
"forme_de_prezentare": [
"compr 300mg"
]
},
{
"denumire_comerciala": "Trimebutin",
"forme_de_prezentare": [
"compr 100mg"
]
},
{
"denumire_comerciala": "Colperin",
"forme_de_prezentare": [
"compr 100mg"
]
}
],
"dozaj": {
"nounascuti": "1ml/kg/zi div 3,",
"copii": "1ml/kg/zi div 3, peste 5 ani 3x10ml",
"adulti": "3x1-2 compr/zi, 1x300mg/zi sau 3x1-2 lingură/zi"
},
"mentiuni": [
"se poate administra de la naștere",
"se poate administra amestecat cu apă, lapte",
"10ml conține 6g zahăr"
],
"cuvinte_cheie": [
"gastro",
"colică",
"dureri abdominale funcționale",
"constipație"
]
},
{
"substanta_activa": [
"benzydaminum"
],
"produse": [
{
"denumire_comerciala": "Tantum Verde comprimate",
"forme_de_prezentare": [
"pastile pt supt 3mg"
]
},
{
"denumire_comerciala": "Tantum Verde spray",
"forme_de_prezentare": [
"spray bucofaringian 0,15%, 0,3%"
]
}
],
"dozaj": {
"nounascuti": "contraindicat",
"copii": "2-6 ani: 2-6x1 puf/4kg; >6 sni: 2-6x 4doze sau 3x1 pastila/zi",
"adulti": "2-6x 4puf sau 3x1 pastila/zi"
},
"mentiuni": [
"se admin. max. 7 zile"
],
"cuvinte_cheie": [
"antiseptic, anestezic, antiinflamator, oral, OTC"
]
}
]
I have tried several ways, with GSON and without it as well but with no success. Thank you for your help in advance.
EDIT
A little bit more detail:
I have a MainPageActivity, where I initialize an Inputstream, set a path and call my deserialize method from JSONParser class:
InputStream is = null;
String internalStoragePath = getApplicationContext().getFilesDir().getAbsolutePath();
File fileToInternalStorage = new File(internalStoragePath + "/medicinelist.json");
try {
is = new FileInputStream(fileToInternalStorage);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
if (is == null) {
is = getResources().openRawResource(R.raw.gyogyszerek);
}
jsonParser = new JSONParser();
try {
medicines = jsonParser.readJsonStream(getApplicationContext(), is);
//medicines = jsonParser.jsonDeserializer(getApplicationContext(), is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
In my JSONParser class, as I have mentioned I have tried several ways to deserialize the JSON input.
Here is the "traditional" way, with Android's built-in JsonReader class (sorry, a little bit long):
public ArrayList readJsonStream(Context applicationContext, InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
try {
return readMedicineArray(reader);
} finally {
reader.close();
}
}
public ArrayList readMedicineArray(JsonReader reader) throws IOException {
ArrayList medicines = new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
medicines.add(readMedicine(reader));
}
reader.endArray();
return medicines;
}
public Medicine readMedicine(JsonReader reader) throws IOException {
List active_substance = null;
List product = null;
Dosage dosage = null;
List notes = null;
List keyword = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("substanta_activa")) {
active_substance = readActiveSubstanceArray(reader);
} else if (name.equals("produse")) {
product = readProductArray(reader);
} else if (name.equals("dozaj")) {
dosage = readDosage (reader);
} else if (name.equals("mentiuni") && reader.peek() != JsonToken.NULL) {
notes= readNotesArray(reader);
} else if (name.equals("cuvinte_cheie") && reader.peek() != JsonToken.NULL) {
keyword = readKeywordArray(reader);
} else {
reader.skipValue();
}
}
reader.endObject();
return new Medicine(active_substance, product, dosage, notes, keyword);
}
public List readActiveSubstanceArray(JsonReader reader) throws IOException {
List active_substance = new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
active_substance.add(reader.nextString());
}
reader.endArray();
return active_substance;
}
public List readProductArray(JsonReader reader) throws IOException {
List product = new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
product.add(readProduct(reader));
}
reader.endArray();
return product;
}
public Product readProduct(JsonReader reader) throws IOException {
String productName = null;
List form = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("denumire_comerciala")) {
productName = reader.nextString();
} else if (name.equals("forme_de_prezentare")) {
form = readFormArray(reader);
} else {
reader.skipValue();
}
}
reader.endObject();
return new Product(productName, form);
}
public List readFormArray(JsonReader reader) throws IOException {
List form = new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
form.add(reader.nextString());
}
reader.endArray();
return form;
}
public Dosage readDosage(JsonReader reader) throws IOException {
String newborn= null;
String child= null;
String adult= null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if (name.equals("nounascuti")) {
newborn= reader.nextString();
} else if (name.equals("copii")) {
child= reader.nextString();
} else if (name.equals("adulti")) {
adult= reader.nextString();
} else {
reader.skipValue();
}
}
reader.endObject();
return new Dosage(newborn, child, adult);
}
public List readNotesArray(JsonReader reader) throws IOException {
List notes= new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
notes.add(reader.nextString());
}
reader.endArray();
return notes;
}
public List readKeywordArray(JsonReader reader) throws IOException {
List keyword= new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
keyword.add(reader.nextString());
}
reader.endArray();
return keyword;
}
And here is the other way with GSON library:
public ArrayList<Medicine> jsonDeserializer(Context contexts, InputStream in) throws IOException {
Reader reader = new InputStreamReader(in);
ArrayList medicinesList = new ArrayList();
final GsonBuilder gsonBuilder = new GsonBuilder();
final Gson gson = gsonBuilder.create();
Medicine[] medicinesArray = new Gson().fromJson(reader, Medicine[].class);
for(int i = 0; i < medicinesArray.length; ++i){
medicinesList.add(medicinesArray[i]);
}
return medicinesList;
}
None of them works, but I don't know what is the problem.

//try this
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<Medicine>>() {}.getType();
List<Medicine> medList = gson.fromJson(<YOUR JSON STRING>, listType);

1) Firstly create your classes like this:
public class Produse
{
public String Denumire_comerciala;
public List<String > Forme_de_prezentare;
}
public class Dosage
{
public String Nounascuti;
public String Copii;
public String Adulti;
}
public class RootObject
{
public List<String > Substanta_activa;
public List<Produse> Produse;
public Dosage Dozaj;
public List<String > Mentiuni;
public List<String > Cuvinte_cheie;
}
2) Then use gson like in this way:
Gson _gson = new GsonBuilder().create();
RootObject root= gson.fromJson("*YOUR JSON HERE*", RootObject .class);
Hope it will help.

use this method:
public static <T> T JsonParse(T t, String response)
throws JsonSyntaxException, IOException, XmlPullParserException {
InputStream in = new ByteArrayInputStream(response.getBytes());
JsonReader reader;
reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
GsonBuilder b = new GsonBuilder();
Gson gson = b.create();
t = (T) gson.fromJson(reader, t.getClass());
reader.close();
return t;
}
use this method:
ArrayList<Medicine> arrlist=JsonParse(new Medicine(),JsonResponse);
i hope its useful to you.

Related

JSON flattener returning only last object from JSON to a flattened form

I have a JSON that looks like below,
{
"users": [
{
"displayName": "Sharad Dutta",
"givenName": "",
"surname": "",
"extension_user_type": "user",
"identities": [
{
"signInType": "emailAddress",
"issuerAssignedId": "kkr007#gmail.com"
}
],
"extension_timezone": "VET",
"extension_locale": "en-GB",
"extension_tenant": "EG12345"
},
{
"displayName": "Sharad Dutta",
"givenName": "",
"surname": "",
"extension_user_type": "user",
"identities": [
{
"signInType": "emailAddress",
"issuerAssignedId": "kkr007#gmail.com"
}
],
"extension_timezone": "VET",
"extension_locale": "en-GB",
"extension_tenant": "EG12345"
}
]
}
I have the above code and it is able to flatten the JSON like this,
{
"extension_timezone": "VET",
"extension_tenant": "EG12345",
"extension_locale": "en-GB",
"signInType": "userName",
"displayName": "Wayne Rooney",
"surname": "Rooney",
"givenName": "Wayne",
"issuerAssignedId": "pdhongade007",
"extension_user_type": "user"
}
But the code is returning only the last user in the "users" array of JSON. It is not returning the first user (essentially the last user only, no matter how many users are there) just the last one is coming out in flattened form from the "users" array.
public class TestConvertor {
static String userJsonAsString;
public static void main(String[] args) throws JSONException {
String userJsonFile = "C:\\Users\\Administrator\\Desktop\\jsonRes\\json_format_user_data_input_file.json";
try {
userJsonAsString = readFileAsAString(userJsonFile);
} catch (Exception e1) {
e1.printStackTrace();
}
JSONObject object = new JSONObject(userJsonAsString); // this is your input
Map<String, Object> flatKeyValue = new HashMap<String, Object>();
System.out.println("flatKeyValue : " + flatKeyValue);
readValues(object, flatKeyValue);
System.out.println(new JSONObject(flatKeyValue)); // this is flat
}
static void readValues(JSONObject object, Map<String, Object> json) throws JSONException {
for (Iterator it = object.keys(); it.hasNext(); ) {
String key = (String) it.next();
Object next = object.get(key);
readValue(json, key, next);
}
}
static void readValue(Map<String, Object> json, String key, Object next) throws JSONException {
if (next instanceof JSONArray) {
JSONArray array = (JSONArray) next;
for (int i = 0; i < array.length(); ++i) {
readValue(json, key, array.opt(i));
}
} else if (next instanceof JSONObject) {
readValues((JSONObject) next, json);
} else {
json.put(key, next);
}
}
private static String readFileAsAString(String inputJsonFile) throws Exception {
return new String(Files.readAllBytes(Paths.get(inputJsonFile)));
}
}
Please suggest where I am doing wrong or my code needs modification.
Please try the below approach, this will give you a comma separated format for both user and identifier (flat file per se),
public static void main(String[] args) throws JSONException, ParseException {
String userJsonFile = "path to your JSON";
final StringBuilder sBuild = new StringBuilder();
final StringBuilder sBuild2 = new StringBuilder();
try {
String userJsonAsString = convert your JSON to string and store in var;
} catch (Exception e1) {
e1.printStackTrace();
}
JSONParser jsonParser = new JSONParser();
JSONObject output = (JSONObject) jsonParser.parse(userJsonAsString);
try {
JSONArray docs = (JSONArray) output.get("users");
Iterator<Object> iterator = docs.iterator();
while (iterator.hasNext()) {
JSONObject userEleObj = (JSONObject)iterator.next();
JSONArray nestedIdArray = (JSONArray) userEleObj.get("identities");
Iterator<Object> nestIter = nestedIdArray.iterator();
while (nestIter.hasNext()) {
JSONObject identityEleObj = (JSONObject)nestIter.next();
identityEleObj.keySet().stream().forEach(key -> sBuild2.append(identityEleObj.get(key) + ","));
userEleObj.keySet().stream().forEach(key -> {
if (StringUtils.equals((CharSequence) key, "identities")) {
sBuild.append(sBuild2.toString());
sBuild2.replace(0, sBuild2.length(), "");
} else {
sBuild.append(userEleObj.get(key) + ",");
}
});
}
sBuild.replace(sBuild.lastIndexOf(","), sBuild.length(), "\n");
}
System.out.println(sBuild);
} catch (Exception e) {
e.printStackTrace();
}
}

Parse JSON Objects and store them in to an existing ArrayList

I have a method that writes my objects in to a JSON file, is there a way I can read the objects and store them back in to an ArrayList? Ideally I would like to store the objects in to the 'music' ArrayList.
Write to JSON method:
public class TimelineLayout extends JFrame {
private static final long serialVersionUID = 1L;
private JLabel timelineLabel;
static ArrayList<Music> music = new ArrayList<>();
public static void saveMusic(ArrayList<Music> music, String filename) {
String fn;
Gson gson = new Gson();
JsonElement element = gson.toJsonTree(music, new TypeToken<ArrayList<Music>>() {
}.getType());
JsonArray jsonArray = element.getAsJsonArray();
String json = gson.toJson(jsonArray);
try {
//write converted json data to a file named "objects.json"
if (filename != null) {
fn = "objects.json";
} else {
fn = filename + ".json";
}
FileWriter writer = new FileWriter(fn);
writer.write(json);
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
JSON Objects:
[{
"artist": "Usher",
"title": "U got it bad",
"genre": "Pop",
"duration": 3.01,
"year": 2003
},
{
"artist": "Coldplay",
"title": "Viva la vida",
"genre": "Rock n ",
"duration": 2.56,
"year": 2001
}
]
Trying to parse using GSON library:
public static List<Music> loadMusic() {
ArrayList<Music> musicList = new ArrayList<>();
Gson gson = new Gson();
JsonParser jsonParser = new JsonParser();
try {
BufferedReader br = new BufferedReader(new FileReader("objects.json"));
JsonElement jsonElement = jsonParser.parse(br);
//Create generic type
java.lang.reflect.Type type = new TypeToken<List<Music>>() {
}.getType();
return gson.fromJson(jsonElement, type);
} catch (IOException e) {
e.printStackTrace();
}
return musicList;
}

Gson - How do you store properties and values

How do I go about storing the values for "id" and "name" as HashMap<Integer, String> respectively?
Currently, dumping out pseudoStations gives me [{"id":0,"name":"London"}, {"id":1,"name":"Nottingham"}]. Iterating through would just give me a JsonObject for each list element.
Main Class
public static void main(String[] args) {
Gson gson = new Gson();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("stations.json"));
StationManager sm = gson.fromJson(br, StationManager.class);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (br != null) {
closeBufferedReader(br);
}
}
}
Station Manager Class
public class StationManager {
#SerializedName("pseudoStations")
#Expose
private List<JsonObject> pseudoStations = null;
public void setPseudoStations(List<JsonObject> pseudoStations) {
this.pseudoStations = pseudoStations;
}
}
stations.json
{
"pseudoStations":[
{
"id": 0,
"name": "London"
},
{
"id": 1,
"name": "Nottingham"
}
]
}
You can loop through the List of JSONObject from StationManager and add the data to HashMap.
public static void main(String[] args) {
Map<Integer, String> output = new HashMap<Integer, String>();
Gson gson = new Gson();
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("stations.json"));
StationManager sm = gson.fromJson(br, StationManager.class);
List<JsonObject> listOfObjs = sm.getPseudoStations();
for(JsonObject obj: listOfObjs){
output.put(obj.getInt("id"), obj.getString("name"));
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (br != null) {
closeBufferedReader(br);
}
}
}

Json parsing with nested array using Gson

I have not seen an (answered) example on the web which discusses this kind of nested-json-array.
JSON to be parsed:
{
"Field": {
"ObjectsList": [
{
"type": "Num",
"priority": "Low",
"size": 3.43
},
{
"type": "Str",
"priority": "Med",
"size": 2.61
}
]
}
}
I created a class for each 'level' of nested json block. I want to be able to parse the contents of the "ObjectList" array.
Can anyone help me to parse this JSON using Gson in Java?
Any hints or code-snippets would be greatly appreciated.
My approach is the following:
public static void main (String... args) throws Exception
{
URL jsonUrl = new URL("http://jsonUrl.com") // cannot share the url
try (InputStream input = jsonUrl.openStream();
BufferedReader buffReader = new BufferedReader (new InputStreamReader (input, "UTF-8")))
{
Gson gson = new GsonBuilder().create();
ClassA classA = gson.fromJson(buffReader, ClassA.class);
System.out.println(classA);
}
}
}
class ClassA
{
private String field;
// getter & setter //
}
class ClassB
{
private List<ClassC> objList;
// getter & setter //
}
clas ClassC
{
private String type;
private String priority;
private double size;
// getters & setters //
public String printStr()
{
return String.format(type, priority, size);
}
}
The following snippet and source file would help you:
https://github.com/matpalm/common-crawl-quick-hacks/blob/master/links_in_metadata/src/com/matpalm/MetaDataToTldLinks.java#L17
private static ParseResult NO_LINKS = new ParseResult(new HashSet<String>(), 0);
private JsonParser parser;
public static void main(String[] s) throws IOException {
BufferedReader reader = new BufferedReader(new FileReader(s[0]));
MetaDataToTldLinks metaDataToTldLinks = new MetaDataToTldLinks();
while (reader.ready()) {
String[] fields = reader.readLine().split("\t");
ParseResult outboundLinks = metaDataToTldLinks.outboundLinks(fields[1]);
System.out.println(tldOf(fields[0]) + " " + outboundLinks.links);
}
}
public MetaDataToTldLinks() {
this.parser = new JsonParser();
}
public ParseResult outboundLinks(String jsonMetaData) {
JsonObject metaData = parser.parse(jsonMetaData.toString()).getAsJsonObject();
if (!"SUCCESS".equals(metaData.get("disposition").getAsString()))
return NO_LINKS;
JsonElement content = metaData.get("content");
if (content == null)
return NO_LINKS;
JsonArray links = content.getAsJsonObject().getAsJsonArray("links");
if (links == null)
return NO_LINKS;
Set<String> outboundLinks = new HashSet<String>();
int numNull = 0;
for (JsonElement linke : links) {
JsonObject link = linke.getAsJsonObject();
if ("a".equals(link.get("type").getAsString())) { // anchor
String tld = tldOf(link.get("href").getAsString());
if (tld == null)
++numNull;
else
outboundLinks.add(tld);
}
}
return new ParseResult(outboundLinks, numNull);
}
public static String tldOf(String url) {
try {
String tld = new URI(url).getHost();
if (tld==null)
return null;
if (tld.startsWith("www."))
tld = tld.substring(4);
tld = tld.trim();
return tld.length()==0 ? null : tld;
}
catch (URISyntaxException e) {
return null;
}
}
public static class ParseResult {
public final Set<String> links;
public final int numNull;
public ParseResult(Set<String> links, int numNull) {
this.links = links;
this.numNull = numNull;
}
}
How about this snippet?:
if (json.isJsonArray()) {
JsonArray array = json.getAsJsonArray();
List<Object> out = Lists.newArrayListWithCapacity(array.size());
for (JsonElement item : array) {
out.add(toRawTypes(item));
}
}

Android JSON Parser "User cannot be resolved to a type"

public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public List readJsonStream(InputStream in) throws IOException {
JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
try {
return readMessagesArray(reader);
} finally {
reader.close();
}
}
public List readMessagesArray(JsonReader reader) throws IOException {
List messages = new ArrayList();
reader.beginArray();
while (reader.hasNext()) {
messages.add(readMessage(reader));
}
reader.endArray();
return messages;
}
public Message readMessage(JsonReader reader) throws IOException {
long id = -1;
String text = null;
User user = null;
List geo = null;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if(name.equals("id")) {
id = reader.nextLong();
} else if (name.equals("text")) {
text = reader.nextString();
} else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
geo = readDoublesArray(reader);
} else if (name.equals("user")) {
user = readUser(reader);
} else {
reader.skipValue();
}
}
reader.endObject();
return new Message(id, text, user, geo);
}
public List readDoublesArray(JsonReader reader)throws IOException {
List doubles = new ArrayList();
reader.beginArray();
return doubles;
}
public User readUser(JsonReader reader) throws IOException {
String username = null;
int followersCount = -1;
reader.beginObject();
while (reader.hasNext()) {
String name = reader.nextName();
if(name.equals("name")) {
username = reader.nextString();
} else if (name.equals("followers_count")) {
followersCount = reader.nextInt();
} else {
reader.skipValue();
}
}
reader.endObject();
return new User(username, followersCount);
}}
I'm using the exact example from http://developer.android.com/reference/android/util/JsonReader.html. However, there is a problem with "User cannot be resolved to a type".
'User' class in the given example is just to show how it may work. You may substitute it with something like this:
public class User{
String name;
int followers_count;
public User(String name, int followers_count){
this.name=name;
this.followers_count=followers_count;
}
}

Categories