This is the JSON array:
{
"server_response": [{
"Total": "135",
"Paid": "105",
"Rest": "30"
}]
}
So, how can i get the object names? I want to put them in separate TextView.
Thanks.
Put this out side everything. I mean outside onCreate() and all.
private <T> Iterable<T> iterate(final Iterator<T> i){
return new Iterable<T>() {
#Override
public Iterator<T> iterator() {
return i;
}
};
}
For getting the names of objects :
try
{
JSONObject jsonObject = new JSONObject("{" +"\"server_response\": [{" +"\"Total\": \"135\"," +"\"Paid\": \"105\"," +"\"Rest\": \"30\"" +"}]"+"}";);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
JSONObject object = jsonArray.getJSONObject(0);
for (String key : iterate(object.keys()))
{
// here key will be containing your OBJECT NAME YOU CAN SET IT IN TEXTVIEW.
Toast.makeText(HomeActivity.this, ""+key, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
Hope this helps :)
My suggestion:
Go to this website:
Json to pojo
Get your pojo classes and then use them in Android.
All you need to do is to use Gson.fromGson(params here).
One of your params is the class that you created using the online schema.
You can use jackson ObjectMapper to do this.
public class ServerResponse {
#JsonProperty("Total")
private String total;
#JsonProperty("Paid")
private String paid;
#JsonProperty("Rest")
private String rest;
//getters and setters
//toString()
}
//Now convert json into ServerResponse object
ObjectMapper mapper = new ObjectMapper();
TypeReference<ServerResponse> serverResponse = new TypeReference<ServerResponse>() { };
Object object = mapper.readValue(jsonString, serverResponse);
if (object instanceof ServerResponse) {
return (ServerResponse) object;
}
JSONObject jsonObject = new JSONObject("Your JSON");
int Total = jsonObject.getJSONArray("server_response").getJSONObject(0).getInt("Total");
int Paid = jsonObject.getJSONArray("server_response").getJSONObject(0).getInt("Paid");
int Rest = jsonObject.getJSONArray("server_response").getJSONObject(0).getInt("Rest");
Related
I have some problem fetching info from JSON. I'm confused about whether to use ArrayList or any other data type to retrieve data from JSON server.
I've tried to fetch data using
ArrayList<String>
in model.
Below is data format of JSON
[
{
"sun_timing": "{\"sun_from\":\"12:30\",\"sun_to\":\"4:30\"}",
"mon_timing": "{\"mon_from\":\"3:00\",\"mon_to\":\"4:30\"}"
},
{
"sun_timing": "{\"sun_from\":\"12:30\",\"sun_to\":\"4:30\"}",
"mon_timing": "{\"mon_from\":\"3:00\",\"mon_to\":\"4:30\"}"
}
]
I want to fetch all sun_timing data and mon_timing data.
That is sun_from,sun_to and mon_from,mon_to data.
Your Plain Old Java Object(POJO) for your json looks like this:
public class Example {
#SerializedName("sun_timing")
#Expose
private String sunTiming;
#SerializedName("mon_timing")
#Expose
private String monTiming;
public String getSunTiming() {
return sunTiming;
}
public void setSunTiming(String sunTiming) {
this.sunTiming = sunTiming;
}
public String getMonTiming() {
return monTiming;
}
public void setMonTiming(String monTiming) {
this.monTiming = monTiming;
}
}
See also: https://stackoverflow.com/a/40973753/10452701 for more details about How to get json via Rerofit2.
try this out working for me
private List<String> getSunList() {
ArrayList sunList = new ArrayList<String>()
String sun_json = your_json_string
try {
JSONObject jsonObject = new JSONObject(sun_json)
Log.d(TAG, "jsonObject: "+jsonObject)
Log.d(TAG, "jsonObject: "+sun_json)
JSONArray jsonArray = jsonObject.getJSONArray("sun_timing")
for (i in 0 until jsonArray.length())
{
JSONObject obj = jsonArray.get(i) as JSONObject
String sun_from = obj.getString("sun_from")
String sun_to = obj.getString("sun_to")
sunList.add(sun_from)
Log.d(TAG, "obj= "+obj)
}
}
catch (e: java.lang.Exception)
{
}
return sunList
}
Im learning how to produce and consume JSON in rest services, but I wanna learn it well so im trying all possible cases of objects, one of them is an object that has an List attribute like this class:
import java.util.List;
public class PruebaJSON {
private String nombre;
private List atributos;
private String descripcion;
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public List getAtributos() {
return atributos;
}
public void setAtributos(List atributos) {
this.atributos = atributos;
}
public String getDescripcion() {
return descripcion;
}
public void setDescripcion(String descripcion) {
this.descripcion = descripcion;
}
}
Then all what im doing on my rest service method is this:
#POST
#Path("/prueba")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public PruebaJSON prueba(String data) {
try {
JSONObject json = new JSONObject(data);
Gson convertir = new GsonBuilder().create();
PruebaJSON pruebaJson = convertir.fromJson(json.toString(), PruebaJSON.class);
return pruebaJson;
} catch (Exception e) {
System.out.println("error " + e);
return null;
}
}
Then in POSTMAN I pass this:
{
"descripcion": "Primera prueba",
"nombre": "Prueba 1",
"atributos": [
"hello",
"kek",
"lul"
]
}
And it works fine, the problem is when I try to do the same by Java, for example:
List atributos = new ArrayList<>();
atributos.add("hello");
atributos.add("kek");
atributos.add("lul");
System.out.println(bus.prueba("Prueba 1", "Primera Prueba", atributos));
bus.prueba just executes the service but then in console I get this error:
14:16:56,567 INFO [stdout] (default task-2) error com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was STRING at line 1 column 66 path $.atributos
I did the search of the error and found this:
Gson: Expected begin_array but was STRING
I understand the error but whats the solution?
I can't really control how the JSON builds the arraylist can I?
This is the method prueba in my client:
public String prueba(String nombre, String descripcion, List atributos) {
HashMap map = new HashMap<>();
map.put("nombre", nombre);
map.put("descripcion", descripcion);
map.put("atributos", atributos);
String respuesta = utilidadesRestSeguridad.consumir("prueba", map);
return respuesta;
}
In my client component this is the method that builds the json:
public static JsonObject generateJSON(HashMap map) throws MalformedURLException {
JsonObject json = new JsonObject();
for (Object key : map.keySet()) {
json.addProperty(key.toString(), map.get(key).toString());
}
return json;
}
And thats it guys if you wanna see more code or me to explain something tell me I appreciate any help.
I think maybe the error is in the method generateJSON because of the .toString(), but then how I should handle that case?
Assuming that the line utilidadesRestSeguridad.consumir("prueba", map) ends up calling your generateJSON method downstream, then your issue is likely in the generateJSON() method as you suspect. Basically, you are just adding all elements as strings. If one of the elements in your map is an instance of a List, then you need to call JsonObject#add("atributos", value). For example, you will need something like the following code:
if (map.get(key) instanceof List) {
json.add(key.toString(), map.get(key);
} else {
json.addProperty(key.toString(), map.get(key).toString());
}
As I suspected, the error was in the generateJSON method, needed to add this validation that entpnerd suggested:
public static JsonObject generateJSON(HashMap map) throws MalformedURLException {
JsonObject json = new JsonObject();
for (Object key : map.keySet()) {
if (map.get(key) instanceof List) {
JsonParser parser = new JsonParser();
parser.parse((map.get(key).toString()));
json.add(key.toString(), parser.parse((map.get(key).toString())));
} else {
json.addProperty(key.toString(), map.get(key).toString());
}
}
return json;
}
Notice that I had to use JsonParser, not sure how is it working but at the end that made it work.
Source: How to parse this JSON String with GSON?
Anyways Im gonna try the solution entpnerd is suggesting and post it too.
Here is the implementation of entpnerd suggestion:
public static JsonObject generateJSON(HashMap map) throws MalformedURLException {
JsonObject json = new JsonObject();
for (Object key : map.keySet()) {
if (map.get(key) instanceof List) {
JsonArray jsonArray = new JsonArray();
for (Object object : (ArrayList<Object>) map.get(key)) {
jsonArray.add(object.toString());
}
json.add(key.toString(), jsonArray);
} else {
json.addProperty(key.toString(), map.get(key).toString());
}
}
return json;
}
it works too, you guys decide which one to use, thanks very much.
My only question is, what if the element that is an array, has more arrays inside it, what would you do?
You don't need to get that json value manually, add requestbody annotation to your method parameter
public PruebaJSON prueba(#RequestBody PruebaJSON json){
System.out.println(json);
};
I have the following json
"notes": {"note": [
{
"content": "Having wisdom teeth removed.",
"from": "employee"
},
{
"content": "Get well soon",
"from": "manager"
}
]},
the issue is that the value coud also be
"notes": "",
or
"notes": {"note": {
"content": "This is a test note.",
"from": "employee"
}},
and storing it in these
public class Notes
{
#SerializedName ("note")
public List<Note> note;
}
public class Note
{
#SerializedName ("content")
public String content;
#SerializedName ("from")
public String from;
}
I believe I solved the issue of not being an array but being an single object by doing this
public class Json {
private static Gson gson;
private static class MyNoteClassTypeAdapter implements JsonDeserializer<List<RequestsDTO.Note>> {
public List<RequestsDTO.Note> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) {
List<RequestsDTO.Note> vals = new ArrayList<RequestsDTO.Note>();
if (json.isJsonArray()) {
for (JsonElement e : json.getAsJsonArray()) {
vals.add((RequestsDTO.Note) ctx.deserialize(e, RequestsDTO.Note.class));
}
} else if (json.isJsonObject()) {
vals.add((RequestsDTO.Note) ctx.deserialize(json,RequestsDTO.Note.class));
} else {
throw new RuntimeException("Unexpected JSON type: " + json.getClass());
}
return vals;
}
}
public static Gson getGson()
{
if (gson == null)
{
Type ListType = new TypeToken<List<RequestsDTO.Note>>() {}.getType();
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(DateTime.class, new DateTimeSerializer());
builder.registerTypeAdapter(ListType, new MyNoteClassTypeAdapter());
gson = builder.create();
}
return gson;
}
}
And now I am stuck on when the whole thing just comes back as a string....
Refer the code snippet below to deserialize your json using Gson library without exceptions.
String jsonStr = "your json string ";
Gson gson = new Gson();
JsonObject jsonObj = gson.fromJson (jsonStr, JsonElement.class).getAsJsonObject();
JsonElement elem = jsonObj.get("note");
if(elem.isJsonArray()) { //**Array**
List<Note> notelist = gson.fromJson(elem.toString(), new TypeToken<List<Note>>(){}.getType());
} else if(elem.isJsonObject()) { //**Object**
Note note = gson.fromJson(elem.toString(), Note.class);
} else { //**String**
String note = elem.toString();
}
The idea is try to get "note" field (from "notes" JSONObject) as JSONArray first and if it throws exception that will mean that there is no "note" JSONArray into "notes" JSONObject and that will mean that "note" is JSONObject. The same way we can figure out situation when note field is String.
try {
//String jsonString="{\"notes\": {\"note\": [{\"content\": \"Having wisdom teeth removed.\",\"from\": \"employee\" }, {\"content\": \"Get well soon\", \"from\": \"manager\"} ] }}";
//String jsonString="{\"notes\": { \"note\": {\"content\": \"This is a test note.\",\"from\": \"employee\"}}}";
String jsonString="{\"notes\": { \"note\": \"\"}}";
JSONObject jsonObject=new JSONObject(jsonString);
JSONObject jsonObjectNotes=jsonObject.getJSONObject("notes");
try{
JSONArray jsonArrayNote=jsonObjectNotes.getJSONArray("note");
for (int i = 0; i < jsonArrayNote.length(); i++) {
JSONObject jsonObject2= jsonArrayNote.getJSONObject(i);
String stringContent=jsonObject2.getString( "content");
String stringFrom= jsonObject2.getString( "from");
Log.e(getClass().getName(), "content="+stringContent +"; from="+stringFrom);
}
}
catch(JSONException e){
//that means that jsonObjectNotes has no jsonArray with name "notes" and "notes" is jsonObject
try{
JSONObject jsonObject3=jsonObjectNotes.getJSONObject("note");
String stringContent=(String) jsonObject3.get( "content");
String stringFrom=(String) jsonObject3.get( "from");
Log.e(getClass().getName(), "content="+stringContent +"; from="+stringFrom);
}
catch(JSONException ex){
//that means that jsonObjectNotes has no jsonObject with name "notes" and "notes" is empty String
String stringNote=jsonObjectNotes.getString("note") ;
Log.e(getClass().getName(), "note is string ="+ stringNote);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
In my example code another get operations can also throw jsonExceptions but I think you get the idea.
Have a look at Genson library http://code.google.com/p/genson/.
If your classes are inner classes make them static.
The following code should solve your problem.
Genson genson = new Genson.Builder().withDeserializerFactory(new NotesDeserializerFactory()).create();
Notes notes = genson.deserialize(in, Notes.class);
// Define a factory so you can delegate the deserialization to existing mechanisms for lists and beans
class NotesDeserializerFactory implements Factory<Deserializer<Notes>> {
#Override
public Deserializer<Notes> create(Type type, Genson genson) {
Converter<List<Note>> noteListConverter = genson.provideConverter(new GenericType<List<Note>>() {}.getType());
Converter<Note> noteConverter = genson.provideConverter(Note.class);
return new NotesDeserializer(noteListConverter, noteConverter);
}
}
// define an implementation for you Notes class so you can handle the different cases
class NotesDeserializer implements Deserializer<Notes> {
private final Converter<List<Note>> noteListConverter;
private final Converter<Note> noteConverter;
public NotesDeserializer(Converter<List<Note>> noteListConverter,
Converter<Note> noteConverter) {
this.noteListConverter = noteListConverter;
this.noteConverter = noteConverter;
}
#Override
public Notes deserialize(ObjectReader reader, Context ctx) throws TransformationException,
IOException {
Notes notes = new Notes();
if (reader.getValueType() == ValueType.ARRAY) notes.note = noteListConverter.deserialize(reader, ctx);
else if (reader.getValueType() == ValueType.OBJECT) notes.note = Arrays.asList(noteConverter.deserialize(reader, ctx));
else { // it is a litteral (string, numeric, boolean, null)
notes.note = new ArrayList<Note>();
}
return notes;
}
}
I have the following json
"notes": {"note": [
{
"content": "Having wisdom teeth removed.",
"from": "employee"
},
{
"content": "Get well soon",
"from": "manager"
}
]},
the issue is that the value coud also be
"notes": "",
or
"notes": {"note": {
"content": "This is a test note.",
"from": "employee"
}},
and storing it in these
public class Notes
{
#SerializedName ("note")
public List<Note> note;
}
public class Note
{
#SerializedName ("content")
public String content;
#SerializedName ("from")
public String from;
}
I believe I solved the issue of not being an array but being an single object by doing this
public class Json {
private static Gson gson;
private static class MyNoteClassTypeAdapter implements JsonDeserializer<List<RequestsDTO.Note>> {
public List<RequestsDTO.Note> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext ctx) {
List<RequestsDTO.Note> vals = new ArrayList<RequestsDTO.Note>();
if (json.isJsonArray()) {
for (JsonElement e : json.getAsJsonArray()) {
vals.add((RequestsDTO.Note) ctx.deserialize(e, RequestsDTO.Note.class));
}
} else if (json.isJsonObject()) {
vals.add((RequestsDTO.Note) ctx.deserialize(json,RequestsDTO.Note.class));
} else {
throw new RuntimeException("Unexpected JSON type: " + json.getClass());
}
return vals;
}
}
public static Gson getGson()
{
if (gson == null)
{
Type ListType = new TypeToken<List<RequestsDTO.Note>>() {}.getType();
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(DateTime.class, new DateTimeSerializer());
builder.registerTypeAdapter(ListType, new MyNoteClassTypeAdapter());
gson = builder.create();
}
return gson;
}
}
And now I am stuck on when the whole thing just comes back as a string....
Refer the code snippet below to deserialize your json using Gson library without exceptions.
String jsonStr = "your json string ";
Gson gson = new Gson();
JsonObject jsonObj = gson.fromJson (jsonStr, JsonElement.class).getAsJsonObject();
JsonElement elem = jsonObj.get("note");
if(elem.isJsonArray()) { //**Array**
List<Note> notelist = gson.fromJson(elem.toString(), new TypeToken<List<Note>>(){}.getType());
} else if(elem.isJsonObject()) { //**Object**
Note note = gson.fromJson(elem.toString(), Note.class);
} else { //**String**
String note = elem.toString();
}
The idea is try to get "note" field (from "notes" JSONObject) as JSONArray first and if it throws exception that will mean that there is no "note" JSONArray into "notes" JSONObject and that will mean that "note" is JSONObject. The same way we can figure out situation when note field is String.
try {
//String jsonString="{\"notes\": {\"note\": [{\"content\": \"Having wisdom teeth removed.\",\"from\": \"employee\" }, {\"content\": \"Get well soon\", \"from\": \"manager\"} ] }}";
//String jsonString="{\"notes\": { \"note\": {\"content\": \"This is a test note.\",\"from\": \"employee\"}}}";
String jsonString="{\"notes\": { \"note\": \"\"}}";
JSONObject jsonObject=new JSONObject(jsonString);
JSONObject jsonObjectNotes=jsonObject.getJSONObject("notes");
try{
JSONArray jsonArrayNote=jsonObjectNotes.getJSONArray("note");
for (int i = 0; i < jsonArrayNote.length(); i++) {
JSONObject jsonObject2= jsonArrayNote.getJSONObject(i);
String stringContent=jsonObject2.getString( "content");
String stringFrom= jsonObject2.getString( "from");
Log.e(getClass().getName(), "content="+stringContent +"; from="+stringFrom);
}
}
catch(JSONException e){
//that means that jsonObjectNotes has no jsonArray with name "notes" and "notes" is jsonObject
try{
JSONObject jsonObject3=jsonObjectNotes.getJSONObject("note");
String stringContent=(String) jsonObject3.get( "content");
String stringFrom=(String) jsonObject3.get( "from");
Log.e(getClass().getName(), "content="+stringContent +"; from="+stringFrom);
}
catch(JSONException ex){
//that means that jsonObjectNotes has no jsonObject with name "notes" and "notes" is empty String
String stringNote=jsonObjectNotes.getString("note") ;
Log.e(getClass().getName(), "note is string ="+ stringNote);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
In my example code another get operations can also throw jsonExceptions but I think you get the idea.
Have a look at Genson library http://code.google.com/p/genson/.
If your classes are inner classes make them static.
The following code should solve your problem.
Genson genson = new Genson.Builder().withDeserializerFactory(new NotesDeserializerFactory()).create();
Notes notes = genson.deserialize(in, Notes.class);
// Define a factory so you can delegate the deserialization to existing mechanisms for lists and beans
class NotesDeserializerFactory implements Factory<Deserializer<Notes>> {
#Override
public Deserializer<Notes> create(Type type, Genson genson) {
Converter<List<Note>> noteListConverter = genson.provideConverter(new GenericType<List<Note>>() {}.getType());
Converter<Note> noteConverter = genson.provideConverter(Note.class);
return new NotesDeserializer(noteListConverter, noteConverter);
}
}
// define an implementation for you Notes class so you can handle the different cases
class NotesDeserializer implements Deserializer<Notes> {
private final Converter<List<Note>> noteListConverter;
private final Converter<Note> noteConverter;
public NotesDeserializer(Converter<List<Note>> noteListConverter,
Converter<Note> noteConverter) {
this.noteListConverter = noteListConverter;
this.noteConverter = noteConverter;
}
#Override
public Notes deserialize(ObjectReader reader, Context ctx) throws TransformationException,
IOException {
Notes notes = new Notes();
if (reader.getValueType() == ValueType.ARRAY) notes.note = noteListConverter.deserialize(reader, ctx);
else if (reader.getValueType() == ValueType.OBJECT) notes.note = Arrays.asList(noteConverter.deserialize(reader, ctx));
else { // it is a litteral (string, numeric, boolean, null)
notes.note = new ArrayList<Note>();
}
return notes;
}
}
I'm new to java so this is a bit confusing
I want to get json formatted string
The result I want is
{ "user": [ "name", "lamis" ] }
What I'm currently doing is this :
JSONObject json = new JSONObject();
json.put("name", "Lamis");
System.out.println(json.toString());
And I'm getting this result
{"name":"Lamis"}
I tried this but it didnt work
json.put("user", json.put("name", "Lamis"));
Try this:
JSONObject json = new JSONObject();
json.put("user", new JSONArray(new Object[] { "name", "Lamis"} ));
System.out.println(json.toString());
However the "wrong" result you showed would be a more natural mapping of "there's a user with the name "lamis" than the "correct" result.
Why do you think the "correct" result is better?
Another way of doing it is to use a JSONArray for presenting a list
JSONArray arr = new JSONArray();
arr.put("name");
arr.put("lamis");
JSONObject json = new JSONObject();
json.put("user", arr);
System.out.println(json); //{ "user": [ "name", "lamis" ] }
Probably what you are after is different than what you think you need;
You should have a separate 'User' object to hold all properties like name, age etc etc.
And then that object should have a method giving you the Json representation of the object...
You can check the code below;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
public class User {
String name;
Integer age;
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public JSONObject toJson() {
try {
JSONObject json = new JSONObject();
json.put("name", name);
json.put("age", age);
return json;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
}
public static void main(String[] args) {
User lamis = new User("lamis", 23);
System.out.println(lamis.toJson());
}
}