I have checked out many pages but most of the tutorials and script return an error code with this type of JSON output. So how would I be able to extract the data from this JSON in Java?:
[
{
"user":{"id":"1","username":"user1"},
"item_name":"item1",
"custom_field":"custom1"
},
{
"user":{"id":"2","username":"user2"},
"item_name":"item2",
"custom_field":"custom2"
},
{
"user":{"id":"3","username":"user3"},
"item_name":"item3",
"custom_field":"custom3"
}
]
If you want to use Gson, then first you declare classes for holding each element and sub elements:
public class MyUser {
public String id;
public String username;
}
public class MyElement {
public MyUser user;
public String item_name;
public String custom_field;
}
Then you declare an array of the outermost element (because in your case the JSON object is a JSON array), and assign it:
MyElement[] data = gson.fromJson (myJSONString, MyElement[].class);
Then you simply access the elements of data.
The important thing to remember is that the names and types of the attributes you declare should match the ones in the JSON string. e.g. "id", "item_name" etc.
If your trying to serialize/deserialize json in Java I would recommend using Jackson. http://jackson.codehaus.org/
Once you have Jackson downloaded you can deserialize the json strings to an object which matches the objects in JSON.
Jackson provides annotations that can be attached to your class which make deserialization pretty simple.
You could try JSON Simple
http://code.google.com/p/json-simple/
Example:
JSONParser jsonParser = new JSONParser();
JSONArray jsonArray = (JSONArray) jsonParser.parse(jsonDataString);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject obj = (JSONObject) jsonArray.get(i);
//Access data with obj.get("item_name")
}
Just be careful to check for nulls/be careful with casting and such.
Related
I have an Abstract class with many concrete implementations:
public abstract Ticket {
private Long id;
private Currency fine;
...
}
public class SpeedingTicket extends Ticket {
public Currency getFine(){
// Expensive!
...
}
}
public class ParkingTicket extends Ticket {
public Currency getFine(){
// Eh, not so bad
...
}
}
When the concrete classes are serialized into JSON, it is wrapped with the classes simple name (speedingTickets or parkingTickets):
"_embedded": {
"speedingTickets" :
[{
"id":1,
"fine": "$190",
...,
},
{
"id":2,
"fine": "$100",
...,
}]
}
or
"_embedded": {
"parkingTickets" :[{
"id":100,
"fine": "$15",
...,
}]
}
Since I do not know, at runtime, which Ticket implementation I am receiving back, how can I parse the JSON out using the JSON Response API given the array is wrapped with the concrete implementations simple name?
I have a hack where I take the String value of the JSON and do String operations (substring, indexOf, etc) on it to return only what's in between the braces ("[...]"). I know there's a better way to do this...
After some research, I think I'll try the following tomorrow to see if it works:
JsonNode rootNode = mapper.readTree(jsonResponse);
String classImpl = Iterables.get(rootNode.get("_embedded").fields(), 0).textValue()
I can then say List<Ticket> tickets = response.readAsList(jsonResponse, "_embedded",classImpl) which should allow me to parse the JSON into a List
If you're using Jackson (as your tag suggests), you want to use Polymorphic Deserialization - which is exactly the problem of knowing how to deserialize to the correct subtype.
For example:
#JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="#class")
class { }
What this essentially does is include the class name in your JSON, so the deserializer has enough information to properly choose the subclass to instantiate. Something like this:
"_embedded": {
"parkingTickets" :[{
"_type": "ParkingTicket.class",
"id":100,
"fine": "$15",
...,
}]
}
You can just check the type by checking the variable the response contains.
JSONObject jsonObj = new JSONObject(response);
if(jsonObj.has("speedingTickets")){
// parse speedingTickets
}else if(jsonObj.has("parkingTickets")){
// parse parkingtickets
}
A JSON object is an unordered set of key/value pairs. A JSON array is an ordered collection of values. The values themselves could be objects or arrays.
In java it is easy to parse json with org.json library https://github.com/stleary/JSON-java
Short example how to parse json array:
String str = "{ \"number\": [3, 4, 5, 6] }";
JSONObject obj = new JSONObject(str);
JSONArray arr = obj.getJSONArray("number");
for (int i = 0; i < arr.length(); i++)
System.out.println(arr.getInt(i));
Right now I am using Gson to deserialize JSON to Object.
The JSON looks like this:
[
{
"hash":"c8b2ce0aacede58da5d2b82225efb3b7",
"instanceid":"aa49882f-4534-4add-998c-09af078595d1",
"text":"{\"C_FirstName\":\"\",\"ContactID\":\"2776967\",\"C_LastName\":\"\"}",
"queueDate":"2016-06-28T01:03:36"
}
]
And my entity object looks like this:
public class AppCldFrmContact {
public String hash;
public String instanceid;
public HashMap<String,String> text;
public String queueDate;
}
If text was a String data type, everything would be fine. But then I wouldn't be able to access different fields as I want to.
Is there a way to convert given JSON to Object I want?
The error I am getting is: Expected BEGIN_OBJECT but was STRING at line 1 column 174, which is understandable if it cannot parse it.
The code doing the parsing:
Type listType = new TypeToken<List<AppCldFrmContact>>() {
}.getType();
List<AppCldFrmContact> contacts = gson.fromJson(response.body, listType);
For you expected result, JSON data should be like below format,
[
{
"hash":"c8b2ce0aacede58da5d2b82225efb3b7",
"instanceid":"aa49882f-4534-4add-998c-09af078595d1",
"text":{"C_FirstName":"","ContactID":"2776967","C_LastName":""},
"queueDate":"2016-06-28T01:03:36"
}
]
You are getting this error because text field is a JSON map serialized to the string. If it is an actual your data and not a just an example, you can annotate a field with #JsonDeserialize and write your own custom JsonDeserializer<HashMap<String,String>> which will make deserialization 2 times.
I have a JSON payload coming from the server which is a list of Objects. I need a way to get the response and then check each object for a particular attribute and then decide which POJO object to decode each of those. I have checked StackOverflow and I have come across solutions like :
Gson gson = new Gson();
String json = response.getBody().toString();
if (checkResponseMessage(json)) {
Pojo1 pojo1 = gson.fromJson(json, Pojo1.class);
} else {
Pojo2 pojo2 = gson.fromJson(json, Pojo2.class);
}
here the json string is the entire string which is a list of objects, i need to drill down into the list, check an attribute in the object to determine which POJO to use. Any pointers or help appreciated! Thanks!
I am trying to parse the JSON from this link: https://api.guildwars2.com/v2/items/56 , everything fine until i met the line: "infix_upgrade":{"attributes":[{"attribute":"Power","modifier":4},{"attribute":"Precision","modifier":3}]} ...
If i dont get this wrong: infix_upgradehas 1 element attributes inside him. attributes has 2 elements with 2 other inside them. Is this a 2 dimension array?
I have tried (code too long to post):
JsonObject _detailsObject = _rootObject.get("details").getAsJsonObject();
JsonObject infix_upgradeObject = _detailsObject.get("infix_upgrade").getAsJsonObject();
JsonElement _infix_upgrade_attributesElement = infix_upgradeObject.get("attributes");
JsonArray _infix_upgrade_attributesJsonArray = _infix_upgrade_attributesElement.getAsJsonArray();
The problem is that I dont know what to do next, also tried to continue transforming JsonArray into string array like this:
Type _listType = new TypeToken<List<String>>() {}.getType();
List<String> _details_infusion_slotsStringArray = new Gson().fromJson(_infix_upgrade_attributesJsonArray, _listType);
but im getting java.lang.IllegalStateException: Expected STRING but was BEGIN_OBJECT which i guess comes from the attributes...
With a proper formatting (JSONLint, for example, checks if the JSON data is valid and does the formatting, which makes the structure more clear than what the GW link gives), attributes looks actually like this:
"attributes": [
{
"attribute": "Power",
"modifier": 4
},
{
"attribute": "Precision",
"modifier": 3
}
]
So it's an array of JsonObject and each object as two key-value pairs. This is why the parser throws an error because you require that this array contains only String which is not the case.
So the actual type is:
Type _listType = new TypeToken<List<JsonObject>>(){}.getType();
The problem is that I dont know what to do next
Hold on. You are using Gson and Java is an OO language so I suggest you to create classes.
This would be easier for you to fetch the datas afterward and for the parsing since you just need to provide the class of the actual class the JSON data represents to the parser (some edge-cases could be handled by writing a custom serializer/deserializer).
The data is also better typed than this bunch of JsonObject/JsonArray/etc.
This will give you a good starting point:
class Equipment {
private String name;
private String description;
...
#SerializedName("game_types")
private List<String> gameTypes;
...
private Details details;
...
}
class Details {
...
#SerializedName("infix_upgrade")
private InfixUpgrade infixUpgrade;
...
}
class InfixUpgrade {
private List<Attribute> attributes;
...
}
class Attribute {
private String attribute;
private int modifier;
...
}
and then just give the type to the parser:
Equipment equipment = new Gson().fromJson(jsonString, Equipment.class);
Hope it helps! :)
Given the following JSON object
{
"id": 5,
"data: { ... }
}
Is it possible to map this to the following POJO?
class MyEntity {
int id;
Map<String, Object> data;
}
Because I would like to leave the data object open ended. Is this even possible or what is a better approach to go about this? I am doing this on Android.
I don't have any idea about Android application but you can achieve it using Gson library easily.
The JSON that is used in your post is not valid. It might be a typo. Please validate it here on JSONLint - The JSON Validator
Simply use Gson#fromJson(String, Class) method to convert a JSON string into the object of passed class type.
Remember the name of instance member must be exactly same (case-sensitive) as defined in JSON string as well. Read more about JSON Field Naming
Use GsonBuilder#setPrettyPrinting() that configures Gson to output Json that fits in a page for pretty printing.
Sample code:
String json = "{\"id\": 5,\"data\": {}}";
MyEntity myEntity = new Gson().fromJson(json, MyEntity.class);
String prettyJsonString = new GsonBuilder().setPrettyPrinting().create().toJson(myEntity);
System.out.println(prettyJsonString);
output:
{
"id": 5,
"data": {}
}