GSON parsing of google places API - java

I need a little help with creating classes which will be filled with GSON parser.
This is the output od autocomplete Google Places API:
{
"predictions" : [
{
"reference" : "CjQtAA",
"terms" : [
{
"offset" : 0,
"value" : "Ladimirevci"
},
{
"offset" : 13,
"value" : "Hrvatska"
}
],
"types" : [ "locality", "political", "geocode" ]
},
{
"reference" : "CjQtAAA",
"terms" : [
{
"offset" : 0,
"value" : "Ladimirevci"
},
{
"offset" : 13,
"value" : "Hrvatska"
}
],
"types" : [ "locality", "political", "geocode" ]
}
],
"status" : "OK"
}
SOLUTION thanks to MikO
Classes are:
public class GPlacesAPIResults {
#SerializedName("predictions")
public List<GPlacesAPILocation> predictions;
#SerializedName("status")
public String status;
}
Second:
public class GPlacesAPILocation implements Serializable {
private static final long serialVersionUID = 4509808527882750586L;
#SerializedName("reference")
private String reference;
#SerializedName("terms")
private List<GPlacesAPIAddress> terms;
#SerializedName("types")
private List<String> types;
}
Third:
public class GPlacesAPIAddress implements Serializable {
private static final long serialVersionUID = -6916297127791361853L;
#SerializedName("value")
public String value;
}
In app I call it like this
InputStreamReader in = new InputStreamReader(conn.getInputStream()); //results from places api
GPlacesAPIResults lcs = new Gson().fromJson( in , GPlacesAPIResults.class);
Thank you for the effort :-)

Your Result class with an attribute locations doesn't make any sense... in fact I don't understand why you came up with that, since there's no locations element anywhere in your JSON!
Try something like this (following your particular notation):
Results
List<Locations> predictions;
String status;
Locations
String reference;
List <Addresses> terms;
Addresses
String value;

Related

How to deserialize list with dynamic number of keys with same value structure?

I am trying to find an optimal way to deserialize dynamic fields that all contain the same value object structure:
"data": {
"lastUpdate": 1605299294253,
"tableData": [
{
"recordId": 1,
"isSelected": 1,
"myKey1": {
"valueRef": 72,
"value": "Some value"
},
"myKey2": {
"valueRef": 0,
"value": "123"
}
}
]
}
For the tableData JSON array, I have tried this approach without success:
import lombok.Data;
import java.util.Map;
#Data
public class TableRowDataVO {
private Integer recordId;
private Integer recordStatus;
private Map<String, TableRowDetailVO> columnData1;
private Map<String, TableRowDetailVO> columnData2;
}
This class is nested into another class to encompass the entire JSON body in data:
public class TabularDataDTO {
private Long lastUpdate;
private List<TableRowDataVO> tableData;
}
and each dynamic field holds the same Object of the following type:
public class TableRowDetailVO {
private Integer valueRef;
private String value;
}
There is also no guarantee that there are only 2 dynamic keys. It can be 0 to many dynamic keys that are in TableRowDataVO, but if there are limitations that require me to settle with 2, I can do that, but if 0 to many dynamic fields are possible, that would be great. I am trying to use the ObjectMapper with TypeReference as TabularDataVO but it throws an exception. What is the proper way to design my objects such that TabularDataVO can be deserialized by the mapper?
since the key is dynamic so when you process data you need some special process.
#Data
public class NewDTO {
private Long lastUpdate;
private List<Map<String, Object>> tableData;
}
Just to understand your question correctly. You Json is like following: -
"data": {
"lastUpdate": 1605299294253,
"tableData": [
{
"recordId": 1,
"isSelected": 1,
"myKey1": {
"valueRef": 72,
"value": "Some value"
},
"myKey2": {
"valueRef": 0,
"value": "123"
}
}
]
}
Not like
"data": {
"lastUpdate": 1605299294253,
"tableData": [
{
"recordId": 1,
"isSelected": 1,
"keys": [
{
"valueRef": 72,
"value": "Some value"
},
{
"valueRef": 0,
"value": "123"
}
]
}
]
}
Latter can be easily deserialized using jackson library and defining keys as List<Map<String, Object>>

How to do 3 way filtering/Grouping on Java streams

