Can not deserialize instance of Object out of START_ARRAY token - java

I have two object one is Dashboard and second is Room i have a json which is look like this
{
"hotel_id":"1",
"hotel_room":"200",
"hotel_properties":[{
"id":"1",
"room_type":"Single",
"rack_rate":"2000",
"publish_rate":"1800",
"discount":"10",
"availiable":"40",
"total":"50"
},
{
"id":"2",
"room_type":"Double",
"rack_rate":"4000",
"publish_rate":"3600",
"discount":"10",
"availiable":"45",
"total":"50"
}
]
}
And the Object is
public class DashBoard {
private int hotel_id;
private int hotel_room;
#JsonProperty("hotel_properties")
private Room hotel_properties;
}
There is another Object Room which is look like this
public class Room {
private Long id;
private String room_type;
private String rack_rate;
private String publish_rate;
private String discount;
private String availiable;
private String total;
}
I am Hide all constructor,setter and getter for Stackoverflow but it is in my code
i want parse Json to Object using ObjectMapper from an URL using this code
JsonReader jsonReader = new JsonReader();
ObjectMapper mapper = new ObjectMapper();
try {
JSONObject json = jsonReader.readJsonFromUrl("http://localhost/quinchy/json/dashboard.json");
DashBoard dsh = mapper.readValue(json.toString(), DashBoard.class);
System.out.println(json.toString());
} catch (IOException | JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
but i get this error
org.codehaus.jackson.map.JsonMappingException: Can not deserialize instance of Object out of START_ARRAY token
please help me out from this

From the JSON String you posted, it looks like there is a list of Room objects. But you have used a single object.
In your DashBoard class, try changing:
private Room hotel_properties;
to:
private List<Room> hotel_properties;

Related

How to Parse Get Request Response to get All key and Value pairs?

I was able to pull data from an api using my get request method
{"vulnerabilities":[{"id":5027994,"status":"open","closed_at":null,"created_at":"2019-06-07T06:10:15Z","due_date":null,"notes":null,"port":[],"priority":null,"identifiers":["adobe-reader-apsb09-15-cve-2009-2990"],"last_seen_time":"2019-07-24T05:00:00.000Z","fix_id":4953,"scanner_vulnerabilities":[{"port":null,"external_unique_id":"adobe-reader-apsb09-15-cve-2009-2990","open":true}],"asset_id":119920,"connectors":[{"name":"Nexpose Enterprise","id":7,"connector_definition_name":"Nexpose Enterprise","vendor":"R7"}],"service_ticket":null,"urls":{"asset":"dummy.com"},"patch":true,"patch_published_at":"2009-10-08T22:40:52.000Z","cve_id":"CVE-2009-2990","cve_description":"Array index error in Adobe Reader and Acrobat 9.x before 9.2, 8.x before 8.1.7, and possibly 7.x through 7.1.4 might allow attackers to execute arbitrary code via unspecified vectors.","cve_published_at":"2009-10-19T22:30:00.000Z","description":null,"solution":null,"wasc_id":null,"severity":9,"threat":9,"popular_target":false,"active_internet_breach":true,"easily_exploitable":true,"malware_exploitable":true,"predicted_exploitable":false,"custom_fields":[],"first_found_on":"2019-06-05T05:22:23Z","top_priority":true,"risk_meter_score":100,"closed":false}
the problem I have encountered is to parse this json data by separating it by colon and comma?
I have created a parser method show below:
public static TableRow parseRequest(String request, TableRow row) {
JsonParser parser= new JsonParser();
try {
Object object = parser.parse(request);
//throws an ClassCastException JsonObject jsonObject = (JsonObject) object;
JsonArray array = (JsonArray) object;
for (Iterator iterator = jsonObject.keySet().iterator(); iterator.hasNext(); ) {
String keyString = (String) iterator.next();
System.out.println("iterator" + iterator);
System.out.println(jsonObject.get(keyString));
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
return parserequesTableRow(row);
}
The results that I get is java.lang.ClassCastException. I am very new to Json so I would like to know if there is a better method than the one I am implementing?
I would advise to use jackson library for this. Jackson is a library for parsing json string to java class. You can also generate a json from a java class. See here for more info and how to use it: https://www.baeldung.com/jackson-object-mapper-tutorial
Here is an example how you can set it up. First create a java pojo which should be equal to your response json:
#JsonInclude(NON_NULL)
class Response {
private List<Vulnerability> vulnerabilities;
// getters and setters
}
#JsonInclude(NON_NULL)
class Vulnerability {
private String id;
private String status;
private String closed_at;
private String created_at;
private String due_date;
private String notes;
private String[] port;
private String priority;
// etc for other class members
// getters and setters
}
And here is your parsing logic:
public static void main(String[] args) throws IOException {
String json = ""; //put here your data which you got from your get request
ObjectMapper objectMapper = new ObjectMapper();
Response response = objectMapper.readValue(json, Response.class);
}

Deserialize JSON object from MongoDB to Java object on GET request

I have some nested classes in Java, simplified here. Getters and setters exist.
Example
public class Planet {
#JsonProperty("name")
private String name;
#JsonProperty("moons")
private List<Moon> moons;
}
public class Moon {
#JsonProperty("moonname")
private String name;
#JsonProperty("craters")
private int craters;
}
I want to be able to deserialize the records on mongo (following this same structure) to java objects on the rest controller, specifically the HTTP GET request.
#RestController
#RequestMapping("/planets")
public class PlanetController {
#Autowired
private PlanetService planetService;
#RequestMapping("/")
public List<Planet> getAllPlanets() {
//Need to deserialize here
return planetService.getAll();
}
#RequestMapping("/{name}")
public Planet getItemsWithName(#PathVariable("name") String name) {
//deserialize here
return planetService.getEntryWithName(name.toLowerCase());
}
PlanetService.getAll() is expecting return type of List. getEntryWithName() is expecting return type of Planet.
How can I loop the results in the getAll() so I can deserialize them before they are returned?
Using Jackson's object mapper, I can do the serialization of a Java object to a JSON object.
ObjectMapper mapper = new ObjectMapper();
try {
mapper.writeValue(new File("target/mars.json"), mars);
} catch (IOException e) {
e.printStackTrace();
}
I can probably use readValue for the opposite process but I don't know how to loop the results.
I will appreciate the help. Let me know if something is not clear.
public List<Planet> getAllPlanets() {
List<Planet> planets = planetService.getAll();
String jsonString = new ObjectMapper().writeValueAsString(planets);
return planets;
}

How to get value from Json file

I am retrieving an Json from an API. The problem is that I don't have any idea on how to convert Json format to a format maybe a java class so that it can be used by me to get the intended values.
This is my sample Json format
{
"par_a":".....",
"par_b": [ {
"b1":".....",
"b2":".....",
"b3":".....",
"b4":".....",
"b5":".....",
"b6":".....",
"b7":".....",
"b8":".....",
"b9":".....",
"b10": { "b10-1":".....", "b10-2":".....", "b10-3":"....." } ,
"b11": { "b11-1": ["....." ], "b11-2": ["....." ] } ,
"b13":"......."
} ]
}
I do not have an option to contact the owner of the API and understand how this works and hence any help would be really grateful.
I have seen many posts online but I have nowhere seen a Json format as mine hence no solution has worked for me.
A nice workaround would be to create a Model corresponding to the response you're receiving from the server and using GSON library you can easily deserialize the json to your model.
Your model will be something like this:
public class MyResponseModel {
#SerializedName("par_a")
private String parameterA;
#SerializedName("par_b")
private List<AnotherModel> parametersB;
/.../
}
If you get the data from your json file and it store in your project then
your solution is here.
Gson gson = new Gson();
String customRatioResponse = LocalUtils.loadJSONFromAsset(getActivity(), "custom_ratio.json"); // here custom_ratio.json is my json file. it's store in assets folder of project
CustomRatioList getSampleImageResponse = gson.fromJson(customRatioResponse, CustomRatioList.class); // here CustormRatioList is my POJO file
Log.i(TAG, "getAllCategory() -> Offline list size: " + (getSampleImageResponse.getCustomRatio() != null ? getSampleImageResponse.getCustomRatio().size() : 0));
return getSampleImageResponse.getCustomRatio();
Here, If your Json file having too much data or list of data then it gives you arrayList type of data.
LocalUtils.java
public class LocalUtils {
public static String loadJSONFromAsset(Context context, String jsonFilePath) {
String json = null;
try {
InputStream is = context.getAssets().open(jsonFilePath);
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (Throwable e) {
e.printStackTrace();
return "";
}
return json;
}
}
If will you get pojo of your json then go to http://www.jsonschema2pojo.org/ paste your sample data json and get pojo structure. Thank you for read.
You have an excellent library doing that, Use GSON lib. You just have to create an object representing your Json File, and when you will decode it, it will feel your object with your json datas !
Use this way
public String loadJSONFromAsset() {
String json = null;
try {
InputStream is = getActivity().getAssets().open("filename.json");
int size = is.available();
byte[] buffer = new byte[size];
is.read(buffer);
is.close();
json = new String(buffer, "UTF-8");
} catch (IOException ex) {
ex.printStackTrace();
return null;
}
return json;
}
and then parse the json
JSONObject obj = new JSONObject(loadJSONFromAsset());
Install DTO generator plug in for android studio ("this will be useful for future works too"). : File -> settings -> plugins -> search for DTO and install
Create a simple class say DataRetriever. Place cursor in that class and press Alt+insert -> select DTO from JSON
Enter obtained JSON in the window and press generate. This will make your class Gson with all attributes in Json. Create getter and setter for attributes. Result will be like
public class DataRetriever {
#Expose
#SerializedName("par_b")
private List<Par_bEntity> mPar_b;
#Expose
#SerializedName("par_a")
private String mPar_a;
public List<Par_bEntity> getmPar_b() {
return mPar_b;
}
public void setmPar_b(List<Par_bEntity> mPar_b) {
this.mPar_b = mPar_b;
}
public String getmPar_a() {
return mPar_a;
}
public void setmPar_a(String mPar_a) {
this.mPar_a = mPar_a;
}
/**
* Similar to these getter and setter, you can add getter and setter for sub
classes also
*/
}
class Par_bEntity {
#Expose
#SerializedName("b13")
private String mB13;
#Expose
#SerializedName("b11")
private B11Entity mB11;
#Expose
#SerializedName("b10")
private B10Entity mB10;
#Expose
#SerializedName("b9")
private String mB9;
#Expose
#SerializedName("b8")
private String mB8;
#Expose
#SerializedName("b7")
private String mB7;
#Expose
#SerializedName("b6")
private String mB6;
#Expose
#SerializedName("b5")
private String mB5;
#Expose
#SerializedName("b4")
private String mB4;
#Expose
#SerializedName("b3")
private String mB3;
#Expose
#SerializedName("b2")
private String mB2;
#Expose
#SerializedName("b1")
private String mB1;
}
class B10Entity {
#Expose
#SerializedName("b10-3")
private String b10_3;
#Expose
#SerializedName("b10-2")
private String b10_2;
#Expose
#SerializedName("b10-1")
private String b10_1;
}
class B11Entity {
#Expose
#SerializedName("b11-2")
private List<String> b11_2;
#Expose
#SerializedName("b11-1")
private List<String> b11_1;
}
At the place where you obtain json string get values to DataRetriever class by calling
DataRetriever mDataRetriever = new Gson().fromJson(jsonString, DataRetriever.class);
Using mDataRetriever object and getter methods you can retrieve value using
Ex : mDataRetriever.getmPar_a()for value “par_a”
Suppose you are trying to find the string value for b10-1 :
The code will be like below:
String json = "{par_a:.....,par_b: [ {b1:.....,b2:.....,b3:.....,b4:.....,b5:.....,b6:.....,b7:.....,b8:.....,b9:.....,b10: { b10-1:....., b10-2:....., b10-3:..... } ,b11: { b11-1: [..... ], b11-2: [..... ] } , b13:.......} ]}";
try{
String result = new JSONObject(json).getJSONArray("par_b").getJSONObject(0).getJSONObject("b_10").getString("b10-1");
}catch(Exception e){
}

How to get and ignore specific field in JSON

Game class:
public class Game {
private String name;
private int steam_appid;
private boolean isInstalled;
}
Json example: https://store.steampowered.com/api/appdetails/?appids=435150&filters=basic
My attempt:
public static Game readJson(String gameID) throws IOException {
String targetURL = String.format(STEAM_API, gameID);
URL url = new URL(targetURL);
InputStreamReader reader = new InputStreamReader(url.openStream());
Gson gson = new Gson();
Game json = gson.fromJson(reader, Game.class);
return json;
}
When I tried to print the output, I get Name:null steam_appid:0 isInstalled:false
I want to check the key success first, if value is true parse it to Game. Otherwise, do nothing.
How can I parse the Json to my Game?
If a field is marked transient, (by default) it is ignored and not included in the JSON serialization or deserialization.
https://sites.google.com/site/gson/gson-user-guide#TOC-Finer-Points-with-Objects
use below code if you don't want to include name in json:
public class Game
{
private transient String name;
private int steam_appid;
private boolean isInstalled;
}
Option 1:
Ignore Field at the Field Level
public class Game {
private String name;
#JsonIgnore
private int steam_appid;
private boolean isInstalled;
}
We can also ignore a field directly via the #JsonIgnore annotation directly on the field:
Option 2:
In another way you can use #JsonIgnoreProperties annotation to skip pojo properties. Here is the code snippet: You can use either way.
#JsonIgnoreProperties({ "name", "steam_appid" })
public class Game {
private String name;
private int steam_appid;
private boolean isInstalled;
}
Based on the response example the class to use Gson should look like this:
Note the classes need the getters and setters to be added.
class SteamResponseWrapper{
#SerializedName("434150")
private SteamResponse steamResponse;
}
class SteamResponse{
boolean success;
GameData data;
}
class GameData {
String name;
int steam_appid;
// I couldn't find the isInstalled property if you are adding it, make it transient
}
With this structure you would call:
SteamResponseWrapper wrapper = new Gson().fromJson(reader, SteamResponseWrapper.class)
and then
wrapper.getSteamResponse().isSuccess()
to check the success field.
And
wrapper.getSteamResponse().getData()
to access the game object.
But the problem I see is that the top object name is in fact data and will change for every game. So I don't think Gson will be able to handle this because for every request the annotated serialized name should be different.
I think you will be better of handling it with Jackson or as a JsonObject.
EDIT I
This example uses these maven dependencies:
<dependency>
<groupId>javax.json</groupId>
<artifactId>javax.json-api</artifactId>
<version>1.0</version>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.json</artifactId>
<version>1.0.4</version>
</dependency>
The example:
public class SteamApiReader {
private static final String STEAM_API = "http:// ......";
public static void main(String args[]) {
try {
SteamApiReader.readJson("435150");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Game readJson(String gameID) throws IOException {
Game rtn = null;
String targetURL = String.format(STEAM_API, gameID);;
URL url = new URL(targetURL);
InputStreamReader reader = new InputStreamReader(url.openStream());
JsonReader jsonReader = Json.createReader(reader);
JsonStructure jsonStructure = jsonReader.read();
JsonObject jsonObject = (JsonObject) jsonStructure;
JsonObject wrapper = jsonObject.getJsonObject(gameID);
boolean success = wrapper.getBoolean("success");
if(success) {
JsonObject data = wrapper.getJsonObject("data");
String name = data.getString("name");
int steamAppId = data.getInt("steam_appid");
rtn = new Game(name, steamAppId);
}
return rtn;
}
public static class Game{
public Game(String name, int steamAppId) {
this.name = name;
this.steamAppId = steamAppId;
}
String name;
int steamAppId;
}
}

How to Convert JSON to JAVA Object using ObjectMapper?

Java Object
class B {
private String attr;
/***** getters and setters *****/
}
class A {
private String attr1;
private String attr2;
private Map<String,B> attr3;
/***** getters and setters *****/
}
Json Object
json = {attr1 :"val1", attr2 : "val2", attr3 : {attr : "val"}}
How to convert json to java Object (class java contain Map as type of attribute) ?
You can use Jackson to do that:
//Create mapper instance
ObjectMapper mapper = new ObjectMapper();
//Usea a JSON string (exists other methos, i.e. you can get the JSON from a file)
String jsonString= "{'name' : 'test'}";
//JSON from String to Object
MyClass result= mapper.readValue(jsonString, MyClass .class);
You can use Gson library as following:
// representation string for your Json object
String json = "{\"attr1\": \"val1\",\"attr2\": \"val2\",\"attr3\": {\"attr\": \"val\"}}";
Gson gson = new Gson();
A a = gson.fromJson(json, A.class);
Create a model/POJO which resembles your json structure and then by putting json string in json file you can get java object by using below simple code by using JACKSON dependacy
ObjectMapper mapper = new ObjectMapper();
File inRulesFile = (new ClassPathResource(rulesFileName + ".json")).getFile();
List<Rule> rules = mapper.readValue(inRulesFile, new TypeReference<List<Rule>>() {
});
#RunWith(SpringRunner.class)
#SpringBootTest
class PostSaveServiceTest {
private static final String PATH_TO_JSON = "classpath:json/post-save";
private static final String EXTENSION_JSON = ".json";
#Test
void setData() {
ObjectMapper objectMapper = new ObjectMapper();
Post post = runParseJsonFile(objectMapper);
System.out.println(post);
}
private Post runParseJsonFile(ObjectMapper objectMapper) {
File pathToFileJson = getPathToFileJson(PATH_TO_JSON + EXTENSION_JSON);
Post post = null;
try {
post = objectMapper.readValue(pathToFileJson, Post.class);
} catch (IOException e) {
System.out.println("File didn't found : " + e);
}
return post;
}
private File getPathToFileJson(String path) {
File pathToJson = null;
try {
pathToJson = ResourceUtils.getFile(path);
} catch (IOException e) {
e.printStackTrace();
}
return pathToJson;
}
}

Categories

Resources