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
Related
When I call my API with a request body I deserialize it with the variable name in my POJO. I modify the same list and return back but it duplicates the list
#JsonSerialize
#JsonIgnoreProperties(ignoreUnknown = true)
public class UASchema {
#JsonProperty("metric_id")
private ArrayList<String> fMetricId;
#JsonProperty("schema")
private ArrayList<String> fSchema;
#JsonProperty("hash")
private String fHash;
...
...
//getter and setters
}
Request body is
{
"data" : [
{
"metric_id": ["k1", "ak2", "d90"],
"schema": ["s1", "s2"]
},
{
"metric_id": ["k21", "k22"],
"schema": ["a11", "s22"]
}
]
}
Response I get is (added hash)
{
"result": [
{
"fmetricId": [
"k1",
"ak2",
"d90"
],
"fschema": [
"s1",
"s2"
],
"metric_id": [
"k1",
"ak2",
"d90"
],
"schema": [
"s1",
"s2"
],
"hash": "389abc9093442cfd2aee1f20807ba467"
},
{
"fmetricId": [
"k21",
"k22"
],
"fschema": [
"a11",
"s22"
],
"metric_id": [
"k21",
"k22"
],
"schema": [
"a11",
"s22"
],
"hash": "5f366dde65b69fa679f95a81f3115b7f"
}
]
}
It duplicates the list and not correctly serializing it. I want the response to just have the same list as request body and I added hash back.
It looks like your algorithm duplicates entries or you manually generated getters and setters which duplicate output. By default Jackson does not add extra entries. See below example how you can do that, I generated getters and setters in IDE. f-fieldName pattern for fields is outdated and you should use regular names. See, for example, Google's Java Guide:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.io.File;
import java.util.List;
import java.util.UUID;
public class JsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
Root root = mapper.readValue(jsonFile, Root.class);
root.getData().forEach(s -> s.setfHash(UUID.randomUUID().toString()));
System.out.println(mapper.writeValueAsString(root));
}
}
class Root {
private List<UASchema> data;
public List<UASchema> getData() {
return data;
}
public void setData(List<UASchema> data) {
this.data = data;
}
#Override
public String toString() {
return "Root{" +
"data=" + data +
'}';
}
}
class UASchema {
#JsonProperty("metric_id")
private List<String> fMetricId;
#JsonProperty("schema")
private List<String> fSchema;
#JsonProperty("hash")
private String fHash;
public List<String> getfMetricId() {
return fMetricId;
}
public void setfMetricId(List<String> fMetricId) {
this.fMetricId = fMetricId;
}
public List<String> getfSchema() {
return fSchema;
}
public void setfSchema(List<String> fSchema) {
this.fSchema = fSchema;
}
public String getfHash() {
return fHash;
}
public void setfHash(String fHash) {
this.fHash = fHash;
}
#Override
public String toString() {
return "UASchema{" +
"fMetricId=" + fMetricId +
", fSchema=" + fSchema +
", fHash='" + fHash + '\'' +
'}';
}
}
Above code prints:
{
"data" : [ {
"metric_id" : [ "k1", "ak2", "d90" ],
"schema" : [ "s1", "s2" ],
"hash" : "80dcf06d-1d83-463c-afb8-edef8efdc71f"
}, {
"metric_id" : [ "k21", "k22" ],
"schema" : [ "a11", "s22" ],
"hash" : "a83d7981-4b80-4318-a632-f3c91d14379b"
} ]
}
I use swagger-maven-plugin to generate swagger.json. However, I noticed that an order of properties changes from run to run. For example, it can be:
{
...
"definitions" : {
"MyClass1" : {
"type" : "object",
"properties" : {
"name" : {
"type" : "string"
},
"title" : {
"type" : "string"
},
"description" : {
"type" : "string"
},
}
}
}
...
}
and then after the next generation:
{
...
"definitions" : {
"MyClass1" : {
"type" : "object",
"properties" : {
"description" : {
"type" : "string"
},
"title" : {
"type" : "string"
},
"name" : {
"type" : "string"
}
}
}
}
...
}
My class in Java:
public interface MyClass1 {
String getName();
String getTitle();
String getDescription();
}
It's impossible in Java Runtime to know the exact order of methods declared in a class. If you open java.lang.Class#getDeclaredMethods() (see https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html#getDeclaredMethods--) you will see that The elements in the returned array are not sorted and are not in any particular order..
That's why Jackson can't do it for you.
However, there are 2 solutions:
1.You can use #JsonPropertyOrder annotation:
#JsonPropertyOrder({"name", "title", "description"})
public interface MyClass1 {
String getName();
String getTitle();
String getDescription();
}
2.You can use a class with fields (field order is preserved)
public class MyClass1 {
String name;
String title;
String description;
//Getters skipped
}
My repository implements the following interface:
QueryDslPredicateExecutor<Rule>
The structure of mongo's document(Rule object) is:
{
"_id" : ObjectId("5aa924242a73bec4ce581717"),
"name" : "test-name",
"expressionGroups" : [
{
"type" : "WHEN",
"expressions" : [
{
"name" : "name1",
"values" : ["VAL1", "VAL2", "VAL3"]
},
{
"name" : "name2",
"values" : ["VAL4", "VAL5"]
}
]
},
{
"type" : "FOR",
"expressions" : [
{
"name" : "name3",
"values" : ["VAL6", "VAL7"]
}
]
}
]
}
I want to use the following method to find particular rule within mongodb:
Iterable<T> findAll(Predicate predicate);
I've prepared mongo shell query:
db.rule.find({
'expressionGroups.expressions': {
$all: [
{
'$elemMatch': {
'name': "name1",
'values': "VAL2"
}
},
{
'$elemMatch': {
'name': "name3",
'values': "VAL7"
}
}
]
}
}).pretty()
How can I create com.querydsl.core.types.Predicate based on above query?
There is still no answer and I've met the same issue. So I created such code:
private List<Predicate> toPredicates(String root, Map<String, Object> map) {
List<Predicate> predicates = new ArrayList<>();
for (Map.Entry<String, Object> entry: map.entrySet()) {
String path = root+'.'+entry.getKey();
Object value = entry.getValue();
if (entry.getValue() instanceof Map) {
predicates.addAll(toPredicates(path, (Map<String, Object>) value));
} else {
predicates.add(new SimplePath(path).eq(value.toString()));
}
}
return predicates;
}
private static class SimplePath extends StringPath {
protected SimplePath(String var) {
super(var);
}
}
So, you can parse Json to Map and this is it.
Looking to parse some Json and parse out array of arrays. Unfortunately I cannot figure out how to handle nested arrays within the json.
json
{
"type": "MultiPolygon",
"coordinates": [
[
[
[
-71.25,
42.33
],
[
-71.25,
42.33
]
]
],
[
[
[
-71.23,
42.33
],
[
-71.23,
42.33
]
]
]
]
}
What I have implemented when I just an a single array.
public class JsonObjectBreakDown {
public String type;
public List<List<String[]>> coordinates = new ArrayList<>();
public void setCoordinates(List<List<String[]>> coordinates) {
this.coordinates = coordinates;
}
}
parsing call
JsonObjectBreakDown p = gson.fromJson(withDup, JsonObjectBreakDown.class);
You've got an array of arrays of arrays of arrays of Strings. You need
public List<List<List<String[]>>> coordinates = new ArrayList<>();
The following
public static void main(String args[]) {
Gson gson = new Gson();
String jsonstr ="{ \"type\": \"MultiPolygon\",\"coordinates\": [ [ [ [ -71.25, 42.33 ], [ -71.25, 42.33 ] ] ], [ [ [ -71.23, 42.33 ], [ -71.23, 42.33 ] ] ] ]}";
JsonObjectBreakDown obj = gson.fromJson(jsonstr, JsonObjectBreakDown.class);
System.out.println(Arrays.toString(obj.coordinates.get(0).get(0).get(0)));
}
public static class JsonObjectBreakDown {
public String type;
public List<List<List<String[]>>> coordinates = new ArrayList<>();
public void setCoordinates(List<List<List<String[]>>> coordinates) {
this.coordinates = coordinates;
}
}
prints
[-71.25, 42.33]
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;