I have a Java list representation like below
List representation of data
[
{ "type" : "Error", "name" : "xyz" },
{ "type" : "Success", "name" : "abc" },
{ "type" : "none", "name" : "prq" },
{ "type" : "Success", "name" : "" },
{ "type" : "Success", "name" : "xyz" },
{ "type" : "Warning", "name" : "efc" }
.
.
.
]
(Partial representation here).
and an Object representation below
public Node {
List<String> errorNames;
List<String> SuccessNames;
List<String> WarningNames;
}
I want to use Java streams to separate the three type of names based on their type and add each name to the respective Lists.
What will be the best way (Stream.filter/Collect/Map anything else) to split the list such that at the end "Node's->(all the lists)" will have corresponding data?
Assuming your Node class actually looks something like this:
public class Node {
private String type;
private String name;
public Node(String type, String name) {
this.type = type;
this.name = name;
}
public String getType() {
return type;
}
public String getName() {
return name;
}
}
You can use Collectors#groupingBy in combination with Collectors#mapping to create a Map<String, List<String>> where they key is the type and the value are the List of name for every Node of that type:
var nodes = List.of(
new Node("Error", "xyz"), new Node("Success", "abc"),
new Node("none", "prq"), new Node("Success", ""),
new Node("Success", "xyz"), new Node("Warning", "efc")
);
var map = nodes.stream()
.collect(Collectors.groupingBy(Node::getType,
Collectors.mapping(Node::getName, Collectors.toList())));
System.out.println(map);
Output:
{Warning=[efc], Error=[xyz], none=[prq], Success=[abc, , xyz]}

Json Request with POSTMAN

I have this class:
#Getter
#Setter
IntestatarioPrivacySospensiva {
private IntestatarioInput intestatario;
private List<DatiPrivacySospensiva> datiPrivacy;
private String sportelloRiferimento;
private String riferimento;
private String note;
private String accettazioneConsensoC1;
private String accettazioneConsensoC3;
}
I have to make a JSON request to map this object, I have made this but it is never seen as IntestatarioPrivacySospensiva object.
[
{
//this are intestatarioInput variable
"abi":"abi",
"cf":"cf",
"ndg":"ndg"
},
{//This are datiprivacy variable
"tipoConsenso":"tipoConsenso",
"consenso":"consenso"
},
{
"sportelloRiferimento":"sportelloRif",
"riferimento":"riferimento",
"note":"note",
"accettazioneConsensoC1":"true",
"accettazioneConsensoC3":"false"
}
]
My service have in the request ArrayList x; how i have to map it in json?
I'm using Postman to send JSON.
I believe this should work:
[{
"sportelloRiferimento":"sportelloRif",
"riferimento":"riferimento",
"note":"note",
"accettazioneConsensoC1":"true",
"accettazioneConsensoC3":"false",
"intestatario" : {
"abi":"abi",
"cf":"cf",
"ndg":"ndg"
},
"datiPrivacy" : [ {
"tipoConsenso":"tipoConsenso",
"consenso":"consenso"
} ]
},
{
"sportelloRiferimento":"sportelloRif",
"riferimento":"riferimento",
"note":"note",
"accettazioneConsensoC1":"true",
"accettazioneConsensoC3":"false",
"intestatario" : {
"abi":"abi",
"cf":"cf",
"ndg":"ndg"
},
"datiPrivacy" : [ {
"tipoConsenso":"tipoConsenso",
"consenso":"consenso"
} ]
}]
You can use Jackson 2.x to get JSON strings from your Java objects. Checkout the below example:
https://www.mkyong.com/java/jackson-2-convert-java-object-to-from-json/

Convert JSON from serializeArray() to Java class with GSON

