LibGDX parsing standard json to an object - java

I have a very basic problem.
I read though the LibGDX documentation a few times regarding JSON and Google around for an answer but it still does't work..
Basically I'm pulling json from a server like such which works as:
{"id":1,"facebook_id":"23432232","json":"{\"json\":\"test\"}"}
I have a class like this:
public class ServerJson
{
public static final String NAME = "ServerJson";
private int id;
private String facebookID;
private String json;
public ServerJson(){}
public ServerJson(int id, String facebookID, String json)
{
this.id = id;
this.facebookID = facebookID;
this.json = json;
}
public int getId() {
return id;
}
public String getFacebookID() {
return facebookID;
}
public String getJson() {
return json;
}
When I try to parse the code, it doesn't work. I get null:
String resultString = httpResponse.getResultAsString(); //{"id":1,"facebook_id":"23432232","json":"{\"json\":\"test\"}"}
Json json = new Json();
ServerJson serverJson = json.fromJson(ServerJson.class, resultString);
log(serverJson.getFacebookID()); //<< Is null.

Make sure the fields of your object class match up with the fields of the json object.

Related

How to model Json array in Java?

I am pretty new to Java.
I want to model this request for a batch request to Microsoft graphAPI.
{"requests":[
{"id":"employeeId","method":"GET","url":"/me/employeeId"},
{"id":"thumbnailPhoto","method":"GET","url":"/me/photo/$value"}]
}
So "requests" is an array of BatchRequest object.
What I have currently:
// BatchRequest object
public class BatchRequest
{
private String id;
private String method;
private String url;
public BatchRequest(String id, String method, String url)
{
this.id = id;
this.method = method;
this.url = url;
}
// getters and setters below
}
private List<BatchRequest> requests;
#Override
public UserInfoResponse callGraphApi()
{
BatchRequest employeeId = new BatchRequest("employeeId", "GET", "/me/employeeId");
BatchRequest photo = new BatchRequest("thumbnailPhoto", "GET", "/me/photo/$value");
requests.add(employeeId);
requests.add(photo);
return callGraphApi(requests);
}
Is this how I would model the JSON?
Found this Jsonschema2pojo while i was trying to figure out how to model my Json response into java objects in android app development. Install gson or jackson in your project and it'll take care of the things under the hood.
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class BatchRequest {
#SerializedName("requests")
#Expose
private List<Request> requests = null;
public List<Request> getRequests() {
return requests;
}
public void setRequests(List<Request> requests) {
this.requests = requests;
}
}
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Request {
#SerializedName("id")
#Expose
private String id;
#SerializedName("method")
#Expose
private String method;
#SerializedName("url")
#Expose
private String url;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Sure. The task of turning an instance of a simple java object into a bunch of JSON, as well as the job of turning a bunch of JSON, combined with a list of simple java classes into instances of those classes, is called 'marshalling'. You'll need a library to do it; the popular ones are Jackson and GSON.

JSON to GSON and POJO class

I have a JSON response like the following:
{
"number":"123456789101112",
"dimensions":"{\"height\":\"8.200\",\"width\":\"18.800\",\"depth\":\"9.400\"}",
"uom":"centimetre"
}
I am using the following to convert from JSON to GSON
Gson gson = new Gson();
Details details = gson.fromJson(JSONresponse, Details .class);
I want to know how to map the JSON response into my pojo class for converting this JSON to GSON and retrieving individual values.
I want to know how to access the height,width,depth from the response. This is my current Details class:
public class Details
{
private String number;
private String dimensions;
private String uom;
public void setNumber(String number){
this.number = number;
}
public String getNumber(){
return this.number;
}
public void setDimensions(String dimensions){
this.dimensions = dimensions;
}
public String getDimensions(){
return this.dimensions;
}
public void setUom(String uom){
this.uom = uom;
}
public String getUom(){
return this.uom;
}
}
I would model your POJO as:
public class Details {
private Integer number;
private Dimension dimensions; // lowercase according to Java naming conventions
private String uom;
// getters and setters
}
public class Dimension {
private String height;
private String width;
private String depth;
// getters and setters
}
Then just use your current (correct) code, and then access whichever fields you want:
Gson gson = new Gson();
Details details = gson.fromJson(JSONresponse, Details.class);
String height = details.getDimensions().getHeight();

Trouble serializing with to JSON in Java using Jackson

Good morning guys!
I have a JSON strings that looks like:
{
"StatusCode":0,
"Message":null,
"ExecutionTime":0,
"ResponseData":[
{"Name":"name1","SiteId":"1234","Type":"Type1","X":"1234567","Y":"123456"},
{"Name":"Name2","SiteId":"2134","Type":"Type2","X":"1234567","Y":"1234567"},
{"Name":"Name3","SiteId":"3241","Type":"Type3","X":"1234567","Y":"1234567"},
{"Name":"Name4","SiteId":"4123","Type":"Type4","X":"123456","Y":"123456"}
]
}
I want to create an object where I can retrieve the Xand Y values.
I've been trying to use Jackson to serialize the JSON string, without success. I've created two extra classes for Jackson to use. One class for the top layer, StatusCode, Message, ExecutionTime and ResponseData which looks like
public class PL {
private Long statusCode;
private String executionTime;
private String message;
private ResponseData responseData;
public PL(){
}
public void setStatusCode(Long statusCode){
this.statusCode = statusCode;
}
public Long getStatusCode(){
return this.statusCode;
}
public void setExecutionTime(String executionTime){
this.executionTime = executionTime;
}
public String getExecutionTime(){
return this.executionTime;
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return this.message;
}
public void setResponseData(ResponseData responseData){
this.responseData = responseData;
}
public ResponseData getResponseData(){
return this.responseData;
}
}
Where ReponseData is returned as an object, and then I have another class for serializing ResponseData which looks like
public class ResponseData {
private String name;
private String siteId;
private String type;
private String x;
private String y;
public ResponseData(){
}
public void setName(String name){
this.name = name;
}
public String getName(){
return this.name;
}
public void setSiteId(String siteId){
this.siteId = siteId;
}
public String getSiteId(){
return this.siteId;
}
public void setType(String type){
this.type = type;
}
public String setType(){
return this.type;
}
public void setX(String x){
this.x = x;
}
public String getX(){
return this.x;
}
public void setY(String y){
this.y = y;
}
public String getY(){
return this.y;
}
}
I then create an ObjectMapper with
private final static ObjectMapper mapper = new ObjectMapper();
and try to so read the values with
ResponseData e = mapper.readValue(result.toString(), ResponseData.class);
and end up with the exception
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "StatusCode" (class MyClass.ResponseData), not marked as ignorable (5 known properties: "x", "y", "siteId", "name", "type"])
as if it can't parse the first entry, StatusMessage. Even if I remove the second class and only try to parse the first four entries where i return ResponseData as a String I still get the same exception.
To start with, in PL you should have a List<ResponseData> not a simple ResponseData attribute. As you can see, in the JSON, ResponseData is an array "ResponseData":[...] so it will be deserialized as a List. Each element of the list will be a ResponseData object as you defined it.
Then you have a case issue, you have upper cases in the JSON that you don't have in your class attributes. You can use the #JsonProperty (See API) annotation to overcome the problem, this way:
class PL {
#JsonProperty("StatusCode")
private Long statusCode;
#JsonProperty("ExecutionTime")
private String executionTime;
#JsonProperty("Message")
private String message;
#JsonProperty("ResponseData")
private List<ResponseData> responseDatas;
public PL(){
}
// getters/Setters
}
class ResponseData {
#JsonProperty("Name")
private String name;
#JsonProperty("SiteId")
private String siteId;
#JsonProperty("Type")
private String type;
#JsonProperty("X")
private String x;
#JsonProperty("Y")
private String y;
public ResponseData(){
}
// getters/Setters
}
Then read your JSON as a PL object, like this:
ObjectMapper mapper = new ObjectMapper();
PL pl = mapper.readValue(json, PL.class);
for(ResponseData rd : pl.getResponseDatas()) {
System.out.println(rd.getX());
System.out.println(rd.getY());
}
This outputs:
1234567
123456
1234567
1234567
1234567
1234567
123456
123456
It is fairly straightforward. Define your response structure using composition of classes. It is unfortunate to use capitalised fields in JSON, which out-of-the-box requires capitalised field names in the Java DTO. Still those can be easily mapped to conventional low-case names either by using the ACCEPT_CASE_INSENSITIVE_PROPERTIES modifier on the ObjectMapper or by annotating fields with corresponding names. I prefer a property on the ObjectMapper as it keeps the DTO independent of the serialisation code and this technique is used in the test below (the test is green):
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
public class TestDeserialization50386188 {
public static class Response {
public static class ResponseDataType {
public String name;
public String siteId;
public String type;
public long x;
public long y;
}
public int statusCode;
public String message;
public long executionTime;
public List<ResponseDataType> ResponseData = new ArrayList<>();
}
private static final String data = "{\"StatusCode\":0,\"Message\":null,\"ExecutionTime\":0,\"ResponseData\":[{\"Name\":\"name1\",\"SiteId\":\"1234\",\"Type\":\"Type1\",\"X\":\"1234567\",\"Y\":\"123456\"},{\"Name\":\"Name2\",\"SiteId\":\"2134\",\"Type\":\"Type2\",\"X\":\"1234567\",\"Y\":\"1234567\"},{\"Name\":\"Name3\",\"SiteId\":\"3241\",\"Type\":\"Type3\",\"X\":\"1234567\",\"Y\":\"1234567\"},{\"Name\":\"Name4\",\"SiteId\":\"4123\",\"Type\":\"Type4\",\"X\":\"123456\",\"Y\":\"123456\"}]}";
#Test
public void deserialize_response_withJackson_ok() throws IOException {
ObjectMapper mapper = new ObjectMapper()
.configure(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES, true);
Response response = mapper.readValue(data, Response.class);
assertEquals(4, response.ResponseData.size());
assertEquals(1234567, response.ResponseData.get(2).x);
assertEquals(1234567, response.ResponseData.get(2).y);
}
}
You fill find the project with the executable test on this dedicated GitHub repo.
The "Clean Code" book by Uncle Bob does not really recommend the overuse of getters and setters so common in Java for DTOs, which a Response class is. Still you can replace all public fields with getter/setter pairs if you like but the clarity will suffer with no obvious gain on quality.
Use List to receive arrays.
private Long statusCode;
private String executionTime;
private String message;
public List<ResponseDataType> ResponseData
and it will do everything automatically.

Convert JSON array to Java Class Object List

I have a JSON string that comes from a WFC service. When I try to convert JSON array into List object, I've got the following error :
".JsonMappingException: Can not deserialize instance of java.util.ArrayList out of START_OBJECT token at [Source: java.io.StringReader#41f27f18; line: 1, column: 1]"
The Java class (Card Class):
public class Card {
public String ID;
public String CompanyID;
public String CompanyName;
public String FiscalCode;
public String Limit;
public String StateID;
public String CardState;
public String Deleted;
public String Sold;
public String StartDate;
public String InvoiceStartDate;
public String Quantity;
public String Value;
public String CardTypeID;
public String CardType;
public String SoldChanged;
public String DriverName;
public String VehiclePlateNumber;
public String VehicleID;
public String Discount;
public String ContractID;
public String DiscountPerMonth;
public String ProductID;
public String ProductStateID;
public String Mail;
public String WithoutLimit;
public String ContractSold;
public String ContractLimit;
public String NumberOfTransactions;
public String DriverNameOnly;
public String DriverSurnameOnly;
}
The Java code to deserialize :
strResponse = responseHandler.handleResponse(response);
if (strResponse.contains("Credit") || strResponse.contains("Debit")) {
ObjectMapper mapper = new ObjectMapper();
strResponse= strResponse.replace("\"GetCardsResult\":", "");
userCards = mapper.readValue(strResponse, mapper.getTypeFactory().constructCollectionType(List.class, Card.class));
}
The JSON string:
{ "GetCardsResult":"[{\"ID\":3,\"CompanyID\":1155,\"CompanyName\":\"test\",\"FiscalCode\":null,\"Code\":\"1423127205\",\"Limit\":0.000,\"StateID\":1,\"CardState\":\"Activ\",\"Deleted\":false,\"Sold\":0.000,\"StartDate\":\"\/Date(1412974800000+0300)\/\",\"InvoiceStartDate\":\"\/Date(-62135596800000+0200)\/\",\"Quantity\":null,\"Value\":0.0,\"CardTypeID\":1,\"CardType\":\"Credit\",\"SoldChanged\":false,\"DriverName\":\"\",\"VehiclePlateNumber\":\"B 222 ART\",\"VehicleID\":null,\"Discount\":null,\"ContractID\":15,\"DiscountPerMonth\":null,\"ProductID\":null,\"ProductStateID\":null,\"Mail\":\"\",\"WithoutLimit\":true,\"ContractSold\":null,\"ContractLimit\":null,\"NumberOfTransactions\":null,\"DriverNameOnly\":null,\"DriverSurnameOnly\":null},{\"ID\":2881,\"CompanyID\":1155,\"CompanyName\":\"test\",\"FiscalCode\":null,\"Code\":\"test0000\",\"Limit\":125.000,\"StateID\":1,\"CardState\":\"Activ\",\"Deleted\":false,\"Sold\":132.330,\"StartDate\":\"\/Date(1436130000000+0300)\/\",\"InvoiceStartDate\":\"\/Date(-62135596800000+0200)\/\",\"Quantity\":null,\"Value\":0.0,\"CardTypeID\":1,\"CardType\":\"Credit\",\"SoldChanged\":false,\"DriverName\":\"aaa aaa\",\"VehiclePlateNumber\":\"aaa\",\"VehicleID\":null,\"Discount\":null,\"ContractID\":15,\"DiscountPerMonth\":null,\"ProductID\":null,\"ProductStateID\":null,\"Mail\":\"\",\"WithoutLimit\":true,\"ContractSold\":null,\"ContractLimit\":null,\"NumberOfTransactions\":null,\"DriverNameOnly\":null,\"DriverSurnameOnly\":null}]" }
Thanks in advance!
Try this:
try {
JSONObject jsonObject = null;
yourJSONString.replace("\\", "");
jsonObject = new JSONObject(yourJSONString);
String newJSONString = jsonObject.get("GetCardsResult").toString();
JSONArray jsonMainArr = new JSONArray(newJSONString);
//now just loop the json Array
for (int i = 0; i < jsonMainArr.length(); ++i) {
JSONObject rec = jsonMainArr.getJSONObject(i);
card.set_id(rec.get("ID").toString());
//....
}
} catch (JSONException e) {
e.printStackTrace();
}
Try to use GSON its very efficient and easy to implement, As example below will be your POJO class.
public class Post {
#SerializedName("id")
public long ID;
public String title;
public String author;
public String url;
#SerializedName("date")
public Date dateCreated;
public String body;
public List tags;
public Post() {
}
}
//Tag.java
public class Tag {
public String name;
public String url;
public Tag() {
}
}
And this will how you parse your JSON string to Object Class,
Reader reader = new InputStreamReader(content);
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("M/d/yy hh:mm a");
Gson gson = gsonBuilder.create();
List<Post> posts = new ArrayList<Post>();
posts = Arrays.asList(gson.fromJson(reader, Post[].class));
content.close();
What do you pass to the mapper - string before or after compiling the regular expression?
Did you try any external lib like Gson? Everything you need is just new Gson().fromJson(strResponse, new TypeToken<List<Card>>() {}.getType(););

parse json when value of one json becomes key of another json in java

I have two jsons like these
{
"clientId":"patientId",
"vendorId":"businessKey"
}
{
"patientId":"1234",
"businessKey":"abcd"
}
I have java POJOs created like these
public class Patient{
private String patientId;
private String businessKey;
public String getPatientId() {
return patientId;
}
public void setPatientId(String patientId) {
this.patientId = patientId;
}
public String getBusinessKey() {
return businessKey;
}
public void setBusinessKey(String businessKey) {
this.businessKey = businessKey;
}
}
public class Client {
private String clientId;
private String vendorId;
public String getClientId() {
return clientId;
}
public void setClientId(String clientId) {
this.clientId = clientId;
}
public String getVendorId() {
return vendorId;
}
public void setVendorId(String vendorId) {
this.vendorId = vendorId;
}
}
I am using Jackson's ObjectMapper to parse the JSON. What I want to achieve is first read the first JSON, get the value from that and then read the actual value from the second JSON.
Ex: I read the first JSON to getClientId - "patientId"
Then in the second JSON I should read getPatientId - 1234.
How do I achieve this programmatically. I dont want to clutter my code by adding lot many if else blocks. Is there any library that I could use?

Categories

Resources