Parsing JSON Object with no identifier with Jackson - java

I am getting JSON from a web service, the JSON response I'm getting is:
{
"response":"itemList",
"items":[
"0300300000",
"0522400317",
"1224200035",
"1224200037",
"1547409999"
]
}
I am looking to get each id within the items array. The problem is I'm unsure how to parse this with Jackson when there are no identifiers for the id in the items array. My understanding is I could have an item class with a variable id and #JsonProperty ("id"), but I don't know how to proceed. I need to display these ids in a list (which I can do no problem once I have the data.
Could someone please point me in the right direction.
Thank you.

You could deserialize into something like
public class MyData {
public String response;
public List<String> items;
}
(this will also work if you have private fields with public set methods). Or if you don't mind having jackson-specific annotations in your data classes, you can leave them as non-public and annotate them:
public class MyData {
#JsonProperty
String response;
#JsonProperty
List<String> items;
}
either way, use this to parse:
import com.fasterxml.jackson.databind.ObjectMapper;
//...
MyData data=new ObjectMapper().readValue(jsonStringFromWebService, MyData.class);

You can Convert the JSON String to JSON object, and identify the array and get the IDs..
String josn = "{\"response\":\"itemList\", \"items\":[\"0300300000\",\"0522400317\",\"1224200035\",\"1224200037\",\"1547409999\"]}";
JSONObject jsonObject = new org.json.JSONObject(josn);
JSONArray itemsArray = jsonObject.getJSONArray("items");
System.out.println("Item - 1 =" + itemsArray.getString(0));

class Something {
public String response;
#JsonCreator
public Something(#JsonProperty("response") String response) {
this.response=response;
}
public List<String> items= new ArrayList<String>();
public List<String> addItem(String item) {
items.add(item);
return items;
}
}
and then:
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException {
String json = "{\"response\":\"itemList\",\"items\":[\"0300300000\",\"0522400317\"]}";
ObjectMapper mapper = new ObjectMapper();
mapper.readValue(json, Something.class);
}

I think so, you want this :
ArrayList<String> notifArray=new ArrayList<String>();
JSONObject jsonObj= new JSONObject (resultLine);
JSONArray jArray = jsonObj.getJSONArray("items");
for (int i = 0; i < jArray.length(); i++) {
String str = jArray.getString(i);
notifArray.add(str);
}

Related

Create org.json.JSONObject from a class object by using Gson

I have the following Java class
public static class LogItem {
public Long timestamp;
public Integer level;
public String topic;
public String type;
public String message;
}
and I want to convert an ArrayList<LogItem> into the following JSON string:
{"logitems":[
{"timestamp":1560924642000, "level":20, "topic":"websocket", "type":"status", "message":"connected (mobile)"},
...
]}`
I would like to do the following:
JSONArray logitems = new JSONArray();
for (DB_LogUtils.LogItem item : items) {
logitems.put(DB_LogUtils.asJSONObject(item)); // <----
}
JSONObject data = new JSONObject();
data.put("logitems", logitems);
webViewFragment.onInjectMessage(data.toString(), null);
where DB_LogUtils.asJSONObject is the following method
public static JSONObject asJSONObject(LogItem item) throws JSONException
{
JSONObject logitem = new JSONObject();
logitem.put("timestamp", item.timestamp);
logitem.put("level", item.level);
logitem.put("topic", item.topic);
logitem.put("type", item.type);
logitem.put("message", item.message);
return logitem;
}
but instead of doing this manually (like logitem.put("timestamp", item.timestamp);) I want to do this with Gson, so that I would end up with something like this
JSONArray logitems = new JSONArray();
for (DB_LogUtils.LogItem item : items) {
logitems.put(new Gson().toJSONObject(item)); // <----
}
JSONObject data = new JSONObject();
data.put("logitems", logitems);
webViewFragment.onInjectMessage(data.toString(), null);
in order to not have to edit the code at multiple points when the LogItem class changes.
But Gson().toJSONObject(...) does not exist, only Gson().toJson(...), which returns a String. I don't want to transition into a String only to then parse it with org.json.JSONObject.
I ended up using a second class
public static class LogItems {
public List<LogItem> logitems = new ArrayList<>();
}
which then let me change the whole code to
webViewFragment.onInjectMessage(new Gson().toJson(items), null);
where items would be of type LogItems.
In this case, creating the extra wrapper class was an overall benefit, but I'd still want to know how I can create such a JSONObject from a class by using Gson.
As far as i know it could be not possible without using for loop to iterate json string into array and store into map with same key.
But you can achieve your solution instead of passing dto pass the list of items into gson object as follow.
List<Object> list = new ArrayList<Object>();
list.add("1560924642000");
list.add(20);
list.add("websocket");
list.add("status");
list.add("connected (mobile)");
Gson gson = new Gson();
Map mp = new HashMap();
mp.put("ietams", list);
String json = gson.toJson(mp);
System.out.println(json);
output will be
{"logitems":["1560924642000",20,"websocket","status","connected (mobile)"]}
Hope this will help !

How to pull values from a json object that looks like "key":[10,12,56] with Java

In wordpress an Api I use returns the tags' ids in an odd way, it returns in this ways:
"tags":[50,51,54]
I have never seen any Json that doesn't look like "key":"value", and I got no clue how to parse it...
I hope you can help, Thank you!
Update:
My bad, the example I posted was not a full json, it looks like that:
{"categories":[2,8],"tags":[50,51,54]}
The [] indicate that the tags are stored as an array. You can use JSONObject.getJSONArray() to access the array as a JSONArray object, then use .getInt() to retrieve the values. For example:
String jsonString = "{\"categories\":[2,8],\"tags\":[50,51,54]}";
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray tagsArray = jsonObject.getJSONArray("tags");
// Transfer JSONArray to an int[] array.
int tags[] = new int[tagsArray.length()];
for (int i=0; i<tagsArray.length(); i++) {
tags[i] = tagsArray.getInt(i);
}
You can create a class for this json string and parse the json with just one line of code as shown in main method.
public class Example {
private List<Integer> categories = null;
private List<Integer> tags = null;
public List<Integer> getCategories() {
return categories;
}
public void setCategories(List<Integer> categories) {
this.categories = categories;
}
public List<Integer> getTags() {
return tags;
}
public void setTags(List<Integer> tags) {
this.tags = tags;
}
public static void main(String[] args) {
String str = "{\"categories\":[2,8],\"tags\":[50,51,54]}";
Example example = new Gson().fromJson(str, Example.class);
System.out.println(example.getCategories());
System.out.println(example.getTags());
}
}
You need to have gson library for this and have this import,
import com.google.gson.Gson;
Hope this works for you.

De/Serialize Gson an array of arrays [duplicate]

I'm trying to parse some JSON data using gson in Java that has the following structure but by looking at examples online, I cannot find anything that does the job.
Would anyone be able to assist?
{
"data":{
"id":[
{
"stuff":{
},
"values":[
[
123,
456
],
[
123,
456
],
[
123,
456
],
],
"otherStuff":"blah"
}
]
}
}
You just need to create a Java class structure that represents the data in your JSON. In order to do that, I suggest you to copy your JSON into this online JSON Viewer and you'll see the structure of your JSON much clearer...
Basically you need these classes (pseudo-code):
class Response
Data data
class Data
List<ID> id
class ID
Stuff stuff
List<List<Integer>> values
String otherStuff
Note that attribute names in your classes must match the names of your JSON fields! You may add more attributes and classes according to your actual JSON structure... Also note that you need getters and setters for all your attributes!
Finally, you just need to parse the JSON into your Java class structure with:
Gson gson = new Gson();
Response response = gson.fromJson(yourJsonString, Response.class);
And that's it! Now you can access all your data within the response object using the getters and setters...
For example, in order to access the first value 456, you'll need to do:
int value = response.getData().getId().get(0).getValues().get(0).get(1);
Depending on what you are trying to do. You could just setup a POJO heirarchy that matches your json as seen here (Preferred method). Or, you could provide a custom deserializer. I only dealt with the id data as I assumed it was the tricky implementation in question. Just step through the json using the gson types, and build up the data you are trying to represent. The Data and Id classes are just pojos composed of and reflecting the properties in the original json string.
public class MyDeserializer implements JsonDeserializer<Data>
{
#Override
public Data deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException
{
final Gson gson = new Gson();
final JsonObject obj = je.getAsJsonObject(); //our original full json string
final JsonElement dataElement = obj.get("data");
final JsonElement idElement = dataElement.getAsJsonObject().get("id");
final JsonArray idArray = idElement.getAsJsonArray();
final List<Id> parsedData = new ArrayList<>();
for (Object object : idArray)
{
final JsonObject jsonObject = (JsonObject) object;
//can pass this into constructor of Id or through a setter
final JsonObject stuff = jsonObject.get("stuff").getAsJsonObject();
final JsonArray valuesArray = jsonObject.getAsJsonArray("values");
final Id id = new Id();
for (Object value : valuesArray)
{
final JsonArray nestedArray = (JsonArray)value;
final Integer[] nest = gson.fromJson(nestedArray, Integer[].class);
id.addNestedValues(nest);
}
parsedData.add(id);
}
return new Data(parsedData);
}
}
Test:
#Test
public void testMethod1()
{
final String values = "[[123, 456], [987, 654]]";
final String id = "[ {stuff: { }, values: " + values + ", otherstuff: 'stuff2' }]";
final String jsonString = "{data: {id:" + id + "}}";
System.out.println(jsonString);
final Gson gson = new GsonBuilder().registerTypeAdapter(Data.class, new MyDeserializer()).create();
System.out.println(gson.fromJson(jsonString, Data.class));
}
Result:
Data{ids=[Id {nestedList=[[123, 456], [987, 654]]}]}
POJO:
public class Data
{
private List<Id> ids;
public Data(List<Id> ids)
{
this.ids = ids;
}
#Override
public String toString()
{
return "Data{" + "ids=" + ids + '}';
}
}
public class Id
{
private List<Integer[]> nestedList;
public Id()
{
nestedList = new ArrayList<>();
}
public void addNestedValues(final Integer[] values)
{
nestedList.add(values);
}
#Override
public String toString()
{
final List<String> formattedOutput = new ArrayList();
for (Integer[] integers : nestedList)
{
formattedOutput.add(Arrays.asList(integers).toString());
}
return "Id {" + "nestedList=" + formattedOutput + '}';
}
}

converting json into java object for a array with mixed types

My json string looks like the following:
{
"text": ["foo",1,"bar","2",3],
"text1": "value1",
"ComplexObject": {
.....
}
}
I have a pojo defined like this:
class MyPojo {
List<String> text;
String text1;
ComplexObject complexObject;
}
I use google gson and am able to get my java object populated properly. The problem here is that the field text is an array of mixed types (string and int). So all the entries there are converted into String and i am not able to figure out which entries in the array is a string vs int. I cant use parseInt since the entries in the original array may have "2" as well as 3.
Is there a way for me to get the right instance type of the fields in my array after converting into java object.
SOLUTION
So i implemented the solution using gson the round about way using the JsonDeserializer. And then i tried using jackson. Guess what jackson supports serializing/deserializing the mixed array type by preserving the data types.
ObjectMapper mapper = new ObjectMapper();
MyPojo gmEntry = mapper.readValue(json, new TypeReference<MyPojo >(){});
And i can basically fetch the List<Object> and do an instanceof to check for the datatype.
Shame on you gson!!
By having a custom class and adding a type adapter u can manipulate the string (json.toString() returns with the '"' quotes, so you can see if its a string or not.
Output: (the classes seem correct)
class test.Main$StringPojo pojo{object=foo}
class test.Main$IntPojo pojo{object=1}
class test.Main$StringPojo pojo{object=bar}
class test.Main$StringPojo pojo{object=2}
class test.Main$IntPojo pojo{object=3}
public static void main(final String[] args){
String str = "{\n" +
" \"text\": [\"foo\",1,\"bar\",\"2\",3],\n" +
" \"text1\": \"value1\" }";
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(pojo.class, new JsonDeserializer<pojo>() {
#Override
public pojo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
return new IntPojo(Integer.parseInt(json.toString()));
} catch (Exception e) {
return new StringPojo(json.getAsString());
}
}
});
MyPojo myPojo = builder.create().fromJson(str, MyPojo.class);
for (pojo pojo : myPojo.text) {
System.out.println(pojo.getClass() + " " + pojo.object);
}
}
public static abstract class pojo{
protected Object object;
public pojo() {
}
#Override
public String toString() {
return "pojo{" +
"object=" + object +
'}';
}
}
public static class StringPojo extends pojo{
public StringPojo(String str) {
object = str;
}
}
public static class IntPojo extends pojo{
public IntPojo(int intt) {
this.object = intt;
}
}
public static class MyPojo {
List<pojo> text;
String text1;
}
As you wrote - you defined: List<String> text; but that list also contains integers.
Java is strongly typed, please consider to either declare the List as List<Object> (less preferable) or creating a JSON list that contains only a single type of variable (more preferable).
You can create an abstract class ItemType (for use as array item type) and inherits from it two wrapper classes: one for int type and another for string type.
abstract class ItemType {
protected Object value;
}
class IntType extends ItemType {
IntType(Integer value){
this.value = value;
}
}
class StringType extends ItemType {
IntType(String value){
this.value = value;
}
}
Try this List<ItemType> text;
The above situation can be achived by using TypeAdapter of Gson API.
Please follow : https://sites.google.com/site/gson/gson-user-guide#TOC-Serializing-and-Deserializing-Collection-with-Objects-of-Arbitrary-Types
Not sure if this is what you need, but this is the code I use for parsing JSON.
static public void newsParser(String urlString, String targetObject) throws FileNotFoundException, IOException
{
URL url = new URL(urlString);
JSONParser parser=new JSONParser();
BufferedReader br = new BufferedReader(new InputStreamReader(url.openStream()));
Object obj;
try
{
obj = parser.parse(br);
//JSONObject jsonObject = (JSONObject) obj;
JSONArray jsonArray = (JSONArray) obj;
Iterator<?> i = jsonArray.iterator();
while (i.hasNext())
{
slide = (JSONObject) i.next();
newsInfo = (String)slide.get(targetObject);
System.out.println(newsInfo);
newsTitles.add(newsInfo);
}
}
catch (ParseException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

Parsing JSON ARRAY

I'm working on json parsing and I got a problem.
This is my JSON:
"cards":[
{
"id":"bgyr6gh5yr6154",
"checkItemStates":[
],
"closed":false,
"desc":"",
"due":"2012-06-13T10:00:00.000Z",
"idBoard":"4v454g5r1515",
"idChecklists":[
],
"idList":"16562562526",
"idMembers":[
"2848f4g85t15"
],
"idShort":15,
"labels":[
],
I can get all information in the JSON Array cards (e.g "closed", "due",...)
I'm doing for instance,
JSONArray msg2 = (JSONArray) all.get("cards");
then
String boardId = (String) monobjet.get("closed");
and it works fine!
BUT
I don't know how to get "idMembers" !
Any idea, because it's array in a array?
JSONArray msg2 = (JSONArray) all.get("cards");
then
for (int i2 = 0; i2 < size2; i2++) {
myobject = (JSONObject) msg2.get(i2);
listTemp2.add(jsonObecjtToMyData(myobject));
}
String boardName = (String) monobjet.get("name");
For complex json objects such as the one given, I will strongly recommend gson which will do all the task for you.For example:
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Map map = gson.fromJson(inputField.getText(),Map.class);
Now, map conatains all the things you need, so iterate through the map get the idMembers put it in a list and while you are putting it typecast it to string or any datatype that is fit.
You can individually typecast but not an array. So this will compile and run:
public class MainApp {
public Object obj[]={"foo","loo"};
public Object obj2 = "soo";
public static void main(String[] args) {
MainApp mainApp = new MainApp();
String name = (String) mainApp.obj2;
System.out.println(name);
}
}
Some food for thought:
JSONArray is an object. How would the json handler that you are using would know that it is a JSONArray or list?
Can we do something like this?:
public class MainApp {
public Object obj[]={"foo","loo"};
public static void main(String[] args) {
MainApp mainApp = new MainApp();
String name[] = (String[])mainApp.obj;
for(String str : name){
System.out.println(str);
}
}}
Please use gson and save yourself a lot of pain.Also for complex pojos you can use ObjectMapper.

Categories