I'm having a little trouble trying to convert a JSON string from a serialized HTML form to a Java class using Gson.
Here's the example JSON:
[
{ "name" : "ObjectClass", "value" : "Obama" },
{ "name" : "ObjectType", "value" : "Person" },
{ "name" : "Att_1_name", "value" : "Age" },
{ "name" : "Att_1_value", "value" : "52" },
{ "name" : "Att_2_name", "value" : "Race" },
{ "name" : "Att_2_name", "value" : "African American" }
]
As you can see, it passes an array, then each element of that array consists of a name and a value.
I'm somewhat lost on how to set up my Java class so that Gson can convert it. It should also be noted that the number of elements in the array is variable (there can be as many attributes as the user desires).
My (incorrect) attempt at the class was:
package com.test.objectclasses;
import java.util.ArrayList;
public class tempJSON {
ArrayList<innerJSON> inJSON;
public ArrayList<innerJSON> getInJSON() {
return inJSON;
}
public void setInJSON(ArrayList<innerJSON> inJSON) {
this.inJSON = inJSON;
}
public class innerJSON {
private String name;
private String value;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
}
Any idea how to approach this, or am I thinking about it all wrong? Thanks in advance.
First of all, follow Java naming conventions. Your class names should start with a capital letter. So upper camel case.
Get rid of your enclosing class, tempJSON and use a type token in the Gson#fromJson(..) to mark it as a List, since you have a JSON array.
List<innerJSON> innerJSONs = gson.fromJson(yourStream, new TypeToken<List<innerJSON>>(){}.getType());
Now the List will contain as many innerJSON objects as appear in your JSON.

Google places review, arraylist in jsonparser

I got a problem so I'm using the google places api.
I will not write the whole code here because it's too big. But this is what I get for resuls whenever I call the google api:
{
"html_attributions" : [],
"result" : {
"address_components" : [
{
"long_name" : "48",
"short_name" : "48",
"types" : [ "street_number" ]
},
{
"long_name" : "Pirrama Road",
"short_name" : "Pirrama Road",
"types" : [ "route" ]
},
{
"long_name" : "Pyrmont",
"short_name" : "Pyrmont",
"types" : [ "locality", "political" ]
},
{
"long_name" : "NSW",
"short_name" : "NSW",
"types" : [ "administrative_area_level_1", "political" ]
},
{
"long_name" : "AU",
"short_name" : "AU",
"types" : [ "country", "political" ]
},
{
"long_name" : "2009",
"short_name" : "2009",
"types" : [ "postal_code" ]
}
],
"events" : [
{
"event_id" : "9lJ_jK1GfhX",
"start_time" : 1293865200,
"summary" : "<p>A visit from author John Doe, who will read from his latest book.</p>
<p>A limited number of signed copies will be available.</p>",
"url" : "http://www.example.com/john_doe_visit.html"
}
],
"formatted_address" : "48 Pirrama Road, Pyrmont NSW, Australia",
"formatted_phone_number" : "(02) 9374 4000",
"geometry" : {
"location" : {
"lat" : -33.8669710,
"lng" : 151.1958750
}
},
"icon" : "http://maps.gstatic.com/mapfiles/place_api/icons/generic_business-71.png",
"id" : "4f89212bf76dde31f092cfc14d7506555d85b5c7",
"international_phone_number" : "+61 2 9374 4000",
"name" : "Google Sydney",
"rating" : 4.70,
"reference" : "CnRsAAAA98C4wD-VFvzGq-KHVEFhlHuy1TD1W6UYZw7KjuvfVsKMRZkbCVBVDxXFOOCM108n9PuJMJxeAxix3WB6B16c1p2bY1ZQyOrcu1d9247xQhUmPgYjN37JMo5QBsWipTsnoIZA9yAzA-0pnxFM6yAcDhIQbU0z05f3xD3m9NQnhEDjvBoUw-BdcocVpXzKFcnMXUpf-nkyF1w",
"reviews" : [
{
"aspects" : [
{
"rating" : 3,
"type" : "quality"
}
],
"author_name" : "Simon Bengtsson",
"author_url" : "https://plus.google.com/104675092887960962573",
"text" : "Just went inside to have a look at Google. Amazing.",
"time" : 1338440552869
},
{
"aspects" : [
{
"rating" : 3,
"type" : "quality"
}
],
"author_name" : "Felix Rauch Valenti",
"author_url" : "https://plus.google.com/103291556674373289857",
"text" : "Best place to work :-)",
"time" : 1338411244325
},
{
"aspects" : [
{
"rating" : 3,
"type" : "quality"
}
],
"author_name" : "Chris",
"text" : "Great place to work, always lots of free food!",
"time" : 1330467089039
}
],
"types" : [ "establishment" ],
"url" : "http://maps.google.com/maps/place?cid=10281119596374313554",
"vicinity" : "48 Pirrama Road, Pyrmont",
"website" : "http://www.google.com.au/"
},
"status" : "OK"
}
Now I all save that here:
package com.androidhive.googleplacesandmaps;
import java.io.Serializable;
import com.google.api.client.util.Key;
/** Implement this class from "Serializable"
* So that you can pass this class Object to another using Intents
* Otherwise you can't pass to another actitivy
* */
public class Place implements Serializable {
#Key
public String id;
#Key
public String name;
#Key
public String reference;
#Key
public String icon;
#Key
public String vicinity;
#Key
public Geometry geometry;
#Key
public String formatted_address;
#Key
public String formatted_phone_number;
#Override
public String toString() {
return name + " - " + id + " - " + reference;
}
public static class Geometry implements Serializable
{
#Key
public Location location;
}
public static class Location implements Serializable
{
#Key
public double lat;
#Key
public double lng;
}
}
Here is how I get the results:
public class PlacesList implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Key
public String status;
#Key
public List<Place> results;
}
Now my question is:
In the result i get from google you can see the photo_reference. But it's an array and I just need to have the first photo_reference. How can I get that in my code?
JSONObject res = // your google api results
JSONArray photos = res.getJSONArray("photo_reference"); // Extract the JSONArray
// Get the item at index 0, which should be a reference to the first image
String photo = photos.getString(0);
This will get you the reference to the photo, then it looks like you have to make another request to the Photo API.
https://maps.googleapis.com/maps/api/place/photo?parameters
For more information on how to use the Photo API, look at https://developers.google.com/places/documentation/photos

Categories

Resources