I need to map JSON obj to a class and its arrays to ArrayList in Android and it should have all the children data as well. (with nested arraylists too) and i need to convert updated data list again to jsonobject
my json string is
{
"type": "already_planted",
"crops": [
{
"crop_id": 1,
"crop_name": "apple",
"crop_details": [
{
"created_id": "2017-01-17",
"questions": [
{
"plants": "10"
},
{
"planted_by": "A person"
}
]
},
{
"created_id": "2017-01-30",
"questions": [
{
"plants": "15"
},
{
"planted_by": "B person"
}
]
}
]
},
{
"crop_id": 2,
"crop_name": "Cashew",
"crop_details": [
{
"created_id": "2017-01-17",
"questions": [
{
"plants": "11"
},
{
"planted_by": "c person"
}
]
}
]
}
]
}
First of all, you need to create the class that you are going to map JSON inside.
Fortunately, there is a website that can do it for you here
secondly, you can use google Gson library for easy mapping
1. add the dependency.
dependencies {
implementation 'com.google.code.gson:gson:2.8.6'
}
2. from your object to JSON.
MyData data =new MyData() ; //initialize the constructor
Gson gson = new Gson();
String Json = gson.toJson(data ); //see firstly above above
//now you have the json string do whatever.
3. from JSON to object .
String jsonString =doSthToGetJson(); //http request
MyData data =new MyData() ;
Gson gson = new Gson();
data= gson.fromJson(jsonString,MyData.class);
//now you have Pojo do whatever
for more information about gson see this tutorial.
If you use JsonObject, you can define your entity class as this:
public class Entity {
String type;
List<Crops> crops;
}
public class Crops {
long crop_id;
String crop_name;
List<CropDetail> crop_details;
}
public class CropDetail {
String created_id;
List<Question> questions;
}
public class Question {
int plants;
String planted_by;
}
public void convert(String json){
JsonObject jsonObject = new JsonObject(jsonstring);
Entity entity = new Entity();
entity.type = jsonObject.optString("type");
entity.crops = new ArrayList<>();
JsonArray arr = jsonObject.optJSONArray("crops");
for (int i = 0; i < arr.length(); i++) {
JSONObject crops = arr.optJSONObject(i);
Crops cps = new Crops();
cps.crop_id = crops.optLong("crop_id");
cps.crop_name = crops.optString("crop_name");
cps.crop_details = new ArrayList<>();
JsonArray details = crops.optJsonArray("crop_details");
// some other serialize codes
..........
}
}
So you can nested to convert your json string to an entity class.
Here is how I do it without any packages, this do the work for me for small use cases:
My modal class:
package prog.com.quizapp.models;
import org.json.JSONException;
import org.json.JSONObject;
public class Question {
private String question;
private String correct_answer;
private String answer_a;
private String answer_b;
private String answer_c;
private String answer_d;
public Question() {
}
public Question(String question, String answer_a, String answer_b, String answer_c, String answer_d, String correct_answer) {
this.question = question;
this.answer_a = answer_a;
this.answer_b = answer_b;
this.answer_c = answer_c;
this.answer_d = answer_d;
this.correct_answer = correct_answer;
}
public String getQuestion() {
return question;
}
public void setQuestion(String question) {
this.question = question;
}
public String getCorrect_answer() {
return correct_answer;
}
public void setCorrect_answer(String correct_answer) {
this.correct_answer = correct_answer;
}
public String getAnswer_a() {
return answer_a;
}
public void setAnswer_a(String answer_a) {
this.answer_a = answer_a;
}
public String getAnswer_b() {
return answer_b;
}
public void setAnswer_b(String answer_b) {
this.answer_b = answer_b;
}
public String getAnswer_c() {
return answer_c;
}
public void setAnswer_c(String answer_c) {
this.answer_c = answer_c;
}
public String getAnswer_d() {
return answer_d;
}
public void setAnswer_d(String answer_d) {
this.answer_d = answer_d;
}
#Override
public String toString() {
return "Question{" +
"question='" + question + '\'' +
", correct_answer='" + correct_answer + '\'' +
", answer_a='" + answer_a + '\'' +
", answer_b='" + answer_b + '\'' +
", answer_c='" + answer_c + '\'' +
", answer_d='" + answer_d + '\'' +
'}';
}
public static Question fromJson(JSONObject obj) throws JSONException {
return new Question(
obj.getString("question"),
obj.getString("answer_a"),
obj.getString("answer_b"),
obj.getString("answer_c"),
obj.getString("answer_d"),
obj.getString("correct_answer"));
}
}
And I have another class to get the json file from assets directory and mapped JsonObject to my model class Question:
package prog.com.quizapp.utils;
import android.content.Context;
import android.util.Log;
import org.json.JSONObject;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import prog.com.quizapp.models.Question;
public class JsonSqlQueryMapper {
private Context mContext;
public JsonSqlQueryMapper(Context context) {
this.mContext = context;
}
private static final String TAG = "JsonSqlQueryMapper";
public JSONObject loadJSONFromAsset() {
String json = null;
try {
InputStream is = mContext.getAssets().open("quiz_app.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
try {
JSONObject quizObject = new JSONObject(json).getJSONObject("quiz");
return quizObject;
} catch (Exception e) {
Log.d(TAG, "loadJSONFromAsset: " + e.getMessage());
return null;
}
}
public ArrayList<Question> generateInsertQueryForJsonObjects() {
ArrayList<Question> questions = new ArrayList<>();
JSONObject jsonObject = loadJSONFromAsset();
try {
Iterator<String> iter = jsonObject.keys();
while (iter.hasNext()) {
String key = iter.next();
JSONObject value = jsonObject.getJSONObject(key);
Question question = Question.fromJson(value.getJSONObject("question_two"));
questions.add(question);
Log.d(TAG, "generateInsertQueryForJsonObjects: " + question.getAnswer_a());
}
} catch (Exception e) {
e.printStackTrace();
}
return questions;
}
}
And in my MainActivity -> onCreate:
JsonSqlQueryMapper mapper = new JsonSqlQueryMapper(MainActivity.this);
mapper.generateInsertQueryForJsonObjects();
To check that everything working as I want. Here is the json file if you want to check https://github.com/Blasanka/android_quiz_app/blob/sqlite_db_app/app/src/main/assets/quiz_app.json
Regards!
Related
Here is a java class CreateDoc which is sent from One web service that is producer side to another web service which is consumer side as List with content-type:Json
Below is the class representation
class CreateDoc{
DocMetData dMetaData;
DocContent dCont;
}
Class DocMetData {
String docNamel
String docType;
}
Class DocContent {
String data;
}
Once i receive the List as json in the consumer side i am not able to use this as a java Object and the content type is array with json nested inside an array.
Below is the Representation:
[
[
{
"dMetaData":{
"docName":"string",
"docType":"pdf"
},
"dCont":{
"data":"abc"
}
},
{
"dMetaData":{
"docName":"string",
"docType":"pdf"
},
"dCont":{
"data":"def"
}
},
{
"dMetaData":{
"docName":"string",
"docType":"pdf"
},
"dCont":{
"data":"ghk"
}
}
]
]
Question is how to process this and be able to use the data and represent as List.
Here's some sample code that shows how you can use the Jackson ObjectMapper to parse the data. Note that the code assumes the data is stored in a file, you can modify it as needed to suit your needs.
Here's the main class:
package parsing.arrayofarray;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class ArrayOfArray {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
String data = null;
try {
data = new String(Files.readAllBytes(Paths.get("src/main/resources/jsonArrayOfArray.json")));
} catch (IOException e1) {
e1.printStackTrace();
}
List<List<CreateDoc>> results = null;
try {
results = mapper.readValue(data, new TypeReference<List<List<CreateDoc>>>(){});
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(results);
}
}
and here are the supporting classes, first CreateDoc:
package parsing.arrayofarray;
public class CreateDoc {
DocMetData dMetaData;
DocContent dCont;
public DocMetData getdMetaData() {
return dMetaData;
}
public void setdMetaData(DocMetData dMetaData) {
this.dMetaData = dMetaData;
}
public DocContent getdCont() {
return dCont;
}
public void setdCont(DocContent dCont) {
this.dCont = dCont;
}
#Override
public String toString() {
return "CreateDoc [dMetaData=" + dMetaData + ", dCont=" + dCont + "]";
}
}
and DocContent:
package parsing.arrayofarray;
public class DocContent {
#Override
public String toString() {
return "DocContent [data=" + data + "]";
}
String data;
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
and the DocMetData:
package parsing.arrayofarray;
public class DocMetData {
String docName;
String docType;
public String getDocNamel() {
return docName;
}
public void setDocName(String docName) {
this.docName = docName;
}
#Override
public String toString() {
return "DocMetData [docNamel=" + docName + ", docType=" + docType + "]";
}
public String getDocType() {
return docType;
}
public void setDocType(String docType) {
this.docType = docType;
}
}
The output from the println is:
[[CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=abc]], CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=def]], CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=ghk]]]]
You can use JSONArray(org.json) to parse the first list, and parse with GSON the inside list to create a List of CreatDoc. You can use only GSON to parse the first array too
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
public class Deserializer {
public static void main(String[] args) {
JSONArray jsonArray = new JSONArray(
"[[{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"abc\"}},{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"def\"}},{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"ghk\"}}]]");
JSONArray docsArray = jsonArray.getJSONArray(0);
List<CreateDoc> docsList = new Gson().fromJson(docsArray.toString(),
new TypeToken<ArrayList<CreateDoc>>() {}.getType());
docsList.forEach(System.out::println);
}
public static class CreateDoc {
DocMetData dMetaData;
DocContent dCont;
#Override
public String toString() {
return this.dMetaData.toString() + " " + this.dCont.toString();
}
}
public static class DocMetData {
String docName;
String docType;
#Override
public String toString() {
return "name: " + this.docName + " type: " + this.docType;
}
}
public static class DocContent {
String data;
#Override
public String toString() {
return "data: " + this.data;
}
}
}
You can use GSON to parse the message into a JSONArray with JSONObjects. Then create a parser for each class to convert the fields from the JSONObject into Java objects. Similar question is anwered here.
I think the problem is you are trying to map json to CreateDoc instead of CreateDoc List. If you are using spring boot to manage rest layer in your application use #Requestbody List CreateDoc in the method to convert your json. This will use Jackson converter internally. Otherwise you can use Jackson converter jar to convert your json to objects.
I want to know the best way to iterate this ArrayList, this ArrayList comes from a Response from an API, this is the ArrayList:
The problem is that i dont know how to get the "id" and the "value" from the loop,
i know the arraylist size but i dont have any idea how to print the "Keys" and "Values" from this Array
for(int i=1; i <= contacts.size(); i++) {
//Example System.out.print(contacts[i]->id);
//Example System.out.print(contacts[i]->contact_name) ;
//Example System.out.print(contacts[i]->numbers);
//Example System.out.print(contacts[i]->emails);
//I want to print id and value
//
}
In onResponse i call this fucntion for example:
ServerResponse resp = response.body();
functionExample((ArrayList) resp.getResponse());
The functionExample have an ArrayList as parameter.
This is my result from my resp.getResponse():
This is my json from the API:
{
"result": "success",
"message": "Lista de Contactos",
"response": [
{
"id": 1,
"contact_name": "EDIFICADORA JUANA",
"numbers": "{24602254,55655545}",
"emails": "{oipoa#gmaio.com,rst008#guan.com}"
},
{
"id": 2,
"contact_name": "LA MEJOR",
"numbers": "{25445877,25845877}",
"emails": "{AMEJOR#GMAIL.COM}"
}
]
}
I appreciate any help.
public void FunctionExample(ArrayList contacts) {
for(int i=0; i < contacts.size(); i++) {
LinkedTreeMap<String, Object> map = (LinkedTreeMap<String, Object>) contacts.get(i);
map.containsKey("id");
String id = (String) map.get("id");
map.containsKey("contact_name");
String contact_name = (String) map.get("contact_name");
map.containsKey("numbers");
String numbers = (String) map.get("numbers");
numbers.replace("{","").replace("}","");
map.containsKey("emails");
String emails = (String) map.get("emails");
emails.replace("{","").replace("}","");
Snackbar.make(getView(), id, Snackbar.LENGTH_LONG).show();
Snackbar.make(getView(), contact_name, Snackbar.LENGTH_LONG).show();
Snackbar.make(getView(), numbers, Snackbar.LENGTH_LONG).show();
Snackbar.make(getView(), emails, Snackbar.LENGTH_LONG).show();
}
}
Try this..It will give arrayList of id's
JSONObject object=new JSONObject(response);
JSONArray array= null;
try {
array = object.getJSONArray("response");
} catch (JSONException e) {
e.printStackTrace();
}
ArrayList<String> idArray=new ArrayList<>();
for(int i=0;i< array.length();i++)
{
idArray.add(getJSONObject(i).getString("id"));
}
Try this way if you are using ArrayList<TreeMap<String, String>> contacts;
for(TreeMap<String,String> contact : contacts){
String id = contact.getValue("id");
}
I would strongly encourage you to use e.g. Jackson to map your JSON response to a proper object. Consider following example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class JacksonTest {
private static final String JSON = "{\n" +
"\"result\": \"success\",\n" +
"\"message\": \"Lista de Contactos\",\n" +
"\"response\": [\n" +
" {\n" +
" \"id\": 1,\n" +
" \"contact_name\": \"EDIFICADORA JUANA\",\n" +
" \"numbers\": \"{24602254,55655545}\",\n" +
" \"emails\": \"{oipoa#gmaio.com,rst008#guan.com}\"\n" +
" },\n" +
" {\n" +
" \"id\": 2,\n" +
" \"contact_name\": \"LA MEJOR\",\n" +
" \"numbers\": \"{25445877,25845877}\",\n" +
" \"emails\": \"{AMEJOR#GMAIL.COM}\"\n" +
" }\n" +
" ]\n" +
"}";
#Test
public void testParsingJSONStringWithObjectMapper() throws IOException {
//given:
final ObjectMapper objectMapper = new ObjectMapper();
//when:
final Response response = objectMapper.readValue(JSON, Response.class);
//then:
assert response.getMessage().equals("Lista de Contactos");
//and:
assert response.getResult().equals("success");
//and:
assert response.getResponse().get(0).getId().equals(1);
//and:
assert response.getResponse().get(0).getContactName().equals("EDIFICADORA JUANA");
//and:
assert response.getResponse().get(0).getEmails().equals(Arrays.asList("oipoa#gmaio.com", "rst008#guan.com"));
//and:
assert response.getResponse().get(0).getNumbers().equals(Arrays.asList(24602254, 55655545));
}
static class Response {
private String result;
private String message;
private List<Data> response = new ArrayList<>();
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public List<Data> getResponse() {
return response;
}
public void setResponse(List<Data> response) {
this.response = response;
}
}
static class Data {
private String id;
#JsonProperty("contact_name")
private String contactName;
private String numbers;
private String emails;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public List<Integer> getNumbers() {
return Stream.of(numbers.replaceAll("\\{", "")
.replaceAll("}", "")
.split(","))
.map(Integer::valueOf)
.collect(Collectors.toList());
}
public void setNumbers(String numbers) {
this.numbers = numbers;
}
public List<String> getEmails() {
return Arrays.asList(emails.replaceAll("\\{", "")
.replaceAll("}", "")
.split(","));
}
public void setEmails(String emails) {
this.emails = emails;
}
}
}
In this example I used same JSON response you receive and jackson-core library (http://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core/2.8.9) for mapping String to a POJOs (instead of String you can use InputStream, byte[] etc.). There are two POJOs: Response and Data. Response aggregates a list of Data objects. Additionally, Data's getEmails() and getNumbers() methods parse your input String to a list of expected objects. For example if you call setNumbers("{24602254,55655545}") then getNumbers() will return a list of Integers (you can use any numeric type instead) like [24602254, 55655545].
Other suggestions are also valid, e.g. iterating over collection of TreeMaps or JSONObjects. In this example we limit our focus to deal with Java objects with specific types instead of dealing with primitives like Object class for example.
The final solution also depends on your runtime environment. In this case you will have to add jackson-core dependency - it makes more sense if your project already uses Jackson for other reasons.
If you are using Set< Map< String, String>> set;
set.stream().forEach(map -> {
System.out.print("Id:" + map.get("id") + "ContactName:" + map.get("contact_name"));
});
Try this loop to extract every value from ArrayList of yours
List<LinkedTreeMap> list = new ArrayList<LinkedTreeMap>(); //assign result from API to list
for(LinkedTreeMap<String,String> contact : list){
for(String id : contact.keySet()){
if(id.equalsIgnoreCase("id")){
System.out.println("ID: "+ contact.get(id));
}else if(id.equalsIgnoreCase("contact_name")){
System.out.println("Contact Name: "+ contact.get(id));
}else{ //if it is list of numbers or e-mails
String result = contact.get(id);
result = result.replaceAll("{|}", ""); //removing { }
String[] array = result.split(",");
System.out.println(id+": "); // this will be either numbers or e-mails
//now iterating to get each value
for(String s : array){
System.out.println(s);
}
}
}
}
I'm trying to make a test where I get some documents based on the id of the batch they belong to. More specifically, I want to check that a specific batchPublicId is in the response body. I am using okhttp for the test.
This a shorter version of the json:
{
"_embedded": {
"invoices": [
{
"type": "INVOICE",
"publicId": "27bc8426-17cf-4fe5-9278-64108ae05e4b",
"deliveryStatus": null,
"processingStatus": "INITIATED",
"batchPublicId": "0000000000000000000000001"
}
]
}
}
I'm new to json and this is how far I got with the problem:
String invoicesJsonData = response.body().string();
JSONObject invoicesJsonObject = new JSONObject(invoicesJsonData);
Assert.assertTrue(invoicesJsonObject.getJSONObject("_embedded") !=null && invoicesJsonObject.getJSONObject("_embedded").has("invoices"));
I would like to verify that batchPublicId has the value mentioned in the json. Is there a way to do this? Thank you.
String invoicesJsonData = response.body().string();
JSONObject invoicesJsonObject = new JSONObject(invoicesJsonData);
JSONObject invoicesJsonObject1 = invoicesJsonObject.getJSONObject("_embedded");
JSONArray f2=invoicesJsonObject1.getJSONArray("invoices");
for(int i=0;i<f2.length();i++){
JSONObject obj=f2.getJSONObject(i);
if(obj.get("batchPublicId")!=null){
System.out.println(obj.get("batchPublicId"));
}
You can do something like this,Which worked out for me sometimes back.
String invoicesJsonData = response.body().string();
JSONObject invoicesJsonObject = new JSONObject(invoicesJsonData);
JSONObject invoicesJsonObject = json.getJSONObject("invoicesJsonObject");
String batchPublicId = invoicesJsonObject.getString("batchPublicId");
System.out.println( "batchPublicId: " + batchPublicId );
if(batchPublicId !=null){
// do something
}
Not sure about the syntax.Giving you a hint.
you can check any keys is there in json object or not like below :
if(jsonObject1.has("batchPublicId")){
String batchPublicId = jsonObject1.optString("batchPublicId");
Log.i(getClass().getSimpleName(), "batchPublicId=" + batchPublicId);}
has method is used to find any key is there in jsonobject or not.
In my opinion, a better approach for this would be to create a POJO from this JSON string, and extract the information you need using simply the getters
For example:
Wrapper class:
#JsonIgnoreProperties(ignoreUnknown = true)
#JsonRootName(value = "_embedded")
public class Embeded {
#JsonProperty("invoices")
private List<Invoice> invoices;
public Embeded() {}
public List<Invoice> getInvoices() {
return invoices;
}
public void setInvoices(List<Invoice> invoices) {
this.invoices = invoices;
}
}
Invoice class:
#JsonIgnoreProperties(ignoreUnknown = true)
public class Invoice {
#JsonProperty("type")
private String type;
#JsonProperty("publicId")
private String publicId;
#JsonProperty("deliveryStatus")
private String deliveryStatus;
#JsonProperty("processingStatus")
private String processingStatus;
#JsonProperty("batchPublicId")
private String batchPublicId;
public Invoice() {}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPublicId() {
return publicId;
}
public void setPublicId(String publicId) {
this.publicId = publicId;
}
public String getDeliveryStatus() {
return deliveryStatus;
}
public void setDeliveryStatus(String deliveryStatus) {
this.deliveryStatus = deliveryStatus;
}
public String getProcessingStatus() {
return processingStatus;
}
public void setProcessingStatus(String processingStatus) {
this.processingStatus = processingStatus;
}
public String getBatchPublicId() {
return batchPublicId;
}
public void setBatchPublicId(String batchPublicId) {
this.batchPublicId = batchPublicId;
}
}
Test:
public void json_test() throws JsonParseException, JsonMappingException, IOException {
String json = "{"
+ "\"_embedded\": {"
+ "\"invoices\": ["
+ "{"
+ "\"type\": \"INVOICE\","
+ "\"publicId\": \"27bc8426-17cf-4fe5-9278-64108ae05e4b\","
+ "\"deliveryStatus\": null,"
+ "\"processingStatus\": \"INITIATED\","
+ "\"batchPublicId\": \"0000000000000000000000001\""
+ "}"
+ "]"
+ "}"
+ "}";
ObjectMapper mapper = new ObjectMapper();
mapper.configure(Feature.UNWRAP_ROOT_VALUE, true);
List<Invoice> invoices = mapper.readValue(json, Embeded.class).getInvoices();
Assert.assertTrue(StringUtils.equals(invoices.get(0).getBatchPublicId(), "0000000000000000000000001"));
}
If I understand your right, you just need to call:
Assert.assertTrue(invoicesJsonObject.getString("batchPublicId").equals("0000000000000000000000001"));"
If you want to create a test for JSON Validation, you can use the JSONAssert.
JSONAsset give the method assertEquals, that compare two json structures, strict identic or not.
final String expected_result = YOUR_EXPECTED_RESULT;
JSONAssert.assertEquals(YOUR_EXPECTED_JSON_RESULT, RESULT_FROM_RESPONSE_BODY, false);
The last boolean parameter defines if you want an strict comparation or just compare if your expected result is in result from response.
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));
}
}
[{"user_id":"5633795","username":"_Vorago_","count300":"203483","count100":"16021","count50":"1517","playcount":"1634","ranked_score":"179618425","total_score":"1394180836","pp_rank":"34054","level":"59.6052","pp_raw":"1723.43","accuracy":"96.77945709228516","count_rank_ss":"1","count_rank_s":"19","count_rank_a":"17","country":"US","events":[]}]
I'm trying to convert the JSON above with GSON but am running into errors.
package com.grapefruitcode.osu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import com.google.gson.Gson;
public class Main {
static String ApiKey = "";
public static void main(String[]Args) throws Exception{
String json = readUrl("");
System.out.println(json);
Gson gson = new Gson();
User user = gson.fromJson(json, User.class);
System.out.println();
}
private static String readUrl(String urlString) throws Exception {
BufferedReader reader = null;
try {
URL url = new URL(urlString);
reader = new BufferedReader(new InputStreamReader(url.openStream()));
StringBuffer buffer = new StringBuffer();
int read;
char[] chars = new char[1024];
while ((read = reader.read(chars)) != -1)
buffer.append(chars, 0, read);
return buffer.toString();
} finally {
if (reader != null)
reader.close();
}
}
}
The url and api key are left blank for security reasons, the variables are filled when I run the code and the json is converted to a string properly. I've tested it already. If somebody could tell me what is causing the error that would be wonderful.
package com.grapefruitcode.osu;
public class User {
String user_id = "";
String username = "";
String count300 = "";
String count100= "";
}
In JSON
[ ... ] represents array
{ ... } represents object,
so [ {...} ] is array containing one object. Try using
Gson gson = new Gson();
User[] users = gson.fromJson(json, User[].class);
System.out.println(Arrays.toString(users));
//or since we know which object from array we want to print
System.out.println(users[0]);
Using RetroFit 2 Solution
interface APIInterface {
#POST("GetDataController/GetData")
Call<GeoEvent> getGeofanceRecord(#Body GeoEvent geoEvent);
}
APIInterface apiInterface; // Declare Globally
apiInterface = APIClient.getClient().create(APIInterface.class);
final GeoEvent geoEvent = new GeoEvent(userId);
Call<GeoEvent> call = apiInterface.getGeofanceRecord(geoEvent);
call.enqueue(new Callback<GeoEvent>() {
#Override
public void onResponse(Call<GeoEvent> call, Response<GeoEvent> response) {
GeoEvent geoEvent1 = response.body();
// Log.e("keshav","Location -> " +geoEvent1.responseMessage);
List<GeoEvent.GeoEvents> geoEventsList = geoEvent1.Table; // Array Naame
List<GeoEvent.GeoEvents> geoEventsArrayList = new ArrayList<GeoEvent.GeoEvents>();
geoEventsArrayList.addAll(geoEventsList);
for (GeoEvent.GeoEvents geoEvents : geoEventsList) {
Log.e("keshav", "Location -> " + geoEvents.Location);
Log.e("keshav", "DateTime -> " + geoEvents.DateTime);
}
if (geoEventsArrayList != null) {
adapter.clear();
adapter.addAll(geoEventsArrayList);
adapter.notifyDataSetChanged();
}
}
#Override
public void onFailure(Call<GeoEvent> call, Throwable t) {
call.cancel();
}
});
Your Pojo Class Like This
package pojos;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
public class GeoEvent {
public String userId;
public GeoEvent(String userId){
this.userId= userId;
}
public List<GeoEvents> Table = new ArrayList<>();
public class GeoEvents {
#SerializedName("Location")
public String Location;
#SerializedName("DateTime")
public String DateTime;
public String getLocation() {
return Location;
}
public void setLocation(String location) {
Location = location;
}
public String getDateTime() {
return DateTime;
}
public void setDateTime(String dateTime) {
DateTime = dateTime;
}
}
}