Exception in JSON parsing: Expected BEGIN_ARRAY but was BEGIN_OBJECT? - java

I am trying to parse the JSON response from this link and I'm getting this exception:
Expected BEGIN_ARRAY but was BEGIN_OBJECT
I have created this class to encapsulate the JSON data:
public class PlacesTextSearch {
private String icon;
private String name;
private String types;
private String formatted_address;
private double latitude;
private double longitude;
private String id;
public PlacesTextSearch(String icon,String name,String types,String formatted_address,double latitude,double longitude) {
// TODO Auto-generated constructor stub
setIcon(icon);
setName(name);
setTypes(types);
setFormatted_address(formatted_address);
setLatitude(latitude);
setLongitude(longitude);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTypes() {
return types;
}
public void setTypes(String types) {
this.types = types;
}
public String getFormatted_address() {
return formatted_address;
}
public void setFormatted_address(String formatted_address) {
this.formatted_address = formatted_address;
}
public Double getLatitude() {
return latitude;
}
public void setLatitude(Double latitude) {
this.latitude = latitude;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
}
And this is my code to parse the JSON:
private ArrayList<PlacesTextSearch> arrayListPlaces;
Type listType = new TypeToken<ArrayList<PlacesTextSearch>>(){}.getType();
arrayListPlaces=new Gson().fromJson(response,listType);
Here you can see the complete exception stacktrace:

Have you read Gson documentation before trying to write your code? Have you even taken a look at JSON structures?
Your code has many errors... The point is that you have to create a Java class structure that matches your JSON structure. And in fact, your class structure is not even similar to the JSON you want to parse! Basically where there's an object { } in your JSON you have to use a class, and where there's an array in your JSON [ ] you have to use an array or a List...
According to your PlacesTextSearch class, I guess the JSON piece you want to parse is:
{
...,
"results" : [
{
"formatted_address" : "Zeytinlik Mh., Bakırköy/İstanbul, Türkiye",
"geometry" : {
"location" : {
"lat" : 40.9790040,
"lng" : 28.8730110
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "e520b6e19bae5c014470989f9d3405e55dce5155",
"name" : "PTT",
"types" : [ "post_office", "finance", "establishment" ]
...
},
...
],
...
}
So, how do you pretend to parse this into an ArrayList<PlacesTextSearch>!? That's not what your JSON represents! Do you really not see it?
Try something like this class structure (pseudo-code):
class Response
List<PlacesTextSearch> results;
class PlacesTextSearch
String formatted_address;
Geometry geometry;
String icon;
String id;
String name;
List<String> types;
class Geometry
Location location;
class Location
long lat;
long lng;
And parse it with:
Response response = new Gson().fromJson(response, Response.class);

Related

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $

Ok, So I read a couple other questions with this same error, but none have been answered as working, and doesnt seem like I can get it working.
I am connecting to google in-app billing and have everything set up, but, when I try to pull my skudetails (I have 2 SKUs there now), I get the error -
Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
I have a SubscriptionActivity, Result (serializable), and Details model class (serializable). Below is the code, any help will be great, thanks-
From subscriptionactivity:
Gson gson = new Gson();
try {
Result result = gson.fromJson(skuDetailsList.toString(), Result.class);
if (result != null) {
for (Details d : result.getDetails()) {
System.out.println(d.getProductId()
+ " \n " + d.getTitle() + " \n " + d.getDescription() + " \n "
+ d.getPrice());
}
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
From details model:
public class Details implements Serializable{
#SerializedName("productId")
#Expose
private String productId;
#SerializedName("type")
#Expose
private String type;
#SerializedName("price")
#Expose
private String price;
#SerializedName("price_amount_micros")
#Expose
private Integer priceAmountMicros;
#SerializedName("price_currency_code")
#Expose
private String priceCurrencyCode;
#SerializedName("subscriptionPeriod")
#Expose
private String subscriptionPeriod;
#SerializedName("freeTrialPeriod")
#Expose
private String freeTrialPeriod;
#SerializedName("title")
#Expose
private String title;
#SerializedName("description")
#Expose
private String description;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public Integer getPriceAmountMicros() {
return priceAmountMicros;
}
public void setPriceAmountMicros(Integer priceAmountMicros) {
this.priceAmountMicros = priceAmountMicros;
}
public String getPriceCurrencyCode() {
return priceCurrencyCode;
}
public void setPriceCurrencyCode(String priceCurrencyCode) {
this.priceCurrencyCode = priceCurrencyCode;
}
public String getSubscriptionPeriod() {
return subscriptionPeriod;
}
public void setSubscriptionPeriod(String subscriptionPeriod) {
this.subscriptionPeriod = subscriptionPeriod;
}
public String getFreeTrialPeriod() {
return freeTrialPeriod;
}
public void setFreeTrialPeriod(String freeTrialPeriod) {
this.freeTrialPeriod = freeTrialPeriod;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
From Result activity:
public class Result implements Serializable{
#SerializedName("SkuDetails")
#Expose
private ArrayList<Details> details = new ArrayList<Details>();
/**
*
* #return The SkuDetails
*/
public ArrayList<Details> getDetails() {
return details;
}
/**
*
* #param details
* The details
*/
public void setDetails(ArrayList<Details> details) {
this.details = details;
}
}*
Oh..and the response I was trying to parse (skuDetailsList.toString()) is:
[
SkuDetails: {
"productId": "basic_sub",
"type": "subs",
"price": "$0.99",
"price_amount_micros": 990000,
"price_currency_code": "USD",
"subscriptionPeriod": "P1M",
"freeTrialPeriod": "P4W2D",
"title": "Basic Subscription Service (DadBod Recipes)",
"description": "Basic Subscription Service for DadBodRecipes"
},
SkuDetails: {
"productId": "enterprise_sub",
"type": "subs",
"price": "$2.99",
"price_amount_micros": 2990000,
"price_currency_code": "USD",
"subscriptionPeriod": "P1M",
"freeTrialPeriod": "P4W2D",
"title": "Enterprise Subscription Service (DadBod Recipes)",
"description": "Enterprise Subscription Service for DadBodRecipes"
}
]
Issue is because, the result you're getting is as <Key-Value> pair (not as JSON object/Array, but similar to it).
So you'll need to make it to JSONObject first and then parse it using Gson like below:
Map<String, String> params = skuDetailsList;
JSONObject object = new JSONObject(params);
Result result = gson.fromJson(object.toString(), Result.class);
Do like this, hope it helps !
You are trying to parse your json
[
as
{
when you see the [ it represents a list
when you see the { it represents an object.
I'm pretty sure you know that as you built a wrapper class, but your wrapper class is also an object, not an array.
So your choices are to have your wrapper class extend ArrayList or some form of List.
Or
Tell your Json converter that the base is an Array and you want the first object in the list is an object of your type.

Why are my properties unrecognizable when converting to pojo [duplicate]

This question already has answers here:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field
(7 answers)
Closed 5 years ago.
I have the following JSON:
{ "_id" : "3", "longitude" : "3222", "latitude" : "55", "timeDateOfUsage" : ["02/11/17 13:30:35", "1", "02/11/17 13:30:45", "1", "02/11/17 13:30:51", "0"] }
I'm trying to convert it to a pojo using jackson. This is what I have:
String inputJson = "{ \"_id\" : \"3\", \"longitude\" : \"3222\",
\"latitude\" : \"55\", \"timeDateOfUsage\" : [\"02/11/17 13:30:35\", \"1\", \"02/11/17 13:30:45\", \"1\", \"02/11/17 13:30:51\", \"0\"] }";
ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
try{
dbResponseonce response = mapper.readValue(inputJson,dbResponseonce.class);
System.out.println(response.getLatitude());
} catch (JsonParseException e) {
e.printStackTrace();
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
And my other class has fields which are named as the elements in the JSON and has getters and setters.
The above code works however it does not work when I just create a basic ObjectMapper object with no configurations. Why is this? This is the stacktrace error:
org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "_id" (Class dbResponseonce), not marked as ignorable
This is my pojo class that has the getters and setters:
public class dbResponseonce {
private String _id;
public String getId() { return this._id; }
public void setId(String _id) { this._id = _id; }
private String longitude;
public String getLongitude() { return this.longitude; }
public void setLongitude(String longitude) { this.longitude = longitude; }
private String latitude;
public String getLatitude() { return this.latitude; }
public void setLatitude(String latitude) { this.latitude = latitude; }
private ArrayList<String> timeDateOfUsage;
public ArrayList<String> getTimeDateOfUsage() { return this.timeDateOfUsage; }
public void setTimeDateOfUsage(ArrayList<String> timeDateOfUsage) { this.timeDateOfUsage = timeDateOfUsage; }}
Your getter and setter for _id is incorrect.
Try defining them as follows:
public String get_id() {
return _id;
}
public void set_id(String _id) {
this._id = _id;
}
Or use on the getter or setter of _id #JsonProperty("_id")

how to access to json with java

I have in a rest response this json:
{
"TRANS": {
"HPAY": [
{
"ID": "1234",
"DATE": "10/09/2011 18:09:27",
"REC": "wallet Ricaricato",
"COM": "Tasso Commissione",
"MSG": "Commento White Brand",
"STATUS": "3",
"EXTRA": {
"IS3DS": "0",
"CTRY": "FRA",
"AUTH": "455622"
},
"INT_MSG": "05-00-05 ERR_PSP_REFUSED",
"MLABEL": "IBAN",
"TYPE": "1"
}
]
}
}
I have made pojo class to map this json in java.
public class Trans {
private List<Hpay> hpay;
public Trans(){
}
//getter and setter
}
public class Hpay {
private String id;
private String date;
private String com;
private String msg;
private String status;
private List<Extra> extra;
private String int_msg;
private String mlabel;
private String type;
public Hpay(){
}
//getter and setter
}
I try to map the object with Gson library.
Gson gson=new Gson();
Trans transaction=gson.fromJson(response.toString(), Trans.class);
If i call hpay method on transaction i have null..i don't know why...
I have deleted previous answer and add new one as par your requirement
JSON String :
{
"TRANS": {
"HPAY": [{
"ID": "1234",
"DATE": "10/09/2011 18:09:27",
"REC": "wallet Ricaricato",
"COM": "Tasso Commissione",
"MSG": "Commento White Brand",
"STATUS": "3",
"EXTRA": {
"IS3DS": "0",
"CTRY": "FRA",
"AUTH": "455622"
},
"INT_MSG": "05-00-05 ERR_PSP_REFUSED",
"MLABEL": "IBAN",
"TYPE": "1"
}
]
}
}
Java Objects : (Here Extra is not list)
public class MyObject {
#SerializedName("TRANS")
#Expose
private Trans trans;
public Trans getTRANS() {return trans;}
public void setTRANS(Trans trans) {this.trans = trans;}
}
public class Trans {
#SerializedName("HPAY")
#Expose
private List<HPay> hPay;
public List<HPay> getHPAY() {return hPay;}
public void setHPAY(List<HPay> hPay) {this.hPay = hPay;}
}
public class HPay {
#SerializedName("ID")
#Expose
private String id;
#SerializedName("DATE")
#Expose
private String date;
#SerializedName("REC")
#Expose
private String rec;
#SerializedName("COM")
#Expose
private String com;
#SerializedName("MSG")
#Expose
private String msg;
#SerializedName("STATUS")
#Expose
private String status;
#SerializedName("EXTRA")
#Expose
private Extra extra;
#SerializedName("INT_MSG")
#Expose
private String intMsg;
#SerializedName("MLABEL")
#Expose
private String mLabel;
#SerializedName("TYPE")
#Expose
private String type;
public String getID() {return id;}
public void setID(String id) {this.id = id;}
public String getDATE() {return date;}
public void setDATE(String date) {this.date = date;}
public String getREC() {return rec;}
public void setREC(String rec) {this.rec = rec;}
public String getCOM() {return com;}
public void setCOM(String com) {this.com = com;}
public String getMSG() {return msg;}
public void setMSG(String msg) {this.msg = msg;}
public String getSTATUS() {return status;}
public void setSTATUS(String status) {this.status = status;}
public Extra getEXTRA() {return extra;}
public void setEXTRA(Extra extra) {this.extra = extra;}
public String getINTMSG() {return intMsg;}
public void setINTMSG(String intMsg) {this.intMsg = intMsg;}
public String getMLABEL() {return mLabel;}
public void setMLABEL(String mLabel) {this.mLabel = mLabel;}
public String getTYPE() {return type;}
public void setTYPE(String type) {this.type = type;}
}
public class Extra {
#SerializedName("IS3DS")
#Expose
private String is3ds;
#SerializedName("CTRY")
#Expose
private String ctry;
#SerializedName("AUTH")
#Expose
private String auth;
public String getIS3DS() { return is3ds; }
public void setIS3DS(String is3ds) { this.is3ds = is3ds; }
public String getCTRY() { return ctry; }
public void setCTRY(String ctry) { this.ctry = ctry; }
public String getAUTH() { return auth; }
public void setAUTH(String auth) { this.auth = auth; }
}
Conversion Logic :
import com.google.gson.Gson;
public class NewClass {
public static void main(String[] args) {
Gson g = new Gson();
g.fromJson(json, MyObject.class);
}
static String json = "{ \"TRANS\": { \"HPAY\": [{ \"ID\": \"1234\", \"DATE\": \"10/09/2011 18:09:27\", \"REC\": \"wallet Ricaricato\", \"COM\": \"Tasso Commissione\", \"MSG\": \"Commento White Brand\", \"STATUS\": \"3\", \"EXTRA\": { \"IS3DS\": \"0\", \"CTRY\": \"FRA\", \"AUTH\": \"455622\" }, \"INT_MSG\": \"05-00-05 ERR_PSP_REFUSED\", \"MLABEL\": \"IBAN\", \"TYPE\": \"1\" } ] } }";
}
Here I use Google Gosn lib for conversion.
And need to import bellow classes for annotation
com.google.gson.annotations.Expose;
com.google.gson.annotations.SerializedName;
First parse the json data using json.simple and then set the values using setters
Object obj = parser.parse(new FileReader( "file.json" ));
JSONObject jsonObject = (JSONObject) obj;
JSONArray hpayObj= (JSONArray) jsonObject.get("HPAY");
//get the first element of array
JSONObject details= hpayObj.getJSONArray(0);
String id = (String)details.get("ID");
//set the value of the id field in the setter of class Trans
new Trans().setId(id);
new Trans().setDate((String)details.get("DATE"));
new Trans().setRec((String)details.get("REC"));
and so on..
//get the second array element
JSONObject intMsgObj= hpayObj.getJSONArray(1);
new Trans().setIntmsg((String)details.get("INT_MSG"));
//get the third array element
JSONObject mlabelObj= hpayObj.getJSONArray(2);
new Trans().setMlabel((String)details.get("MLABEL"));
JSONObject typeObj= hpayObj.getJSONArray(3);
new Trans().setType((String)details.get("TYPE"));
Now you can get the values using your getter methods.

JSON - Error on putting a JSON string inside a JSON object

I have a web-service in Java with Jersey to create and edit prices of a market. To do that, I send a JSON object containing the market informations, including another JSON object for the prices.
For example, this is the JSON I'm posting through Postman:
{
"name": "Market 01",
"address": "Market 01 street",
"prices": "{\"watermelon\": \"5.40\", \"melon\": \"2.55\"}"
}
On the web-server side, I try to create a list of the prices using GSON, but I can't get it to work. My objective here is to check on the difference between the new prices and the current prices. Below, there is my POJO Price.java, what I'm trying to do on the Controller for the edit and the Exception I'm geting on Postman:
POJO - Price.java
public class Price {
private String nome;
private Double preco;
//Getters and setters also
}
MarketController.java
Collection<Price> prices = gson.fromJson(json, new TypeToken<List<Price>>(){}.getType());
Exception raised on MarketController.java:
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
EDIT: The solution that worked for me based on #A2H response:
POJO class - Price.java
public class Price {
private String name;
private Double price;
...
#Override
public String toString() {
return "{\"name\":\"" + name + "\", \"price\":" + price + "}";
}
}
POJO class - Market.java
public class Market{
...
//Include as a List<Price>
private List<Price> prices;
...
}
MarketController.java
// When going from List<Price> to JSON String
String prices = gson.toJson(market.getPrices());
// When going from JSON String to List<Price>
List<Price> prices = gson.fromJson(jsonString, new TypeToken<List<Price>>(){}.getType());
This code is well rounded for this situation, where you need to transform from List to JSON String and vice-versa.
Your POJO implies that you should have an array of prices in your JSON object.
Here's a full working example.
package test;
import java.util.List;
import com.google.gson.Gson;
public class TESTTEST {
public class MarketInfo {
String name;
String address;
List<Price> prices;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Price> getPrices() {
return prices;
}
public void setPrices(List<Price> prices) {
this.prices = prices;
}
}
public class Price {
String nome;
Double preco;
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
public Double getPreco() {
return preco;
}
public void setPreco(Double preco) {
this.preco = preco;
}
#Override
public String toString() {
return "{\"nome\":\"" + nome + "\", \"preco\":" + preco + "}";
}
}
public static void main(String[] args) {
Gson gson = new Gson();
String jsonString = "{\"name\": \"Market 01\",\"address\": \"Market 01 street\","
+ "\"prices\": [{\"nome\":\"watermelon\",\"preco\":\"5.40\"}, {\"nome\":\"melon\",\"preco\": \"2.55\"}]}";
MarketInfo res = gson.fromJson(jsonString, MarketInfo.class);
System.out.println(res.getPrices());
}
}
That's because a List would be represented by a JSON array, not by an object as you provide. You can try to deserialize to a map (or, send an array).

Using GSON giving error expected BEGIN_ARRAY but was STRING

An example JSON object is shown below:
[{"Title":"John Doe","Address":{"AddressLines":["The Place","123 New Place","London","England"],"Postcode":"NW7 XXY"},"Telephone":"0012345","Email":"","Latitude":51.5024472101345,"Longitude":-0.557585646554,"Easting":500623,"Northing":179647}]
Suppose the above object is accessed via the link www.domain.com and I have the following class to represent the data
public class LocationData extends Data{
private Address Address;
private String Telephone;
private String Email;
private String Latitude;
private String Longitude;
private String Easting;
private String Northing;
public Address getAddress() {
return Address;
}
public void setAddress(Address address) {
Address = address;
}
public String getTelephone() {
return Telephone;
}
public void setTelephone(String telephone) {
Telephone = telephone;
}
public String getEmail() {
return Email;
}
public void setEmail(String email) {
Email = email;
}
public String getLatitude() {
return Latitude;
}
public void setLatitude(String latitude) {
Latitude = latitude;
}
public String getLongitude() {
return Longitude;
}
public void setLongitude(String longitude) {
Longitude = longitude;
}
public String getEasting() {
return Easting;
}
public void setEasting(String easting) {
Easting = easting;
}
public String getNorthing() {
return Northing;
}
public void setNorthing(String northing) {
Northing = northing;
}
}
And the address class is as follows:
public class Address {
public String[] AddressLines;
public String Postcode;
public String getPostcode() {
return Postcode;
}
public void setPostcode(String postcode) {
Postcode = postcode;
}
public String[] getAddressLines() {
return AddressLines;
}
public void setAddressLines(String addressLines[]) {
AddressLines = addressLines;
}
}
When I try to run
LocationData[] data = gson.fromJson(this.locationServiceUrl, LocationData[].class);
return data;
I get the following error:
Expected BEGIN_ARRAY but was string at the above mentioned line of code. I am not sure if there is something wrong in the manner in which I have set up my classes. Note: I am using an array (LocationData[] data) because the service returns multiple locations although I have just included one in the example shown above. Any help as to why this is happening is much appreciated. I have looked at some of the similar errors on here but none of the fixes provided seem to work for me.
{
"finally":[
{
"Title":"John Doe",
"Address": {
"AddressLines":[
"The Place",
"123 New Place",
"London",
"England"
],
"Postcode":"NW7XXY"
},
"Telephone":"0012345",
"Email":"",
"Latitude":51.5024472101345,
"Longitude":-0.557585646554,
"Easting":500623,
"Northing":179647
}
]
}
and code to parse this JSON is :
public class mainData {
public List<LocationData> finally;
public String[] getLocationData() {
return AddressLines;
}
public void setLocationData(List<LocationData> finally) {
this.finally = finally;
}
}
it is because your string starting with [ when you parsing this type of Json with Gson then you need to prefix a label to it just i like did ( {"finally": your data }).
Actually Gson trying to map the label and its value but in your case your [ doesnt contain Label by which Gson can map.

Categories