Java Gson - Get specific values from JSON tree - java

I have this JSON:
request_time: "2018-03-13T00:59:44+00:00",
stops: [
{
atcocode: "370023715",
mode: "bus",
name: "AG1",
stop_name: "AG1",
smscode: "37023715",
bearing: "N",
locality: "Sheffield Centre",
indicator: "AG1",
longitude: -1.46616,
latitude: 53.38248,
distance: 57
},
{
atcocode: "370027281",
mode: "bus",
name: "AG12",
stop_name: "AG12",
smscode: "37027281",
bearing: "N",
locality: "Sheffield Centre",
indicator: "AG12",
longitude: -1.46583,
latitude: 53.38228,
distance: 77
}
]
}
I would like to retrieve and store each locality and atocode within this sub tree, in an array. I currently have this java code, but it only displays everything within the sub tree :
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(json);
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html><body>");
if (element.isJsonObject()){
JsonObject bus = element.getAsJsonObject();
JsonArray array = bus.getAsJsonArray("stops");
for (int i = 0; i < array.size(); i++){
out.println(array.get(i));
}

So, just use get method of JsonObject on each "stops" array element:
public static void main(String[] args) {
String json = "{request_time: \"2018-03-13T00:59:44+00:00\",\n" + "stops: [\n" + "{\n"
+ "atcocode: \"370023715\",\n" + "mode: \"bus\",\n" + "name: \"AG1\",\n"
+ "stop_name: \"AG1\",\n" + "smscode: \"37023715\",\n" + "bearing: \"N\",\n"
+ "locality: \"Sheffield Centre\",\n" + "indicator: \"AG1\",\n" + "longitude: -1.46616,\n"
+ "latitude: 53.38248,\n" + "distance: 57\n" + "},\n" + "{\n" + "atcocode: \"370027281\",\n"
+ "mode: \"bus\",\n" + "name: \"AG12\",\n" + "stop_name: \"AG12\",\n"
+ "smscode: \"37027281\",\n" + "bearing: \"N\",\n" + "locality: \"Sheffield Centre\",\n"
+ "indicator: \"AG12\",\n" + "longitude: -1.46583,\n" + "latitude: 53.38228,\n"
+ "distance: 77\n" + "}\n" + "]\n" + "}";
JsonParser parser = new JsonParser();
JsonElement element = parser.parse(json);
if (element.isJsonObject()) {
JsonObject bus = element.getAsJsonObject();
JsonArray array = bus.getAsJsonArray("stops");
for (int i = 0; i < array.size(); i++) {
System.out.println(((JsonObject) array.get(i)).get("locality"));
System.out.println(((JsonObject) array.get(i)).get("atcocode"));
}
}
}
Output:
"Sheffield Centre"
"370023715"
"Sheffield Centre"
"370027281"
P.S. I don't provide the code how to store these in an array as it is unclear how you want to store it, how many arrays you want...

Related

How to put a JsonElement back into a JsonObject?

The goal is replace a value in a nested JSON.
Original JSON :
{
"data": {
"car": {
"xia": [
"a0.c904.b0"
]
}
}
}
Expected JSON:
{
"data": {
"car": {
"xia": [
"a0.c234.b0"
]
}
}
}
My code below gives me the JSONElement but I don't know how to put it back to the json object?
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
String inputJson = "{\n"
+ " \"data\": {\n"
+ " \"car\": {\n"
+ " \"xia\": [\n"
+ " \"a0.c904.b0\"\n"
+ " ]\n"
+ " }\n"
+ " }\n"
+ "}";
JsonObject jsonObject = new JsonParser().parse(inputJson).getAsJsonObject();
JsonElement jsonElement = jsonObject.get("data").getAsJsonObject().get("car").getAsJsonObject().get("xia");
String str = jsonElement.getAsString();
System.out.println(str);
String[] strs = str.split("\\.");
String replaced = strs[0] + "." + strs[1].replaceAll("\\d+", "234") + "." + strs[2];
System.out.println(replaced);
JsonElement jsonElementReplaced = new JsonParser().parse(replaced);
I just had to do :
jsonObject.get("data").getAsJsonObject().get("car").getAsJsonObject().add("xia", jsonElementReplaced);

No values from JSON

I'd like to display values from my JSON just for testing purposes, but I've received literally nothing. Where can be an issue? The link in Utils is correctly for sure, I've runned it on my browser, and everything was good.
Here's the code
Utils class
public class WeatherUtils {
public WeatherUtils(){}
public static ArrayList<Weather> getHourlyData (double minTemp, double maxTemp, double currentTemp, double airPressure){
ArrayList<Weather> weatherList = new ArrayList<>();
try {
JSONObject reader = new JSONObject("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...");
JSONArray array = reader.getJSONArray("list");
for (int i = 0; i<array.length(); i++){
JSONObject secondReader = array.getJSONObject(i);
JSONObject dataObject = secondReader.getJSONObject("main");
for (int j = 0; j<dataObject.length(); j++){
currentTemp = dataObject.getDouble("temp");
minTemp = dataObject.getDouble("temp_min");
maxTemp = dataObject.getDouble("temp_max");
airPressure = dataObject.getDouble("pressure");
}
weatherList.add(new Weather(currentTemp,minTemp,maxTemp,airPressure));
}
} catch (JSONException e) {
e.printStackTrace();
}
return weatherList;
}
}
MainActivity
Double a,b,c,d;
a = 0.0;
b = 0.0;
c = 0.0;
d = 0.0;
ArrayList<Weather> weathers = WeatherUtils.getHourlyData(a,b,c,d);
System.out.println(weathers);
JSON structure
{
"cod": "200",
"message": 0.0074,
"cnt": 40,
"list": [
{
"dt": 1559131200,
"main": {
"temp": 22.1,
"temp_min": 21.32,
"temp_max": 22.1,
"pressure": 1012.31,
"sea_level": 1012.31,
"grnd_level": 976.84,
"humidity": 92,
"temp_kf": 0.78
},
"weather": [
{
"id": 500,
"main": "Rain",
"description": "light rain",
"icon": "10d"
}
],
"clouds": {
"all": 89
},
"wind": {
"speed": 3.08,
"deg": 213.025
},
"rain": {
"3h": 0.875
},
"sys": {
"pod": "d"
},
"dt_txt": "2019-05-29 12:00:00"
},
{
Of course, there are more data. I've posted one "block"
How I may fix that?
Well, given that you just want to "test" the json parsing, you have few options but let's go with a simple one. But first, I would say to extract the parser and put it in its own class/method so it becomes easier to test, something like this:
public class WeatherUtils {
public WeatherUtils(){}
public static ArrayList<Weather> getHourlyData (double minTemp, double maxTemp, double currentTemp, double airPressure){
final ArrayList<Weather> weatherList = new ArrayList<>();
try {
final JSONObject response = httpCall();
weatherList = mapWeatherResponse(response);
} catch (JSONException e) {
e.printStackTrace();
}
return weatherList;
}
public static List<Weather> mapWeatherResponse(JSONObject reader){
final ArrayList<Weather> weatherList = new ArrayList<>();
JSONArray array = reader.getJSONArray("list");
for (int i = 0; i<array.length(); i++){
JSONObject secondReader = array.getJSONObject(i);
JSONObject dataObject = secondReader.getJSONObject("main");
for (int j = 0; j<dataObject.length(); j++){
currentTemp = dataObject.getDouble("temp");
minTemp = dataObject.getDouble("temp_min");
maxTemp = dataObject.getDouble("temp_max");
airPressure = dataObject.getDouble("pressure");
}
weatherList.add(new Weather(currentTemp,minTemp,maxTemp,airPressure));
}
}
}
Test the response parser with a junit test:
You can create a junit test like this:
public class WeatherUtilsTest {
#Test
public void parserResponseTEst() {
final List<String> expectedResponse = new ArrayList<>();
//fill the expectedResponse with the correspondent values
final String json = "{\n" +
" \"cod\": \"200\",\n" +
" \"message\": 0.0074,\n" +
" \"cnt\": 40,\n" +
" \"list\": [\n" +
" {\n" +
" \"dt\": 1559131200,\n" +
" \"main\": {\n" +
" \"temp\": 22.1,\n" +
" \"temp_min\": 21.32,\n" +
" \"temp_max\": 22.1,\n" +
" \"pressure\": 1012.31,\n" +
" \"sea_level\": 1012.31,\n" +
" \"grnd_level\": 976.84,\n" +
" \"humidity\": 92,\n" +
" \"temp_kf\": 0.78\n" +
" },\n" +
" \"weather\": [\n" +
" {\n" +
" \"id\": 500,\n" +
" \"main\": \"Rain\",\n" +
" \"description\": \"light rain\",\n" +
" \"icon\": \"10d\"\n" +
" }\n" +
" ],\n" +
" \"clouds\": {\n" +
" \"all\": 89\n" +
" },\n" +
" \"wind\": {\n" +
" \"speed\": 3.08,\n" +
" \"deg\": 213.025\n" +
" },\n" +
" \"rain\": {\n" +
" \"3h\": 0.875\n" +
" }\n" +
" }]\n" +
" }";
final List<String> response = WeatherUtils.mapWeatherResponse(new JSONObject(json));
assertEquals(expectedResponse, response);
}
}
There is nothing wrong with the JSONObject parser you are doing. You mentioned the link you are using in Utils is correct, do you get a proper response when you test it in your browser, postman, insomnia?
OBS JSONObject reader = new JSONObject("https://api..."); does not fetch anything, what you are doing there is creating a JSONObject from the given String, i.e. "https://....". To fetch the data you need to implement some http client. Here is an example https://stackoverflow.com/a/4457526/761668
You're not getting the response from the server, you're trying to initialize a JSONObject with the URL.
To retrieve it you should replace this line:
JSONObject reader = new JSONObject("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...");
with this code:
HttpURLConnection conn = null;
String data = null;
try {
conn = (HttpURLConnection) new URL("https://api.openweathermap.org/data/2.5/forecast?q=London,us&units=metric&appid=ID...").openConnection();
conn.setRequestMethod("GET");
conn.connect();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
sb.append(line + "\n");
}
br.close();
data = sb.toString();
} catch (Exception e) {
// do something
} finally {
if (conn != null) {
try {
conn.disconnect();
} catch (Exception ex) {
// do something
}
}
}
JSONObject reader = new JSONObject(data);
This code will retrieve the JSON object from the endpoint and convert it to a String object. Then you can create a JSONObject with it.

com.fasterxml.jackson.databind.JsonMappingException while sending Json

I am not able to send JsonObject through rest controller:
Failed to write HTTP message: org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: JsonObject; nested exception is com.fasterxml.jackson.databind.JsonMappingException: JsonObject (through reference chain: com.google.gson.JsonObject[0]->com.google.gson.JsonObject["asString"])
private String str = "{ \"document\": [\n" +
" {\n" +
" \"file\": \"PayrollFAQ.pdf\",\n" +
" \"type\": \"pdf\",\n" +
" \"title\": \" FAQ for Payroll\",\n" +
" \"rating\": 4.5,\n" +
" \"confidence\": 0.9\n" +
" }\n" +
" ]}";
#RequestMapping(value = "/posttest", method = RequestMethod.POST, produces="application/json" )
public #ResponseBody ResponseEntity posttest(#RequestBody Information inputReq) {
JsonParser jsonParser = new JsonParser();
List testArray = new ArrayList();
JsonObject objectFromString = jsonParser.parse(str).getAsJsonObject();
testArray.add(HrBotUtilities.getArrayJSON(objectFromString, "document"));
System.out.println("testString : "+testArray.get(0));
return ResponseEntity.status(HttpStatus.OK).body(testArray.get(0));
}
// HrBotUtilities.getArrayJSON Method
public static JsonObject[] getArrayJSON(JsonObject docObj, String name) {
JsonObject[] list = null;
if (docObj.has(name)) {
JsonArray json;
json = docObj.getAsJsonArray(name);
int lenFeatures = json.size();
list = new JsonObject[lenFeatures];
for (int j = 0; j < lenFeatures; j++) {
JsonObject f = json.get(j).getAsJsonObject();
list[j] = f;
}
}
return list;
}
Please help me

JSON array elements to ArrayList for JSP

I am trying to add specific values from the following JSON to a Java ArrayList. I would then like to use this ArrayList within a JSP. This is the JSON:
{
"page": 1,
"rpp": 3,
"total": 3294,
"request_time": "2018-04-23T16:10:20+01:00",
"stops": [
{
"atcocode": "370023715",
"longitude": -1.46616,
"latitude": 53.38248,
"distance": 57
},
{
"atcocode": "370027281",
"longitude": -1.46583,
"latitude": 53.38228,
"distance": 77
},
{
"atcocode": "370022803",
"longitude": -1.46616,
"latitude": 53.38227,
"distance": 80
}
]
}
I would like to add each longitude and latitude elements from under the "stops" subtree into 2 different ArrayLists. This is my attempted code for that:
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{
try {
String json = readUrl (link);
JsonParser parser = new JsonParser();
JsonElement element = parser . parse (json);
if (element.isJsonObject()) {
JsonObject bus = element . getAsJsonObject ();
JsonArray array = bus . getAsJsonArray ("stops");
for (int i = 0; i < array.size(); i++) {
List<String> longitudes = new ArrayList<String>();
List<String> latitudes = new ArrayList<String>();
longitudes.add(array.get(i)).get("longitude");
latitudes.add(array.get(i)).get("latitude");
request.setAttribute("longitudes", longitudes);
request.setAttribute("latitudes", latitudes);
RequestDispatcher dispatcher = request . getRequestDispatcher ("latlong.jsp");
dispatcher.forward(request, response);
}
}
}
}
i get the following error of: "error: incompatible types: JsonElement cannot be converted to String"
Thank you in advance!
One other error you have is that the longitudes, latitudes lists are inside of the loop.
Here is a simple testable piece of code which extracts the data from the JSON and can be tested locally. You can adapt it to your purposes ...
public static void main(String[] args) {
String json = "{\n" +
"\"page\": 1,\n" +
"\"rpp\": 3,\n" +
"\"total\": 3294,\n" +
"\"request_time\": \"2018-04-23T16:10:20+01:00\",\n" +
"\"stops\": [\n" +
"{\n" +
" \"atcocode\": \"370023715\",\n" +
" \"longitude\": -1.46616,\n" +
" \"latitude\": 53.38248,\n" +
" \"distance\": 57\n" +
"},\n" +
"{\n" +
" \"atcocode\": \"370027281\", \n" +
" \"longitude\": -1.46583,\n" +
" \"latitude\": 53.38228,\n" +
" \"distance\": 77\n" +
"},\n" +
"{\n" +
" \"atcocode\": \"370022803\",\n" +
" \"longitude\": -1.46616,\n" +
" \"latitude\": 53.38227,\n" +
" \"distance\": 80\n" +
" }\n" +
"]\n" +
"}";
JsonParser jsonParser = new JsonParser();
JsonElement element = jsonParser.parse(json);
List<String> longitudes = new ArrayList<>();
List<String> latitudes = new ArrayList<>();
if (element.isJsonObject()) {
JsonObject bus = element . getAsJsonObject ();
JsonArray array = bus.getAsJsonArray("stops");
array.forEach(jsonElement -> {
extractToList(longitudes, (JsonObject) jsonElement, "longitude");
extractToList(latitudes, (JsonObject) jsonElement, "latitude");
});
}
System.out.println(longitudes);
System.out.println(latitudes);
}
private static void extractToList(List<String> list, JsonObject jsonElement, String field) {
final JsonElement longitude = jsonElement.get(field);
if(longitude != null) {
list.add(longitude.getAsString());
}
}
If you run this you get printed out on the console:
[-1.46616, -1.46583, -1.46616]
[53.38248, 53.38228, 53.38227]
I have assumed you are using Google's GSON library.
Instead of
longitudes.add(array.get(i)).get("longitude");
latitudes.add(array.get(i)).get("latitude");
Use
longitudes.add(array.get(i).get("longitude").getAsString());
latitudes.add(array.get(i).get("latitude").getAsString());

How to read Json with Gson

HOw would I go about parsing JSON using the google GSON library? An example of my returned JSON is:
[
{
"title": "Down",
"album": "Down",
"length": 212.61,
"artist": "Jay Sean"
},
{
"title": "Come to Me (Peace)",
"album": "Growing Pains",
"length": 301.844,
"artist": "Mary J Blige"
}
]
This is an array of json objects, is that right? How would I go about extracting this with Gson? This is what im trying but am getting null pointer exceptions:
JsonElement jelement = new JsonParser().parse(jsonInfo);
JsonObject jobject = jelement.getAsJsonObject();
jobject = jobject.getAsJsonObject("");
JsonArray jarray = jobject.getAsJsonArray("");
jobject = jarray.get(0).getAsJsonObject();
String result = jobject.get("title").toString();
You must create a Type instance for List.
class MyObj {
String title;
String album;
double length;
String artist;
}
String json = "[\n" +
" {\n" +
" \"title\": \"Down\",\n" +
" \"album\": \"Down\",\n" +
" \"length\": 212.61,\n" +
" \"artist\": \"Jay Sean\"\n" +
" },\n" +
" {\n" +
" \"title\": \"Come to Me (Peace)\",\n" +
" \"album\": \"Growing Pains\",\n" +
" \"length\": 301.844,\n" +
" \"artist\": \"Mary J Blige\"\n" +
" }\n" +
"]";
Type listType = new TypeToken<List<MyObj>>() {}.getType();
List<MyObj> list = new Gson().fromJson(json, listType);
System.out.println(new Gson().toJson(list));
Gson gson = new Gson();
gson. //a lot methods

Categories

Resources