I have learnend how to parsing JSON objects via Retrofit Gson but I need to parse a full JSON array via Retrofit Gson.
I need to parse the following :
"{\n" +
" \"snappedPoints\": [\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.2784167,\n" +
" \"longitude\": 149.1294692\n" +
" },\n" +
" \"originalIndex\": 0,\n" +
" \"placeId\": \"ChIJoR7CemhNFmsRQB9QbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.280321693840129,\n" +
" \"longitude\": 149.12908274880189\n" +
" },\n" +
" \"originalIndex\": 1,\n" +
" \"placeId\": \"ChIJiy6YT2hNFmsRkHZAbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.280960897210818,\n" +
" \"longitude\": 149.1293250692261\n" +
" },\n" +
" \"originalIndex\": 2,\n" +
" \"placeId\": \"ChIJW9R7smlNFmsRMH1AbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.28142839817933,\n" +
" \"longitude\": 149.1298619971291\n" +
" },\n" +
" \"originalIndex\": 3,\n" +
" \"placeId\": \"ChIJy8c0r2lNFmsRQEZUbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.28193988170618,\n" +
" \"longitude\": 149.13001013387623\n" +
" },\n" +
" \"originalIndex\": 4,\n" +
" \"placeId\": \"ChIJ58xCoGlNFmsRUEZUbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.282819705480151,\n" +
" \"longitude\": 149.1295597114644\n" +
" },\n" +
" \"originalIndex\": 5,\n" +
" \"placeId\": \"ChIJabjuhGlNFmsREIxAbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.283139388422363,\n" +
" \"longitude\": 149.12895618087012\n" +
" },\n" +
" \"originalIndex\": 6,\n" +
" \"placeId\": \"ChIJ1Wi6I2pNFmsRQL9GbW7qABM\"\n" +
" },\n" +
" {\n" +
" \"location\": {\n" +
" \"latitude\": -35.284728724835304,\n" +
" \"longitude\": 149.12835061713685\n" +
" },\n" +
" \"originalIndex\": 7,\n" +
" \"placeId\": \"ChIJW5JAZmpNFmsRegG0-Jc80sM\"\n" +
" }\n" +
" ]\n" +
"}"
I need the lat and longs only.
Here is the method I know to parse JSON Objects via Retrofit GSON
package com.example.akshay.retrofitgson;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
/**
* Created by Akshay on 9/6/2015.
*/
public class gitmodel {
#SerializedName("latitude")
#Expose
public String latitude;
#SerializedName("longitude")
#Expose
public String longitude;
public void setLatitude(String latitude)
{
this.latitude = latitude;
}
public String getLatitude()
{
return latitude;
}
public void setLongitude(String longitude)
{
this.longitude = longitude;
}
public String getlatitude()
{
return latitude;
}
}
You might need the lat/longs only, but the easiest thing to do is to just set up your POJO to get everything, then extract the lat longs from the POJO. You can even design the deserialized object to hide the inner object if you want. In the case of your JSON, this is quite easy, just do this:
public static class SnappedPoints {
private List<Point> snappedPoints;
public String toString() {
return snappedPoints.toString();
}
}
public static class Point {
private Location location;
public double getLatitude() {
return location.getLatitude();
}
public double getLongitude() {
return location.getLongitude();
}
public String toString() {
return "{" + location.getLatitude() + "," + location.getLongitude() + "}";
}
}
public static class Location {
double latitude;
double longitude;
public double getLatitude() {
return latitude;
}
public double getLongitude() {
return longitude;
}
}
You can see this in action by simply doing this:
public static void main(String[] args) {
System.out.println(new Gson().fromJson(json, SnappedPoints.class));
}
Or, in the case of Retrofit, something like this:
public interface MyRetrofitAPI {
#GET("/path/to/json")
void getSnappedPoints(/* arguments */, Callback<SnappedPoints> callback);
}
Retrofit uses the Gson library to serialise Json responses. As long as you have a model class setup correctly, you can tell Gson to try and serialise the json into an instance of that model class. Your code should look something like the following:
String json; // retrieved from file/server
MyObject myObject = new Gson().fromJson(json, MyObject.class)
Related
This question already has an answer here:
Add item to arraylist if it does not already exist in list
(1 answer)
Closed last year.
This post was edited and submitted for review last year and failed to reopen the post:
Original close reason(s) were not resolved
Below is the sample code
String jsonString = "{\n" +
" \"models\":[\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"ALL\",\n" +
" \"type\":null,\n" +
" \"name\":\"ALL\",\n" +
" \"feature_types\":null\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"102e\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"SIT\",\n" +
" \"name\":\"MUSTANG\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"A\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"B\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"C\",\n" +
" \"desc\":\"BodyStyle\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"980p\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"SIT\",\n" +
" \"name\":\"Ranger\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"C\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"D\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" } \n" +
" ]\n" +
" }\n" +
" },\n" +
" {\n" +
" \"model\":{\n" +
" \"code\":\"kkpou\",\n" +
" \"defaultLookup\":\"false\",\n" +
" \"type\":\"UAT\",\n" +
" \"name\":\"Transit Custom\",\n" +
" \"feature_types\":[\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"F\",\n" +
" \"desc\":\"All feature types\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"G\",\n" +
" \"desc\":\"Series\"\n" +
" }\n" +
" },\n" +
" {\n" +
" \"feature_type\":{\n" +
" \"code\":\"H\",\n" +
" \"desc\":\"Payload\"\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" }\n" +
" ]\n" +
"}";
for(int i = 0; i<myData.size();i++)
{
String type = "SIT";
FeaturedItems item = resultList.stream().filter(featureItem -> type != null && type.equals(featureItem.getType())).findFirst().orElse(null);
if (type != null) {
item = FeaturedItems.builder().type(type).items(new ArrayList<>()).build();
resultList.add(item);//if the item already exists in the list don't add the new item, instead just add the elements in the exisiting item.
//tried the below commented code to add the item if it doesn't contain in the list -- start
/*boolean flagFound = false;
for (FeaturedItems featureItem : resultList) {
if (featureItem.getType().equalsIgnoreCase(type)) {
flagFound = true;
break;
}
}
if(!flagFound) resultList.add(item);*/
//tried the above commented code to add the item if it doesn't contain in the list -- End
for (int count = 0; count < features.size(); count++) {
String id = getFid(count);
MyDataBuild build = ....//logic to set values in the properties
item.getItems().add(build);
}
}
}
lookUpData.setFeatureGroups(resultList);
}
}
If the type value is already defined in the defined featureItems, then instead of creating the new object in the featureItems list, i need to add the unique items(desc,id) to the existing items element for the matching type. The code snippet mentioned above doesn't add the elements to the existing items if the type is matching in the featureItems list, instead it is creating the new element as shown in the output json sample.
Using a Map instead will make your live much easier. However your example is missing some data so it's a bit hard to understand what is actually happening in your code. So I can give you only a simple example for the usage.
Map<String, FeaturedItems> resultMap = new HashMap<>();
// Get the FeaturedItems for the given type. If none is present create a new one.
FeaturedItems items = resultMap.computeIfAbsent(type, k -> FeaturedItems.builder().type(k).items(new ArrayList<>()).build());
// Add your item to the list
Sale newItem // Obtain new item
items.getItems().add(newItem);
I am usng google DirectionsResul Object
And then I want to using Object mapper to mapping this json to DirectionsResul Object
{
"geocoded_waypoints": [],
"routes": [
{
"bounds": {},
"legs": [
{
"distance": {
"human_readable": "13 km",
"in_meters": 13175
},
"duration": {
"human_readable": "37 phút",
"in_seconds": 2206
},
"steps": []
}
],
"overview_polyline": {
"points": "aaaa"
},
"warnings": [],
"waypoint_order": []
}
]
}
Using this code
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
DirectionsResult result;
result = objectMapper.readValue(json, DirectionsResult.class.);
All is ok but overview_polyline can't mapping, the points value is null
and I see in the EncodedPolyline have a contractor like this
public EncodedPolyline() {
this.points = null;
}
So how can I mapping the points value to the DirectionsResul Object
Here is my result I got
Here is all the code that can run
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.maps.model.DirectionsResult;
public void testGetDirections() throws NetworkException {
String json = "{\n" +
" \"geocoded_waypoints\": [],\n" +
" \"routes\": [\n" +
" {\n" +
" \"bounds\": {\n" +
" \"northeast\": {\n" +
" \"lat\": 34.1358593,\n" +
" \"lng\": -117.922066\n" +
" },\n" +
" \"southwest\": {\n" +
" \"lat\": 33.815582,\n" +
" \"lng\": -118.3516983\n" +
" }\n" +
" },\n" +
" \"legs\": [\n" +
" {\n" +
" \"distance\": {\n" +
" \"human_readable\": \"13 km\",\n" +
" \"in_meters\": 13175\n" +
" },\n" +
" \"duration\": {\n" +
" \"human_readable\": \"37 phút\",\n" +
" \"in_seconds\": 2206\n" +
" },\n" +
" \"steps\": [\n" +
" {\n" +
" \"distance\": {\n" +
" \"human_readable\": \"10 ft\",\n" +
" \"in_meters\": 3\n" +
" },\n" +
" \"duration\": {\n" +
" \"human_readable\": \"1 min\",\n" +
" \"in_seconds\": 0\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" ],\n" +
" \"overview_polyline\": {\n" +
" \"points\": \"{ashdasda}\"\n" +
" },\n" +
" \"warnings\": [],\n" +
" \"waypoint_order\": []\n" +
" }\n" +
" ]\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
DirectionsResult goongMapsDirectionResult;
try {
goongMapsDirectionResult = objectMapper.readValue(json, DirectionsResult.class.);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
The problem is that there is no setter for points on EncodedPolyline.
One way to work around this is to use a DeserializationProblemHandler:
public class SO69242058 {
public static void main(String args[]) throws JsonProcessingException {
String json = "{\n" +
" \"geocoded_waypoints\": [],\n" +
" \"routes\": [\n" +
" {\n" +
" \"bounds\": {\n" +
" \"northeast\": {\n" +
" \"lat\": 34.1358593,\n" +
" \"lng\": -117.922066\n" +
" },\n" +
" \"southwest\": {\n" +
" \"lat\": 33.815582,\n" +
" \"lng\": -118.3516983\n" +
" }\n" +
" },\n" +
" \"legs\": [\n" +
" {\n" +
" \"distance\": {\n" +
" \"human_readable\": \"13 km\",\n" +
" \"in_meters\": 13175\n" +
" },\n" +
" \"duration\": {\n" +
" \"human_readable\": \"37 phút\",\n" +
" \"in_seconds\": 2206\n" +
" },\n" +
" \"steps\": [\n" +
" {\n" +
" \"distance\": {\n" +
" \"human_readable\": \"10 ft\",\n" +
" \"in_meters\": 3\n" +
" },\n" +
" \"duration\": {\n" +
" \"human_readable\": \"1 min\",\n" +
" \"in_seconds\": 0\n" +
" }\n" +
" }\n" +
" ]\n" +
" }\n" +
" ],\n" +
" \"overview_polyline\": {\n" +
" \"points\": \"{ashdasda}\"\n" +
" },\n" +
" \"warnings\": [],\n" +
" \"waypoint_order\": []\n" +
" }\n" +
" ]\n" +
"}";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
//objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
objectMapper.addHandler(new DeserializationProblemHandler() {
#Override
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p,
JsonDeserializer<?> deserializer, Object beanOrClass,
String propertyName) throws IOException {
EncodedPolyline encodedPolyline = (EncodedPolyline)beanOrClass;
try {
Field f = EncodedPolyline.class.getDeclaredField("points");
f.setAccessible(true);
f.set(encodedPolyline, p.readValueAs(String.class));
} catch (NoSuchFieldException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return true;
}
});
DirectionsResult goongMapsDirectionResult;
goongMapsDirectionResult = objectMapper.readValue(json, DirectionsResult.class);
}
}
I've removed objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) so that the error occurs when Jackson tries to set points. Then we set it reflectively.
Just want to ask how can I manipulate my codes in Java wherein I can display the commonnames with multiple latlong values? Please help I'm new at programming.
MainActivity.java
public class MainActivity extends AppCompatActivity {
public AutoCompleteTextView animalname;
public String JSONString = "{\n" +
" \"result\": [\n" +
" {\n" +
" \"0\": \"14.44133541176629\",\n" +
" \"latitude\": \"14.44133541176629\",\n" +
" \"1\": \"120.45936525802608\",\n" +
" \"longitude\": \"120.45936525802608\",\n" +
" \"2\": \"Bataan\",\n" +
" \"province\": \"Bataan\",\n" +
" \"3\": \"Tamaraw\",\n" +
" \"commonname\": \"Tamaraw\"\n" +
" },\n" +
" {\n" +
" \"0\": \"14.656674396646768\",\n" +
" \"latitude\": \"14.656674396646768\",\n" +
" \"1\": \"121.05812014083858\",\n" +
" \"longitude\": \"121.05812014083858\",\n" +
" \"2\": \"Quezon\",\n" +
" \"province\": \"Quezon\",\n" +
" \"3\": \"Walden's Hornbill\",\n" +
" \"commonname\": \"Walden's Hornbill\"\n" +
" },\n" +
" {\n" +
" \"0\": \"14.898346071682198\",\n" +
" \"latitude\": \"14.898346071682198\",\n" +
" \"1\": \"121.42616213302608\",\n" +
" \"longitude\": \"121.42616213302608\",\n" +
" \"2\": \"General nakar\",\n" +
" \"province\": \"General nakar\",\n" +
" \"3\": \"Tamaraw\",\n" +
" \"commonname\": \"Tamaraw\"\n" +
" },\n" +
" {\n" +
" \"0\": \"15.378556159943873\",\n" +
" \"latitude\": \"15.378556159943873\",\n" +
" \"1\": \"121.39594973068233\",\n" +
" \"longitude\": \"121.39594973068233\",\n" +
" \"2\": \"Dingalan\",\n" +
" \"province\": \"Dingalan\",\n" +
" \"3\": \"Philippine Cockatoo\",\n" +
" \"commonname\": \"Philippine Cockatoo\"\n" +
" },\n" +
" {\n" +
" \"0\": \"15.491670747921509\",\n" +
" \"latitude\": \"15.491670747921509\",\n" +
" \"1\": \"120.94052188562534\",\n" +
" \"longitude\": \"120.94052188562534\",\n" +
" \"2\": \"Cabanatuan City\",\n" +
" \"province\": \"Cabanatuan City\",\n" +
" \"3\": \"Philippine Cockatoo\",\n" +
" \"commonname\": \"Philippine Cockatoo\"\n" +
" },\n" +
" {\n" +
" \"0\": \"16.229997551983594\",\n" +
" \"latitude\": \"16.229997551983594\",\n" +
" \"1\": \"120.52623997214562\",\n" +
" \"longitude\": \"120.52623997214562\",\n" +
" \"2\": \"Baguio\",\n" +
" \"province\": \"Baguio\",\n" +
" \"3\": \"Philippine Spotted Deer\",\n" +
" \"commonname\": \"Philippine Spotted Deer\"\n" +
" },\n" +
" {\n" +
" \"0\": \"6.984796116278719\",\n" +
" \"latitude\": \"6.984796116278719\",\n" +
" \"1\": \"122.02642351890961\",\n" +
" \"longitude\": \"122.02642351890961\",\n" +
" \"2\": \"Zamboanga\",\n" +
" \"province\": \"Zamboanga\",\n" +
" \"3\": \"Hawksbill Sea Turtle\",\n" +
" \"commonname\": \"Hawksbill Sea Turtle\"\n" +
" },\n" +
" {\n" +
" \"0\": \"10.100726050965035\",\n" +
" \"latitude\": \"10.100726050965035\",\n" +
" \"1\": \"125.59963979398412\",\n" +
" \"longitude\": \"125.59963979398412\",\n" +
" \"2\": \"Dinagat Island\",\n" +
" \"province\": \"Dinagat Island\",\n" +
" \"3\": \"Dinagat bushy-tailed Cloud Rat\",\n" +
" \"commonname\": \"Dinagat bushy-tailed Cloud Rat\"\n" +
" },\n" +
" {\n" +
" \"0\": \"9.35368808473656\",\n" +
" \"latitude\": \"9.35368808473656\",\n" +
" \"1\": \"118.36544272849846\",\n" +
" \"longitude\": \"118.36544272849846\",\n" +
" \"2\": \"Palawan\",\n" +
" \"province\": \"Palawan\",\n" +
" \"3\": \"Philippine Forest Turtle\",\n" +
" \"commonname\": \"Philippine Forest Turtle\"\n" +
" },\n" +
" {\n" +
" \"0\": \"9.646007526813666\",\n" +
" \"latitude\": \"9.646007526813666\",\n" +
" \"1\": \"122.85255472090171\",\n" +
" \"longitude\": \"122.85255472090171\",\n" +
" \"2\": \"Negros\",\n" +
" \"province\": \"Negros\",\n" +
" \"3\": \"Philippine naked-backed fruit bat\",\n" +
" \"commonname\": \"Philippine naked-backed fruit bat\"\n" +
" },\n" +
" {\n" +
" \"0\": \"9.551081019434731\",\n" +
" \"latitude\": \"9.551081019434731\",\n" +
" \"1\": \"123.09185859510103\",\n" +
" \"longitude\": \"123.09185859510103\",\n" +
" \"2\": \"Negros and Panay\",\n" +
" \"province\": \"Negros and Panay\",\n" +
" \"3\": \"Negros Bleeding-heart\",\n" +
" \"commonname\": \"Negros Bleeding-heart\"\n" +
" },\n" +
" {\n" +
" \"0\": \"9.380944735295179\",\n" +
" \"latitude\": \"9.380944735295179\",\n" +
" \"1\": \"118.38456063371927\",\n" +
" \"longitude\": \"118.38456063371927\",\n" +
" \"2\": \"Palawan\",\n" +
" \"province\": \"Palawan\",\n" +
" \"3\": \"Philippine Cockatoo\",\n" +
" \"commonname\": \"Philippine Cockatoo\"\n" +
" },\n" +
" {\n" +
" \"0\": \"10.071930427284427\",\n" +
" \"latitude\": \"10.071930427284427\",\n" +
" \"1\": \"125.59779391691245\",\n" +
" \"longitude\": \"125.59779391691245\",\n" +
" \"2\": \"Camiguin Sur and Dinagat Island\",\n" +
" \"province\": \"Camiguin Sur and Dinagat Island\",\n" +
" \"3\": \"Walden's Hornbill\",\n" +
" \"commonname\": \"Walden's Hornbill\"\n" +
" },\n" +
" {\n" +
" \"0\": \"13.093068957060206\",\n" +
" \"latitude\": \"13.093068957060206\",\n" +
" \"1\": \"121.06598892373722\",\n" +
" \"longitude\": \"121.06598892373722\",\n" +
" \"2\": \"Mindoro\",\n" +
" \"province\": \"Mindoro\",\n" +
" \"3\": \"Philippine Fresh Water Crocodile\",\n" +
" \"commonname\": \"Philippine Fresh Water Crocodile\"\n" +
" },\n" +
" {\n" +
" \"0\": \"9.651642644962154\",\n" +
" \"latitude\": \"9.651642644962154\",\n" +
" \"1\": \"122.84131398239595\",\n" +
" \"longitude\": \"122.84131398239595\",\n" +
" \"2\": \"Panay And Negros\",\n" +
" \"province\": \"Panay And Negros\",\n" +
" \"3\": \"Visayan Warty Pig\",\n" +
" \"commonname\": \"Visayan Warty Pig\"\n" +
" },\n" +
" {\n" +
" \"0\": \"7.2396901503428\",\n" +
" \"latitude\": \"7.2396901503428\",\n" +
" \"1\": \"125.44315069027664\",\n" +
" \"longitude\": \"125.44315069027664\",\n" +
" \"2\": \"Davao City\",\n" +
" \"province\": \"Davao City\",\n" +
" \"3\": \"Philippine Eagle\",\n" +
" \"commonname\": \"Philippine Eagle\"\n" +
" },\n" +
" {\n" +
" \"0\": \"9.810806171435631\",\n" +
" \"latitude\": \"9.810806171435631\",\n" +
" \"1\": \"124.26143093023506\",\n" +
" \"longitude\": \"124.26143093023506\",\n" +
" \"2\": \"Bohol\",\n" +
" \"province\": \"Bohol\",\n" +
" \"3\": \"Philippine Tarsier\",\n" +
" \"commonname\": \"Philippine Tarsier\"\n" +
" },\n" +
" {\n" +
" \"0\": \"13.088847376649245\",\n" +
" \"latitude\": \"13.088847376649245\",\n" +
" \"1\": \"121.0535496566772\",\n" +
" \"longitude\": \"121.0535496566772\",\n" +
" \"2\": \"Mindoro\",\n" +
" \"province\": \"Mindoro\",\n" +
" \"3\": \"Tamaraw\",\n" +
" \"commonname\": \"Tamaraw\"\n" +
" }\n" +
" ]\n" +
"}";
public ArrayList<Animals> animalList;
TextView latitude_text, longitude_text, province;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
latitude_text = findViewById(R.id.latitude_text);
longitude_text = findViewById(R.id.longitude_text);
province = findViewById(R.id.province);
initView();
animalList = extractAnimals(JSONString);
AnimalAdapter animalAdapter = new AnimalAdapter(this, R.layout.animal_row_layout, animalList);
animalname.setAdapter(animalAdapter);
animalname.setThreshold(1);
animalname.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long l) {
Animals animals = (Animals) parent.getItemAtPosition(position);
animalname.setText(animals.getCommonname());
latitude_text.setText(animals.getLatitude());
longitude_text.setText(animals.getLongitude());
province.setText(animals.getProvince());
}
});
}
private void initView() {
animalname = findViewById(R.id.animalname);
animalList = new ArrayList<>();
}
private ArrayList<Animals> extractAnimals(String JSONString){
ArrayList<Animals> list = new ArrayList<>();
try{
JSONObject rootjo = new JSONObject(JSONString);
JSONArray userja = rootjo.getJSONArray("result");
for(int i = 0; i<userja.length(); i++){
JSONObject jo= userja.getJSONObject(i);
String commonname = jo.optString("commonname");
String latitude = jo.optString("latitude");
String longitude = jo.optString("longitude");
String province = jo.optString("province");
Animals anim = new Animals(commonname, latitude, longitude, province);
list.add(anim);
}
}catch (JSONException e) {
e.printStackTrace();
}
return list;
}
}
AnimalAdapter.java
public class AnimalAdapter extends ArrayAdapter<Animals>{
public ArrayList<Animals> animalList;
public ArrayList<Animals> tempList;
public ArrayList<Animals> suggestionList;
public AnimalAdapter(#NonNull Context context, int resource, #NonNull List<Animals> objects) {
super(context, resource, objects);
animalList = (ArrayList<Animals>) objects;
tempList = new ArrayList<>(animalList);
suggestionList = new ArrayList<>();
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(getContext()).inflate(R.layout.animal_row_layout, parent,false);
TextView textView = convertView.findViewById(R.id.simple_text);
Animals animals = animalList.get(position);
textView.setText(animals.getCommonname());
}
return convertView;
}
#NonNull
#Override
public Filter getFilter() {
return filter;
}
Filter filter = new Filter() {
#Override
public CharSequence convertResultToString(Object resultValue) {
Animals animals = (Animals) resultValue;
return animals.getCommonname();
}
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (constraint != null && constraint.length()>0) {
suggestionList.clear();
constraint = constraint.toString().trim().toLowerCase();
for (Animals animals : tempList){
if(animals.getCommonname().toLowerCase().contains(constraint)){
suggestionList.add(animals);
}
}
filterResults.count = suggestionList.size();
filterResults.values = suggestionList;
}
return filterResults;
}
#Override
protected void publishResults(CharSequence charSequence, FilterResults results) {
ArrayList<Animals> uList = (ArrayList<Animals>) results.values;
if(results != null && results.count > 0){
clear();
for (Animals u : uList) {
add(u);
notifyDataSetChanged();
}
}
}
};
}
Animals.java
public class Animals {
private String commonname;
private String latitude;
private String longitude;
private String province;
public Animals(String commonname, String latitude, String longitude, String province) {
this.commonname = commonname;
this.latitude = latitude;
this.longitude = longitude;
this.province = province;
}
public String getCommonname() {
return commonname;
}
public void setCommonname(String commonname) {
this.commonname = commonname;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
}
animal_row_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/simple_text"/>
<View
android:layout_height="2dp"
android:layout_width="match_parent"
android:background="#color/colorPrimary" />
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp"
tools:context="com.example.admin.sampletransfer.MainActivity">
<AutoCompleteTextView
android:id="#+id/animalname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:completionThreshold="1"
android:hint="Search Animals"/>
<TextView
android:layout_marginTop="30dp"
android:id="#+id/latitude_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_marginTop="30dp"
android:id="#+id/longitude_text"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_marginTop="30dp"
android:id="#+id/province"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
This animal has the same commonname I want to group it. How can I fix this? please let me know.
I have this json data that I was to parse with jsonpath:
{
"kind": "tm:sys:hardware:hardwarestats",
"selfLink": "https://localhost/mgmt/tm/sys/hardware?ver\u003d11.5.4",
"entries": {
"https://localhost/mgmt/tm/sys/hardware/platform": {
"nestedStats": {
"entries": {
"https://localhost/mgmt/tm/sys/hardware/platform/0": {
"nestedStats": {
"entries": {
"baseMac": {
"description": "00:00ยง:00:00:00:00"
},
"biosRev": {
"description": "OBJ-0065-xx Build: 1.06.043.0 05/02/2014"
},
"marketingName": {
"description": "BIG-IP VPR-C2400"
},
"pvaVersion": {
"description": "20"
}
}
}
}
}
}
}
}
}
As you can see some parts consists of children named according to this:
https://[host]/path
I would like to be able to essentially ignore the host part by using a wildcard:
$.entries.https://*/mgmt/tm/sys/hardware/platform.nestedStats.entries.*.nestedStats.entries.marketingName.description
Note the wildcard replacing localhost (it differs depending on which host header is sent to the api endpoint).
I have no control over the server side. Any suggestion appreciated!
/Patrik
If you just want to get the values of those baseMac, biosRev descriptions without filtering path, this should be enough
public static void main(String[] args) {
String samplejson = "{\n" +
" \"kind\": \"tm:sys:hardware:hardwarestats\",\n" +
" \"selfLink\": \"https://localhost/mgmt/tm/sys/hardware?ver\\u003d11.5.4\",\n" +
" \"entries\": {\n" +
" \"https://localhost/mgmt/tm/sys/hardware/platform\": {\n" +
" \"nestedStats\": {\n" +
" \"entries\": {\n" +
" \"https://localhost/mgmt/tm/sys/hardware/platform/0\": {\n" +
" \"nestedStats\": {\n" +
" \"entries\": {\n" +
" \"baseMac\": {\n" +
" \"description\": \"00:00ยง:00:00:00:00\"\n" +
" },\n" +
" \"biosRev\": {\n" +
" \"description\": \"OBJ-0065-xx Build: 1.06.043.0 05/02/2014\"\n" +
" },\n" +
" \"marketingName\": {\n" +
" \"description\": \"BIG-IP VPR-C2400\"\n" +
" },\n" +
" \"pvaVersion\": {\n" +
" \"description\": \"20\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
Object baseMac = JsonPath.read(samplejson, "$.entries..nestedStats.entries.marketingName.description");
System.out.println(baseMac.toString());
}
But, if you want to read those descriptions w.r.t only certain paths, like you want to read only https://localhost/mgmt/tm/sys/hardware/platform/0 and NOT https://localhost/mgmt/tm/sys/hardware/platform/**1**, then solution should be something else.
I am trying to get a value from a JSON string but I am getting a null value instead.
App2.java :
package JsonExample1;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.ObjectMapper;
import java.io.IOException;
import java.io.StringReader;
public class App2 {
private JsonNode rootNode;
public void setup() throws IOException {
String jsonString = "{\n" +
" \"HotelListResponse\" : {\n" +
" \"customerSessionId\" : \"0ABAAA7A-90C9-7491-3FF2-7E2C37496CA2\",\n" +
" \"numberOfRoomsRequested\" : 1,\n" +
" \"moreResultsAvailable\" : true,\n" +
" \"cacheKey\" : \"7790c974:13ff7e2c374:6ccd\",\n" +
" \"cacheLocation\" : \"10.186.170.122:7300\",\n" +
" \"HotelList\" : {\n" +
" \"#activePropertyCount\" : \"223\",\n" +
" \"#size\" : \"1\",\n" +
" \"HotelSummary\" : {\n" +
" \"#order\" : \"0\",\n" +
" \"hotelId\" : 125727,\n" +
" \"name\" : \"Red Lion Hotel on Fifth Avenue\",\n" +
" \"address1\" : \"1415 5th Ave\",\n" +
" \"city\" : \"Seattle\",\n" +
" \"stateProvinceCode\" : \"WA\",\n" +
" \"postalCode\" : 98101,\n" +
" \"countryCode\" : \"US\",\n" +
" \"airportCode\" : \"SEA\",\n" +
" \"supplierType\" : \"E\",\n" +
" \"hotelRating\" : 3.5,\n" +
" \"propertyCategory\" : 1,\n" +
" \"confidenceRating\" : 90,\n" +
" \"amenityMask\" : 7847938,\n" +
" \"tripAdvisorRating\" : 4,\n" +
" \"locationDescription\" : \"Near Pike Place Market\",\n" +
" \"shortDescription\" : \"<p><b>Location. </b> <br />Red Lion Hotel on Fifth Avenue is located close to 5th Avenue Theater, Pike Place Market, and Washington State Convention & Trade Center. Additional points of interest\",\n" +
" \"highRate\" : 149,\n" +
" \"lowRate\" : 126.65,\n" +
" \"rateCurrencyCode\" : \"USD\",\n" +
" \"latitude\" : 47.60985,\n" +
" \"longitude\" : -122.33475,\n" +
" \"proximityDistance\" : 11.168453,\n" +
" \"proximityUnit\" : \"MI\",\n" +
" \"hotelInDestination\" : true,\n" +
" \"thumbNailUrl\" : \"/hotels/1000000/60000/51000/50947/50947_180_t.jpg\",\n" +
" \"deepLink\" : \"http://travel.ian.com/index.jsp?pageName=hotAvail&cid=55505&hotelID=125727&mode=2&numberOfRooms=1&room-0-adult-total=2&room-0-child-total=0&arrivalMonth=8&arrivalDay=4&departureMonth=8&departureDay=5&showInfo=true&locale=en_US¤cyCode=USD\",\n" +
" \"RoomRateDetailsList\" : {\n" +
" \"RoomRateDetails\" : {\n" +
" \"roomTypeCode\" : 253461,\n" +
" \"rateCode\" : 201054304,\n" +
" \"maxRoomOccupancy\" : 2,\n" +
" \"quotedRoomOccupancy\" : 2,\n" +
" \"minGuestAge\" : 0,\n" +
" \"roomDescription\" : \"Classic Single Queen\",\n" +
" \"promoId\" : 202161947,\n" +
" \"promoDescription\" : \"Summer Sale! Save 15%\",\n" +
" \"currentAllotment\" : 0,\n" +
" \"propertyAvailable\" : true,\n" +
" \"propertyRestricted\" : false,\n" +
" \"expediaPropertyId\" : 50947,\n" +
" \"rateKey\" : \"0ABAAA7A-90C9-7491-3FF2-7E2C37496CCE\",\n" +
" \"RateInfo\" : {\n" +
" \"#rateChange\" : \"false\",\n" +
" \"#promo\" : \"true\",\n" +
" \"#priceBreakdown\" : \"true\",\n" +
" \"ChargeableRateInfo\" : {\n" +
" \"#total\" : \"151.23\",\n" +
" \"#surchargeTotal\" : \"24.58\",\n" +
" \"#nightlyRateTotal\" : \"126.65\",\n" +
" \"#maxNightlyRate\" : \"126.65\",\n" +
" \"#currencyCode\" : \"USD\",\n" +
" \"#commissionableUsdTotal\" : \"126.65\",\n" +
" \"#averageRate\" : \"126.65\",\n" +
" \"#averageBaseRate\" : \"149.0\",\n" +
" \"NightlyRatesPerRoom\" : {\n" +
" \"#size\" : \"1\",\n" +
" \"NightlyRate\" : {\n" +
" \"#promo\" : \"true\",\n" +
" \"#rate\" : \"126.65\",\n" +
" \"#baseRate\" : \"149.0\"\n" +
" }\n" +
" },\n" +
" \"Surcharges\" : {\n" +
" \"#size\" : \"1\",\n" +
" \"Surcharge\" : {\n" +
" \"#amount\" : \"24.58\",\n" +
" \"#type\" : \"TaxAndServiceFee\"\n" +
" }\n" +
" }\n" +
" }\n" +
" },\n" +
" \"ValueAdds\" : {\n" +
" \"#size\" : \"1\",\n" +
" \"ValueAdd\" : {\n" +
" \"#id\" : \"2048\",\n" +
" \"description\" : \"Free Wireless Internet\"\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
" }";
rootNode = new ObjectMapper().readTree(new StringReader(jsonString));
}
//other methods
public void basicTreeModelRead()
{
//Just like DOM, our data is in a hierarchy of node (in this case, it is JsonNode)
JsonNode aField = rootNode.get("customerSessionId");
//the customerSessionId has a String value
String myString = aField.asText();
System.out.println("customerSessionId is:" + myString);
}
}
StartHere.java:
package JsonExample1;
import java.io.IOException;
public class StartHere {
public static void main(String[] args) {
App2 myApp = new App2();
try {
myApp.setup();
} catch (IOException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
myApp.basicTreeModelRead();
}
}
After debugging I found that aField value remains null.
Any ideas?
Your root node doesn't have a customerSessionId, it has a HotelListResponse. Get that first.
//other methods
public void basicTreeModelRead()
{
JsonNode innerNode = rootNode.get("HotelListResponse"); // Get the only element in the root node
// get an element in that node
JsonNode aField = innerNode.get("customerSessionId");
//the customerSessionId has a String value
String myString = aField.asText();
System.out.println("customerSessionId is:" + myString);
}
This prints
customerSessionId is:0ABAAA7A-90C9-7491-3FF2-7E2C37496CA2
Another way to get the inner element, with .at() method:
rootNode.at("/HotelListResponse/customerSessionId")
Convert to the Map
Map map = objectMapper.readValue(jsonString, Map.class);
Method for navigation in the map
private static <T> T get(Map map, Class<T> clazz, String... path) {
Map node = map;
for (int i = 0; i < path.length - 1; i++) {
node = (Map) node.get(path[i]);
}
return (T) node.get(path[path.length - 1]);
}
Usage:
String value = get(map, String.class, "path", "to", "the", "node")