I'm using Android Studio and I want to make a listview, which contains values that are received by JSON.
protected Void doInBackground(Void... voids) {
HttpHandler Handler = new HttpHandler();
String JSONString = Handler.makeServiceCall(JSONUrl);
Log.e(TAG, "Response:" + JSONString);
if(JSONString != null){
try {
JSONObject CountriesJSONObject = new JSONObject(JSONString);
JSONArray Countries = CountriesJSONObject.getJSONArray("countries");
for (int i = 1; i < Countries.length(); i++) {
JSONObject Country = Countries.getJSONObject(i);
//Details
String CountryID = Country.getString("id");
String CountryName = Country.getString("name");
String CountryImage = Country.getString("image");
//Hashmap
HashMap<String, String> TempCountry = new HashMap<>();
//Details to Hashmap
TempCountry.put("id", CountryID);
TempCountry.put("name", CountryName);
TempCountry.put("image", CountryImage);
//Hashmap to Countrylist
CountryList.add(TempCountry);
}
} catch (final JSONException e){
Log.e(TAG,e.getMessage());
ProgressDialog.setMessage("Error loading Data!");
}
}
return null;
}
This is the code for getting the JSON values, and i'm receiving an error
"No value for id"
What am I doing wrong?
You still have the "country" key to unwrap. Try like this:
for (int i = 1; i < Countries.length(); i++) {
JSONObject Country = Countries.getJSONObject(i).getJSONObject("country");
//Details
String CountryID = Country.getString("id");
String CountryName = Country.getString("name");
String CountryImage = Country.getString("image");
//Hashmap
HashMap<String, String> TempCountry = new HashMap<>();
//Details to Hashmap
TempCountry.put("id", CountryID);
TempCountry.put("name", CountryName);
TempCountry.put("image", CountryImage);
//Hashmap to Countrylist
CountryList.add(TempCountry);
}
First step is to create a new Java class model for the JSON - you can just copy and paste this.
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
public class Countries {
public class CountriesList implements Serializable {
private Country[] countries;
public Country[] getCountries() {
return countries;
}
public void setCountries(Country[] countries) {
this.countries = countries;
}
public ArrayList<Country> getCountriesAsList() {
if(countries == null || countries.length == 0) {
return new ArrayList<>();
} else {
return (ArrayList<Country>) Arrays.asList(countries);
}
}
}
public class Country implements Serializable {
private String id;
private String name;
private String image;
public Country() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
}
}
Now, it's simply converting the JSON into Java object like this. You can use that ArrayList for adapter or however you like.
protected Void doInBackground(Void... voids) {
HttpHandler Handler = new HttpHandler();
String jsonString = Handler.makeServiceCall(JSONUrl);
Countries.CountriesList countries = new Gson().fromJson(jsonString, Countries.CountriesList.class);
// this is the full list of all your countries form json
ArrayList<Countries.Country> countryList = countries.getCountriesAsList();
}
Note: you will need the Gson library to use the solution I showed above. I use that to convert JSON into Java object.
compile 'com.google.code.gson:gson:2.8.0'
Related
Real title: How do I convert json to custom object using gson(custom object contains ArrayLists and HashMap)?
Problem:
I added an HashMap to my custom object and since then when im trying to convert JSON to my custom object I get this error:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 59 path $[0].currentLesson.students.
What do I need to change? ask for any other info you might need from me and I shall give it to you. Thank you!
Code:
private void initializeDatabase() {
ArrayList<Group> groups = null;
SharedPreferences sharedPreferences = getSharedPreferences(Database.SHARED_PREFERENCES_STRING, MODE_PRIVATE);
Gson gson = new Gson();
String groupsJason = sharedPreferences.getString(Database.GROUPS_STRING, null);
Type typeGroup = new TypeToken<ArrayList<Group>>(){}.getType();
groups = gson.fromJson(groupsJason, typeGroup);
if(groups == null){
groups = new ArrayList<>();
}
Database.setGroups(groups);
}
public class Group {
private String groupName;
private ArrayList<Student> students;
private ArrayList<Lesson> lessons;
private Lesson currentLesson;
public Group(String groupName) {
this.groupName = groupName;
students = new ArrayList<>();
lessons = new ArrayList<>();
}
public Group(String groupName, ArrayList<Student> students) {
this.groupName = groupName;
this.students = students;
lessons = new ArrayList<>();
}
public void setCurrentLesson(String currentLesson) {
this.currentLesson = new Lesson(currentLesson, students);
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public ArrayList<Student> getStudents() {
return students;
}
public int getGroupSize() {
return students.size();
}
public Boolean getArrivedToLesson(Student student){
return currentLesson.getArrivedToLesson(student);
}
public Lesson getCurrentLesson() {
return currentLesson;
}
public void saveLesson() {
lessons.add(currentLesson);
}
}
public class Lesson {
private String lessonDate;
private HashMap<Student, Boolean> students;
public Lesson(String lessonDate, ArrayList<Student> students) {
this.lessonDate = lessonDate;
this.students = new HashMap<>();
for (Student student : students) {
this.students.put(student, false);
}
}
public String getLessonDate() {
return lessonDate;
}
public void arrivedToLesson(Student student) {
student.arrivedToLesson();
students.put(student, true);
}
public void didntArriveToLesson(Student student) {
student.didntArriveToLesson();
students.put(student, false);
}
public Boolean getArrivedToLesson(Student student) {
return students.get(student);
}
}
private void saveData(){
group.saveLesson();
SharedPreferences sharedPreferences = getSharedPreferences(Database.SHARED_PREFERENCES_STRING, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPreferences.edit();
Gson gson = new Gson();
String groupsJason = gson.toJson(Database.getGroups());
editor.putString(Database.GROUPS_STRING, groupsJason);
editor.apply();
Toast.makeText(this, String.format(getResources().getString(R.string.saved_attendance), lessonDate), Toast.LENGTH_SHORT).show();
onButtonBackClick();
}
I've managed to solve the problem. The problem was that my map - I changed it to HashMap<String, Object>. The string represents my custom object's main attribute - in my case it's name, the object is a boolean and I casts it when needed.
I can not convert Java object to JSON object this is my main java object :
I do this:
public class LoginDao {
String company;
String user;
String secure_password;
String secure_device_id;
app_info app_info;
}
jsonObject.put("company", company);
jsonObject.put("user", user);
jsonObject.put("os", os);
jsonObject.put("ver", ver);
jsonObject.put("lang", lang);
but on output I do not have this :
{
"company":"",
"user":"test",
"secure_password":"",
"secure_device_id":"",
"app_info":
{
"os":"soapui",
"ver":1,
"lang":"pl"
}
}
You can do this in many more way. Here are given bellow:
Using Google Gson:
Maven dependency:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.0</version>
</dependency>
Java code:
LoginDao loginData;
// Here loginData is the object. ...
Gson gson = new Gson();
String json = gson.toJson(loginData);
Using Jackson:
Gradle Dependency:
compile 'com.fasterxml.jackson.core:jackson-databind:2.5.3'
Java code
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
String json = ow.writeValueAsString(loginData);
If you need above output, try this:
JSONObject obj = new JSONObject();
obj.put("company", company);
obj.put("user", user);
obj.put("secure_password", secure_password);
obj.put("secure_device_id", secure_device_id);
JSONObject anothetObj = new JSONObject();
anothetObj.put("os", os);
anothetObj.put("ver", ver);
anothetObj.put("lang", lang);
obj.put("app_info", anothetObj);
You can create two DAO Classes,
public class LoginDAO {
private String company;
private String user;
private String secure_password;
private String secure_device_id;
// Getter Methods
public String getCompany() {
return company;
}
public String getUser() {
return user;
}
public String getSecure_password() {
return secure_password;
}
public String getSecure_device_id() {
return secure_device_id;
}
// Setter Methods
public void setCompany( String company ) {
this.company = company;
}
public void setUser( String user ) {
this.user = user;
}
public void setSecure_password( String secure_password ) {
this.secure_password = secure_password;
}
public void setSecure_device_id( String secure_device_id ) {
this.secure_device_id = secure_device_id;
}
}
public class App_info {
private String os;
private float ver;
private String lang;
// Getter Methods
public String getOs() {
return os;
}
public float getVer() {
return ver;
}
public String getLang() {
return lang;
}
// Setter Methods
public void setOs( String os ) {
this.os = os;
}
public void setVer( float ver ) {
this.ver = ver;
}
public void setLang( String lang ) {
this.lang = lang;
}
}
An then you can do this,
LoginDAO login = new LoginDAO();
App_info app = new App_info();
JSONObject jo = new JSONObject();
jo.put("company", login.getCompany());
jo.put("user", login.getUser());
jo.put("secure_password", login.getSecure_password());
jo.put("secure_device_id", login.getSecure_device_id());
Map m = new LinkedHashMap(3);
m.put("os", app.getOs());
m.put("ver", app.getVer());
m.put("lang", app.getLang());
jo.put("app_info", m);
System.out.println(jo.toString);
If not you can simply do this,
JSONObject jo = new JSONObject(
"{ \"company\":\"\", \"user\":\"test\", \"secure_password\":\"\", \"secure_device_id\":\"\", \"app_info\": { \"os\":\"soapui\", \"ver\":1, \"lang\":\"pl\" } }"
);
I am calling Restful service using below code :(Java.net implementation )
StringBuilder responseStrBuilder = new StringBuilder();
try
{
URL url = new URL(restUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(httpRequestMethod);
conn.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
conn.setRequestProperty("Content-Type", "application/json");
if (requestHeaders != null)
{
for (Map.Entry<String, String> entry : requestHeaders.entrySet())
{
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
}
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
os.write(urlParameters.getBytes());
os.flush();
os.close();
if (conn.getResponseCode() != 200) {//do something}
br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
while ((output = br.readLine()) != null)
responseStrBuilder.append(output);
Approach 1:
I have below string(JSON String) as my Restful service response , how can I convert it to Java object. Since same(Itm) object is repeated multiple times if I use org.codehaus.jettison.json.JSONObject myObject = new org.codehaus.jettison.json.JSONObject(responseStrBuilder.toString());
It only reads first Itm Object and does not bring list of all item object.
JSON String output from service :
{"Response":{"RID":"04'34'",
"Itm":{"id":{"ab":"1","cd":"12"},"qw":"JK","name":"abcd "},
"Itm":{"id":{"ab":"2","cd":"34},"qw":"JK","name":"asdf "},
"Itm":{"id":{"ab":"3","cd":"12"},"qw":"JK","name":"fghj "}
}}
Approach 2:
I also tried below snippet with correct Java object with setters and getters
ObjectMapper objectMapper = new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
MyJavaReponseObject javaObj = mapper.readValue(json, MyJavaReponseObject.class);
This approach also reads only one object of Itm and not all the object as its not coming in array format in JSON string. Is there any better way of getting all the object(Itm) mapped to single List of Object in java pojo ?
You can use the List class in your response object, if you should parse that json string itself.
I have a ReponseJSON class with json objects, one Response and three Itms
static class ReponseJSON {
private Response Response;
#JsonProperty("Response")
public Response getResponse() {
return Response;
}
public void setResponse(Response Response) {
this.Response = Response;
}
static class Response {
private String rid;
private Itm Itm;
private List<Itm> listItm = new ArrayList<Itm>();
public Itm getItm() {
return Itm;
}
#JsonProperty("Itm")
public void setItm(Itm Itm) {
this.Itm = Itm;
listItm.add(Itm);
}
public String getRID() {
return rid;
}
public List<Itm> getItms() {
return listItm;
}
#JsonProperty("RID")
public void setRID(String rid) {
this.rid = rid;
}
static class Itm {
private Id id;
private String qw, name;
public String getQw() {
return qw;
}
public void setQw(String qw) {
this.qw = qw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Id getId() {
return id;
}
public void setId(Id id) {
this.id = id;
}
static class Id {
private String ab, cd;
public String getCd() {
return cd;
}
public void setCd(String cd) {
this.cd = cd;
}
public String getAb() {
return ab;
}
public void setAb(String ab) {
this.ab = ab;
}
}
}
}
}
In a Response class, I have a list class and save a Itm object whenever object mapper call this class.
static class Response {
... skip ..
private List<Itm> listItm = new ArrayList<Itm>();
... skip ..
#JsonProperty("Itm")
public void setItm(Itm Itm) {
this.Itm = Itm;
listItm.add(Itm);
}
}
Check the full source code as follows.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class JacksonParserTest {
static class ReponseJSON {
private Response Response;
#JsonProperty("Response")
public Response getResponse() {
return Response;
}
public void setResponse(Response Response) {
this.Response = Response;
}
static class Response {
private String rid;
private Itm Itm;
private List<Itm> listItm = new ArrayList<Itm>();
public Itm getItm() {
return Itm;
}
#JsonProperty("Itm")
public void setItm(Itm Itm) {
this.Itm = Itm;
listItm.add(Itm);
}
public String getRID() {
return rid;
}
public List<Itm> getItms() {
return listItm;
}
#JsonProperty("RID")
public void setRID(String rid) {
this.rid = rid;
}
static class Itm {
private Id id;
private String qw, name;
public String getQw() {
return qw;
}
public void setQw(String qw) {
this.qw = qw;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Id getId() {
return id;
}
public void setId(Id id) {
this.id = id;
}
static class Id {
private String ab, cd;
public String getCd() {
return cd;
}
public void setCd(String cd) {
this.cd = cd;
}
public String getAb() {
return ab;
}
public void setAb(String ab) {
this.ab = ab;
}
}
}
}
}
public static void main(String[] args) {
String responseJson =
"{\"Response\":{\"RID\":\"04'34'\","
+ "\"Itm\":{\"id\":{\"ab\":\"1\",\"cd\":\"12\"},\"qw\":\"JK\",\"name\":\"abcd\"}"
+ ",\"Itm\":{\"id\":{\"ab\":\"2\",\"cd\":\"34\"},\"qw\":\"JK\",\"name\":\"asdf\"}"
+ ",\"Itm\":{\"id\":{\"ab\":\"3\",\"cd\":\"12\"},\"qw\":\"JK\",\"name\":\"fghj\"}"
+ "}} ";
ObjectMapper mapper = new ObjectMapper();
ReponseJSON responseObj = null;
try {
responseObj = mapper.readValue(responseJson, ReponseJSON.class);
ReponseJSON.Response response = responseObj.getResponse();
for(int i = 0; i < response.getItms().size(); i++)
{
ReponseJSON.Response.Itm item = response.getItms().get(i);
System.out.println(item.getId().getAb());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The version of my jackson mapper is 2.9.1.
You check the main method of the source, because the JSON string you prepared is invalid as coddemonkey mentioned.
Have a good day.
Make your json response looks something similar to this
{"Response":{"RID":"04'34'",
"Itms":[{"id":{"ab":"1","cd":"12"},"qw":"JK","name":"abcd "},
{"id":{"ab":"2","cd":"34"},"qw":"JK","name":"asdf "},
{"id":{"ab":"3","cd":"12"},"qw":"JK","name":"fghj "}]
}}
then, use org.json jar to parse the string to jsonObject
JSONObject jsonObject=new JSONObject(responseString);
This is one type of solution, if you can't change the response as mentioned above then you have to manually parse the string(using java bean) there is no other option available.
I have JsonObject
JSON Object
I have method which return JSONArray. I want to pass first field and get only data array. And then cast it to my Array List. I will really appriciated for any suggestion from you.
void getUsersBeacons(){
type = new TypeToken<List<Beacon>>(){}.getType();
JSONArray myReq = new JSONArray(Request.Method.GET, Url + testId + Url2, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try{
JSONArray buffArray = response.getJSONArray(2);
JSONArray bufJsonArray = response.getJSONArray(1);
beaconsList = converter.fromJson(bufJsonArray.toString(), type);
}catch (Exception e){
e.printStackTrace();
}
}
});
VolleySingleton.getInstance(getActivity().getApplicationContext()).addToRequestQueue(myReq);
}
Beacon class:
public class Beacon {
private Object idBeacon;
private String friendlyName;
private String imageUrl;
public Beacon(Object idBeacon, String friendlyName, String imageUrl) {
this.idBeacon = idBeacon;
this.friendlyName = friendlyName;
this.imageUrl = imageUrl;
}
public Object getIdBeacon() {
return idBeacon;
}
public void setIdBeacon(Object idBeacon) {
this.idBeacon = idBeacon;
}
public String getFriendlyName() {
return friendlyName;
}
public void setFriendlyName(String friendlyName) {
this.friendlyName = friendlyName;
}
public String getImageUrl() {
return imageUrl;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
}
If I understand correctly, you better pass in JSONArray instead of string and parse it's contents, like this:
public static List<Beacon> fromJson(JSONArray array)
{
ArrayList<Beacon> res = new ArrayList<>();
for (int i = 0; i < array.length(); ++i)
{
JSONObject beacon = array.getJSONObject(i);
res.add(new Beacon(beacon.getInt("beaconId"), beacon.getString("name"), beacon.getString("imageUrl"))));
}
return res;
}
UPD: in response to your comment, you must use Response.Listener<JSONObject> instead of Response.Listener<JSONArray>, and then do this:
public void onResponse(JSONObject response)
{
JSONArray array = response.getJSONArray("data");
converter.fromJson(array);
}
I want to parse this following dynamic JSON
{
"lowfares": {
"2017-07-30": {
"price": "1208.00",
"tax": "946.00",
"totalprice": "2154.00"
},
"2017-07-31": {
"price": "1208.00",
"tax": "946.00",
"totalprice": "2154.00"
}
}
}
This is my class contains price, tax, and totalprice
public class PriceModel {
#SerializedName("price")
private String price;
#SerializedName("tax")
private String tax;
#SerializedName("totalprice")
private String totalprice;
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getTax() {
return tax;
}
public void setTax(String tax) {
this.tax = tax;
}
public String getTotalPrice() {
return totalprice;
}
public void setTotalPrice(String totalPrice) {
this.totalprice = totalPrice;
}
}
This is my class to contain hashmap to store the response
public class ResponseModel {
#SerializedName("prices")
#Expose
private Map<String,PriceModel> priceModelMap;
public Map<String, PriceModel> getPriceModelMap() {
return priceModelMap;
}
public void setPriceModelMap(Map<String, PriceModel> priceModelMap) {
this.priceModelMap = priceModelMap;
}
}
in API interface, this is how I get the response
#GET("getprice/{start}/{end}/1/2")
Call<ResponseModel> getResponse(#Path("start") String start, #Path("end") String end);
and in MainActivity, I execute like this
Call call = apiInterface.getResponse("CRB","IMY");
call.enqueue(new Callback() {
#Override
public void onResponse(Call call, Response response) {
Log.d("TAG",response.code()+" ");
Log.d("TAG","REsponse: "+response.body());
ResponseModel responseModel = (ResponseModel) response.body();
Log.d("TAG","REsponse: "+responseModel.getPriceModelMap());
Map<String, PriceModel> priceModelMap = responseModel.getPriceModelMap();
for (Map.Entry<String,PriceModel> entry : priceModelMap.entrySet()){
String key = entry.getKey();
PriceModel priceModel = entry.getValue();
System.out.println("KEY: "+key+" value: "+priceModel.getPrice());
}
}
#Override
public void onFailure(Call call, Throwable t) {
call.cancel();
}
});
I want to get price, tax, totalprice. But using my method, I tried getPrice method give null value.
How can I get the date and the values from that JSON? Thanks
So in the end I decided not to use retrofit as I couldnt find a way to parse the json as I wanted.
What I did to parse that dynamic json response
private HashMap<String,JSONObject> getLowfaresJson(JSONObject data){
HashMap<String,JSONObject> result = new HashMap<>();
try {
JSONObject lowfareJson = data.getJSONObject("lowfares");
Iterator keys = lowfareJson.keys();
while ((keys.hasNext())){
//Getting dynamic key from json
String currentDynamicKey = (String) keys.next();
//Getting dynamic value from json
JSONObject currentDynamicValue = lowfareJson.getJSONObject(currentDynamicKey);
result.put(currentDynamicKey,currentDynamicValue);
}
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
that method will return hashmap from dynamic json response. Hope this will help someone
You can simply gson.
Import in your project.
dependencies {
compile 'com.google.code.gson:gson:2.8.1'
}
public class TestModel {
private String name;
private int age;
private String position;
}
Use:
String strModel ="Staff{name='john', age=35, position='Developer'}"
Gson gson = new Gson();
TestModel testModel = gson.fromJson(strModel, TestModel .class);
Read more:Samples