Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
Improve this question
i want to extract the current weather state as a string (like cloudy, rain...) from the openweather API. The Problem is, that the information is located in weather:0:main: (See here)
I just cant get the information because there is a "0:". I'm new to JSON in java and just need your help.
I recommend you using Gson converter. It helps you to convert a JSON to a Java Class.
Data conversions:
JSON Object - Java class
Array - List<>
Helpful links:
This is the library you need to include (tutorials included) in Java: GSON Converter Git
This is a weather sample of a JSON (example by coordinates): JSON example website
This is an JSON to Class online converter: Jsonschema2pojo generator
You can use jsonschema2pojo to convert the JSON to classes like this:
-----------------------------------com.example.Clouds.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Clouds {
#SerializedName("all")
#Expose
private Integer all;
public Integer getAll() {
return all;
}
public void setAll(Integer all) {
this.all = all;
}
}
-----------------------------------com.example.Coord.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Coord {
#SerializedName("lon")
#Expose
private Integer lon;
#SerializedName("lat")
#Expose
private Integer lat;
public Integer getLon() {
return lon;
}
public void setLon(Integer lon) {
this.lon = lon;
}
public Integer getLat() {
return lat;
}
public void setLat(Integer lat) {
this.lat = lat;
}
}
-----------------------------------com.example.Data.java-----------------------------------
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Data {
#SerializedName("coord")
#Expose
private Coord coord;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("rain")
#Expose
private Rain rain;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("cod")
#Expose
private Integer cod;
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Rain getRain() {
return rain;
}
public void setRain(Rain rain) {
this.rain = rain;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCod() {
return cod;
}
public void setCod(Integer cod) {
this.cod = cod;
}
}
-----------------------------------com.example.Main.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Main {
#SerializedName("temp")
#Expose
private Double temp;
#SerializedName("humidity")
#Expose
private Integer humidity;
#SerializedName("pressure")
#Expose
private Integer pressure;
#SerializedName("temp_min")
#Expose
private Double tempMin;
#SerializedName("temp_max")
#Expose
private Double tempMax;
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public Integer getPressure() {
return pressure;
}
public void setPressure(Integer pressure) {
this.pressure = pressure;
}
public Double getTempMin() {
return tempMin;
}
public void setTempMin(Double tempMin) {
this.tempMin = tempMin;
}
public Double getTempMax() {
return tempMax;
}
public void setTempMax(Double tempMax) {
this.tempMax = tempMax;
}
}
-----------------------------------com.example.Rain.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Rain {
#SerializedName("3h")
#Expose
private Integer _3h;
public Integer get3h() {
return _3h;
}
public void set3h(Integer _3h) {
this._3h = _3h;
}
}
-----------------------------------com.example.Sys.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Sys {
#SerializedName("country")
#Expose
private String country;
#SerializedName("sunrise")
#Expose
private Integer sunrise;
#SerializedName("sunset")
#Expose
private Integer sunset;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Integer getSunrise() {
return sunrise;
}
public void setSunrise(Integer sunrise) {
this.sunrise = sunrise;
}
public Integer getSunset() {
return sunset;
}
public void setSunset(Integer sunset) {
this.sunset = sunset;
}
}
-----------------------------------com.example.Weather.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
-----------------------------------com.example.Wind.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Wind {
#SerializedName("speed")
#Expose
private Double speed;
#SerializedName("deg")
#Expose
private Double deg;
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
public Double getDeg() {
return deg;
}
public void setDeg(Double deg) {
this.deg = deg;
}
}
After all is done you can do something like this in Java:
String config_settings = "Your JSON String";
Gson converter = new Gson();
ConfigSettings settings = converter.fromJson(config_settings , Data.class);
You have to go one step deeper int the JSON Array.
Try getting the JSONObject(0) and then yourJSONObject.getString("main") for example
Related
java.lang.IllegalArgumentException: Only one HTTP method is allowed. Found: GET and PUT.
for method ApiInterface.UpdateCoordinates
i have tried for the last 2 hours to update the coordinates but it ain't working keeps throwing this error
java.lang.IllegalArgumentException: Only one HTTP method is allowed. Found: GET and PUT.
for method ApiInterface.UpdateCoordinates
at retrofit2.Utils.methodError(Utils.java:52)
at retrofit2.Utils.methodError(Utils.java:42)
at retrofit2.RequestFactory$Builder.parseHttpMethodAndPath(RequestFactory.java:251)
at retrofit2.RequestFactory$Builder.parseMethodAnnotation(RequestFactory.java:224)
at retrofit2.RequestFactory$Builder.build(RequestFactory.java:171)
at retrofit2.RequestFactory.parseAnnotations(RequestFactory.java:67)
at retrofit2.ServiceMethod.parseAnnotations(ServiceMethod.java:26)
at retrofit2.Retrofit.loadServiceMethod(Retrofit.java:170)
at retrofit2.Retrofit$1.invoke(Retrofit.java:149)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy0.UpdateCoordinates(Unknown Source)
at com.example.charlo.jkuat_mobile_app.util.LocationService$1.onLocationResult(LocationService.java:54)
Model classes
the update model class
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class GpsUpdate {
#SerializedName("success")
#Expose
private Boolean success;
#SerializedName("data")
#Expose
private Data data;
#SerializedName("message")
#Expose
private String message;
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public Data getData() {
return data;
}
public void setData(Data data) {
this.data = data;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
model class
the data model class
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Data {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("driverid")
#Expose
private Integer driverid;
#SerializedName("companyid")
#Expose
private Integer companyid;
#SerializedName("vehicleid")
#Expose
private Integer vehicleid;
#SerializedName("warehouseid")
#Expose
private Integer warehouseid;
#SerializedName("orders")
#Expose
private Integer orders;
#SerializedName("status")
#Expose
private Integer status;
#SerializedName("latitute")
#Expose
private String latitute;
#SerializedName("longitude")
#Expose
private String longitude;
#SerializedName("tripdate")
#Expose
private String tripdate;
#SerializedName("created_at")
#Expose
private String createdAt;
#SerializedName("updated_at")
#Expose
private String updatedAt;
public Data(String latitute, String longitude) {
this.latitute = latitute;
this.longitude = longitude;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getDriverid() {
return driverid;
}
public void setDriverid(Integer driverid) {
this.driverid = driverid;
}
public Integer getCompanyid() {
return companyid;
}
public void setCompanyid(Integer companyid) {
this.companyid = companyid;
}
public Integer getVehicleid() {
return vehicleid;
}
public void setVehicleid(Integer vehicleid) {
this.vehicleid = vehicleid;
}
public Integer getWarehouseid() {
return warehouseid;
}
public void setWarehouseid(Integer warehouseid) {
this.warehouseid = warehouseid;
}
public Integer getOrders() {
return orders;
}
public void setOrders(Integer orders) {
this.orders = orders;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getLatitute() {
return latitute;
}
public void setLatitute(String latitute) {
this.latitute = latitute;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getTripdate() {
return tripdate;
}
public void setTripdate(String tripdate) {
this.tripdate = tripdate;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public String getUpdatedAt() {
return updatedAt;
}
public void setUpdatedAt(String updatedAt) {
this.updatedAt = updatedAt;
}
}
Interface
interface class
#PUT("update_driver/{dispatchid}?")
Call<GpsUpdate> UpdateCoordinates(#Path("dispatchid") int id, #Field("latitude") String latitude, #Field("longitude") String longitude );
location service class
the update class which sends the coordinates to the backend
#Override
public void onCreate() {
super.onCreate();
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
tokenManager = TokenManager.getInstance(getSharedPreferences("prefs", MODE_PRIVATE));
service = ApiClient.createService(ApiInterface.class);
locationCallback = new LocationCallback(){
#Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
double lat = locationResult.getLastLocation().getLatitude();
double lng = locationResult.getLastLocation().getLongitude();
String latitude = String.valueOf(lat);
String longitude = String.valueOf(lng);
Data data = new Data(latitude,longitude);
Call<GpsUpdate> call = service.UpdateCoordinates(tokenManager.getToken().getDispatchid(),data.getLatitute(), data.getLongitude());
call.enqueue(new Callback<GpsUpdate>() {
#Override
public void onResponse(Call<GpsUpdate> call, Response<GpsUpdate> response) {
}
#Override
public void onFailure(Call<GpsUpdate> call, Throwable t) {
}
});
I think I should have marked this as a duplicate:
Retrofit: how fix "only one http method is allowed. found: get and get"?
Try changing the
#Path("dispatchid") int id
to
#Path("dispatchid") int dispatchid
I'm trying to make a simple weather app. I'm using this API for it. on that same page is a list of parameters in the JSON response. I can search for all the parameters and get a response except for the 'weather' parameter. every time I try that I get an
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 3 path $[0]
error. I'm not sure what's causing it. here's my code.
public class Weather {
private String city;
private OWM owm = new OWM("8984d739fa91d7031fff0e84a3d2c520");
private CurrentWeather currentWeather;
private String weather;
private Clouds cloud;
public Weather() throws APIException {
String API_KEY = "8984d739fa91d7031fff0e84a3d2c520";
String Location = "Brooklyn";
String urlString = "http://api.openweathermap.org/data/2.5/weather?q=" + Location
+ "&appid=" + API_KEY + "&units=imperial";
try {
StringBuilder result = new StringBuilder();
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null){
result.append(line);
}
rd.close();
System.out.println(result);
Map<String, Object> respMap = jsonToMap(result.toString());
Map<String, Object> mainMap = jsonToMap(respMap.get("main").toString());
Map<String, Object> windMap = jsonToMap(respMap.get("wind").toString());
Map<String, Object> cloudsMap = jsonToMap(respMap.get("weather").toString());
// error is here
System.out.println("Current Temperature: " + mainMap.get("temp"));
System.out.println("current humidity " + mainMap.get("humidity"));
System.out.println("clouds " + respMap.get("description"));
// System.out.println("weather conditions: " + cloudsMap.get("main"));
// this always returns null
System.out.println("wind speeds " + windMap.get("speed"));
System.out.println("wind angle: " + windMap.get("deg"));
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Map<String, Object> jsonToMap(String str){
Map<String, Object> map = new Gson().fromJson(
str, new TypeToken<HashMap<String, Object>>() {}.getType()
);
return map;
}
public String getCityName() {
return cityName;
}
public int getCurrentWeather() throws APIException {
owm.setUnit(OWM.Unit.IMPERIAL);
currentWeather = owm.currentWeatherByCityName(this.cityName);
return (int) Math.round(currentWeather.getMainData().getTemp());
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public void setZipCode(String zipCode){
this.zipCode = zipCode;
}
public String getZipCode(){
return this.zipCode;
}
public String getWeather(){
return this.weather;
}
}
I'm not really sure why that one parameter isn't working. I can search anything else fine, so why can't I search the weather parameter?
Edit:
I'm doing this in my try/catch statement. it's giving me a NullPointerException
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
conn.connect();
JsonParser jp = new JsonParser();
JsonElement root = jp.parse(new InputStreamReader((InputStream) conn.getContent()));
JsonObject rootObj = root.getAsJsonObject();
String description = rootObj.get("weather").getAsString();
// name of the array in the json
System.out.println(description);
Instead of blindly considering Hashmap for keyvalues, consider creating pojos, and then parse it.
Create all PoJo for json.
Main.java
public class Weather {
public static void main(String[] args) {
String API_KEY = "8984d739fa91d7031fff0e84a3d2c520";
String Location = "Brooklyn";
String urlString = "http://api.openweathermap.org/data/2.5/weather?q=" + Location
+ "&appid=" + API_KEY + "&units=imperial";
try {
StringBuilder result = new StringBuilder();
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line;
while ((line = rd.readLine()) != null){
result.append(line);
}
rd.close();
System.out.println(result);
com.google.gson.Gson gson=new Gson();
Example finalResult=gson.fromJson(result.toString() , Example.class);
System.out.println(finalResult.getMain().getTemp()); //56.26
System.out.println(finalResult.getMain().getHumidity()); // 54
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Example.java (This pojo is for your json schema)
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Example {
#SerializedName("coord")
#Expose
private Coord coord;
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
#SerializedName("base")
#Expose
private String base;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("visibility")
#Expose
private Integer visibility;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("timezone")
#Expose
private Integer timezone;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("cod")
#Expose
private Integer cod;
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Integer getVisibility() {
return visibility;
}
public void setVisibility(Integer visibility) {
this.visibility = visibility;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public Integer getTimezone() {
return timezone;
}
public void setTimezone(Integer timezone) {
this.timezone = timezone;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCod() {
return cod;
}
public void setCod(Integer cod) {
this.cod = cod;
}
}
Coord.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Coord {
#SerializedName("lon")
#Expose
private Double lon;
#SerializedName("lat")
#Expose
private Double lat;
public Double getLon() {
return lon;
}
public void setLon(Double lon) {
this.lon = lon;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
}
Weather.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
Main.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Main {
#SerializedName("temp")
#Expose
private Double temp;
#SerializedName("pressure")
#Expose
private Integer pressure;
#SerializedName("humidity")
#Expose
private Integer humidity;
#SerializedName("temp_min")
#Expose
private Integer tempMin;
#SerializedName("temp_max")
#Expose
private Double tempMax;
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Integer getPressure() {
return pressure;
}
public void setPressure(Integer pressure) {
this.pressure = pressure;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public Integer getTempMin() {
return tempMin;
}
public void setTempMin(Integer tempMin) {
this.tempMin = tempMin;
}
public Double getTempMax() {
return tempMax;
}
public void setTempMax(Double tempMax) {
this.tempMax = tempMax;
}
}
Wind.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Wind {
#SerializedName("speed")
#Expose
private Double speed;
#SerializedName("deg")
#Expose
private Integer deg;
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
public Integer getDeg() {
return deg;
}
public void setDeg(Integer deg) {
this.deg = deg;
}
}
Clouds.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Clouds {
#SerializedName("all")
#Expose
private Integer all;
public Integer getAll() {
return all;
}
public void setAll(Integer all) {
this.all = all;
}
}
Sys.java
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Sys {
#SerializedName("type")
#Expose
private Integer type;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("message")
#Expose
private Double message;
#SerializedName("country")
#Expose
private String country;
#SerializedName("sunrise")
#Expose
private Integer sunrise;
#SerializedName("sunset")
#Expose
private Integer sunset;
public Integer getType() {
return type;
}
public void setType(Integer type) {
this.type = type;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Double getMessage() {
return message;
}
public void setMessage(Double message) {
this.message = message;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Integer getSunrise() {
return sunrise;
}
public void setSunrise(Integer sunrise) {
this.sunrise = sunrise;
}
public Integer getSunset() {
return sunset;
}
public void setSunset(Integer sunset) {
this.sunset = sunset;
}
}
Map<String, Object> cloudsMap = jsonToMap(respMap.get("weather").toString());
This is the problem. You're trying to parse the weather property of the response as an object (a Map) but it's actually an array.
The best way to parse the Json here is Gson Library
Here first you can create pojo class of response you getting ,after that just pass the response String and get your output.
Gson gson=new Gson();
YourClass result=gson.fromjson(jsonString , YourClass.class);
I am trying to parse a JSON string to Java object.
The JSON string is as follows :
{
"token":"Hn2jqNYe75dOY5Xj2BmZTLAB",
"team_id":"T394M2RS5",
"api_app_id":"AC1UE8Y4C",
"event":{
"type":"message",
"user":"UC1C1D059",
"text":"test",
"client_msg_id":"bf824b77-c2ff-4cf3-b770-278168d006fb",
"ts":"1533637676.000135",
"channel":"DC2A6V4SZ",
"event_ts":"1533637676.000135",
"channel_type":"app_home"
},
"type":"event_callback",
"authed_teams":[
"T394M2RS5"
],
"event_id":"EvC5BPR1N2",
"event_time":1533637676
}
I am using GSON to make the conversion, but i don't know how to
design the Java class, because the JSON contains another object( the event object).
Any suggestion how to make the conversion?
Thanks in advance.
Try to follow documentation. It helps you to convert a JSON to a Java Class.
Data conversions:
JSON Object - Java class
Array - List<>
Helpful links:
This is the library you need to include (tutorials included) in Java: GSON Converter Git
This is a weather sample of a JSON (example by coordinates): JSON example website
This is an JSON to Class online converter: Jsonschema2pojo generator
You can use jsonschema2pojo to convert the JSON to classes like this:
-----------------------------------com.example.Clouds.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Clouds {
#SerializedName("all")
#Expose
private Integer all;
public Integer getAll() {
return all;
}
public void setAll(Integer all) {
this.all = all;
}
}
-----------------------------------com.example.Coord.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Coord {
#SerializedName("lon")
#Expose
private Integer lon;
#SerializedName("lat")
#Expose
private Integer lat;
public Integer getLon() {
return lon;
}
public void setLon(Integer lon) {
this.lon = lon;
}
public Integer getLat() {
return lat;
}
public void setLat(Integer lat) {
this.lat = lat;
}
}
-----------------------------------com.example.Data.java-----------------------------------
package com.example;
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Data {
#SerializedName("coord")
#Expose
private Coord coord;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("rain")
#Expose
private Rain rain;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("cod")
#Expose
private Integer cod;
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Rain getRain() {
return rain;
}
public void setRain(Rain rain) {
this.rain = rain;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCod() {
return cod;
}
public void setCod(Integer cod) {
this.cod = cod;
}
}
-----------------------------------com.example.Main.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Main {
#SerializedName("temp")
#Expose
private Double temp;
#SerializedName("humidity")
#Expose
private Integer humidity;
#SerializedName("pressure")
#Expose
private Integer pressure;
#SerializedName("temp_min")
#Expose
private Double tempMin;
#SerializedName("temp_max")
#Expose
private Double tempMax;
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public Integer getPressure() {
return pressure;
}
public void setPressure(Integer pressure) {
this.pressure = pressure;
}
public Double getTempMin() {
return tempMin;
}
public void setTempMin(Double tempMin) {
this.tempMin = tempMin;
}
public Double getTempMax() {
return tempMax;
}
public void setTempMax(Double tempMax) {
this.tempMax = tempMax;
}
}
-----------------------------------com.example.Rain.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Rain {
#SerializedName("3h")
#Expose
private Integer _3h;
public Integer get3h() {
return _3h;
}
public void set3h(Integer _3h) {
this._3h = _3h;
}
}
-----------------------------------com.example.Sys.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Sys {
#SerializedName("country")
#Expose
private String country;
#SerializedName("sunrise")
#Expose
private Integer sunrise;
#SerializedName("sunset")
#Expose
private Integer sunset;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Integer getSunrise() {
return sunrise;
}
public void setSunrise(Integer sunrise) {
this.sunrise = sunrise;
}
public Integer getSunset() {
return sunset;
}
public void setSunset(Integer sunset) {
this.sunset = sunset;
}
}
-----------------------------------com.example.Weather.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
-----------------------------------com.example.Wind.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Wind {
#SerializedName("speed")
#Expose
private Double speed;
#SerializedName("deg")
#Expose
private Double deg;
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
public Double getDeg() {
return deg;
}
public void setDeg(Double deg) {
this.deg = deg;
}
}
After all is done you can do something like this in Java:
String config_settings = "Your JSON String";
Gson converter = new Gson();
ConfigSettings settings = converter.fromJson(config_settings , Data.class);
This is pretty straightforward:
Map each JSON key to a POJO attribute
Use #SerializedName to customize JSON key
Map nested JSON object to a class
Map [] to array
Map {} to object
And this is your result:
public class YourClass {
private String token;
#SerializedName("team_id"
private String teamId;
#SerializedName("api_app_id")
private String apiAppId;
private Event event;
private String type;
#SerializedName("authed_teams")
private List<String> authedTeams;
.
.
.
}
private class Event {
private String type;
.
.
.
#SerializedName("event_ts")
private string eventTs;
#SerializedName("channel_type")
private String channelType;
}
for GSON Library, you can create a package of classes that is identical to your JSON structure, for this, you can use http://www.jsonschema2pojo.org/ and you can use the
.fromJson() method, to transfer the JSON content to the container class.
Another thing is, you can transfer your JSON to Java Map class instead of creating your own classes.
But if you want it simpler, there are other libraries, for my preference, The easiest one to use is JSON Path: https://github.com/json-path/JsonPath
I am currently working on a kind of weather app. Therefor I have to parse A JSON Object. I use GSON for that.
I always get an error.
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was
BEGIN_ARRAY at line 1 column 224 path $.list[0].weather
The JSON Object looks something like this:
{"city":{"id":1851632,"name":"Shuzenji"},
"coord":{"lon":138.933334,"lat":34.966671},
"country":"JP",
"cod":"200",
"message":0.0045,
"cnt":38,
"list":[{
"dt":1406106000,
"main":{
"temp":298.77,
"temp_min":298.77,
"temp_max":298.774,
"pressure":1005.93,
"sea_level":1018.18,
"grnd_level":1005.93,
"humidity":87,
"temp_kf":0.26},
"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],
"clouds":{"all":88},
"wind":{"speed":5.71,"deg":229.501},
"sys":{"pod":"d"},
"dt_txt":"2014-07-23 09:00:00"},
{
"dt":1406106000,
"main":{
"temp":298.77,
"temp_min":298.77,
"temp_max":298.774,
"pressure":1005.93,
"sea_level":1018.18,
"grnd_level":1005.93,
"humidity":87,
"temp_kf":0.26},
"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],
"clouds":{"all":88},
"wind":{"speed":5.71,"deg":229.501},
"sys":{"pod":"d"},
"dt_txt":"2014-07-23 09:00:00"}
]}
I created all the classes needed the "all in one" object is here:
public class AIOobject {
City city;
Coord coord;
String country;
String cod;
String message;
String cnt;
List[] list;
public AIOobject(City city, Coord coord, String country, String cod, String message, String cnt, List[] list) {
this.city = city;
this.coord = coord;
this.country = country;
this.cod = cod;
this.message = message;
this.cnt = cnt;
this.list = list;
}
}
The other classes are just saving data like:
public class Weather {
String id;
String main;
String description;
String icon;
public Weather(String id, String main, String description, String icon) {
this.id = id;
this.main = main;
this.description = description;
this.icon = icon;
}
}
My question is now why I get this error and how I get solve the problem.
Thanks for all responses
EDIT Fixed the JSON Object
~Paul
after fixing your JSON, you can try using an auto generator to create your gson file.
below is the auto-created file from http://www.jsonschema2pojo.org
-----------------------------------com.example.AIObject.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class AIObject {
#SerializedName("city")
#Expose
private City city;
#SerializedName("coord")
#Expose
private Coord coord;
#SerializedName("country")
#Expose
private String country;
#SerializedName("cod")
#Expose
private String cod;
#SerializedName("message")
#Expose
private Double message;
#SerializedName("cnt")
#Expose
private Integer cnt;
#SerializedName("list")
#Expose
private java.util.List<com.example.List> list = null;
public City getCity() {
return city;
}
public void setCity(City city) {
this.city = city;
}
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCod() {
return cod;
}
public void setCod(String cod) {
this.cod = cod;
}
public Double getMessage() {
return message;
}
public void setMessage(Double message) {
this.message = message;
}
public Integer getCnt() {
return cnt;
}
public void setCnt(Integer cnt) {
this.cnt = cnt;
}
public java.util.List<com.example.List> getList() {
return list;
}
public void setList(java.util.List<com.example.List> list) {
this.list = list;
}
}
-----------------------------------com.example.City.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class City {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
-----------------------------------com.example.Clouds.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Clouds {
#SerializedName("all")
#Expose
private Integer all;
public Integer getAll() {
return all;
}
public void setAll(Integer all) {
this.all = all;
}
}
-----------------------------------com.example.Coord.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Coord {
#SerializedName("lon")
#Expose
private Double lon;
#SerializedName("lat")
#Expose
private Double lat;
public Double getLon() {
return lon;
}
public void setLon(Double lon) {
this.lon = lon;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
}
-----------------------------------com.example.List.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class List {
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("weather")
#Expose
private java.util.List<Weather> weather = null;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("dt_txt")
#Expose
private String dtTxt;
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public java.util.List<Weather> getWeather() {
return weather;
}
public void setWeather(java.util.List<Weather> weather) {
this.weather = weather;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public String getDtTxt() {
return dtTxt;
}
public void setDtTxt(String dtTxt) {
this.dtTxt = dtTxt;
}
}
-----------------------------------com.example.Main.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Main {
#SerializedName("temp")
#Expose
private Double temp;
#SerializedName("temp_min")
#Expose
private Double tempMin;
#SerializedName("temp_max")
#Expose
private Double tempMax;
#SerializedName("pressure")
#Expose
private Double pressure;
#SerializedName("sea_level")
#Expose
private Double seaLevel;
#SerializedName("grnd_level")
#Expose
private Double grndLevel;
#SerializedName("humidity")
#Expose
private Integer humidity;
#SerializedName("temp_kf")
#Expose
private Double tempKf;
public Double getTemp() {
return temp;
}
public void setTemp(Double temp) {
this.temp = temp;
}
public Double getTempMin() {
return tempMin;
}
public void setTempMin(Double tempMin) {
this.tempMin = tempMin;
}
public Double getTempMax() {
return tempMax;
}
public void setTempMax(Double tempMax) {
this.tempMax = tempMax;
}
public Double getPressure() {
return pressure;
}
public void setPressure(Double pressure) {
this.pressure = pressure;
}
public Double getSeaLevel() {
return seaLevel;
}
public void setSeaLevel(Double seaLevel) {
this.seaLevel = seaLevel;
}
public Double getGrndLevel() {
return grndLevel;
}
public void setGrndLevel(Double grndLevel) {
this.grndLevel = grndLevel;
}
public Integer getHumidity() {
return humidity;
}
public void setHumidity(Integer humidity) {
this.humidity = humidity;
}
public Double getTempKf() {
return tempKf;
}
public void setTempKf(Double tempKf) {
this.tempKf = tempKf;
}
}
-----------------------------------com.example.Sys.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Sys {
#SerializedName("pod")
#Expose
private String pod;
public String getPod() {
return pod;
}
public void setPod(String pod) {
this.pod = pod;
}
}
-----------------------------------com.example.Weather.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
-----------------------------------com.example.Wind.java-----------------------------------
package com.example;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Wind {
#SerializedName("speed")
#Expose
private Double speed;
#SerializedName("deg")
#Expose
private Double deg;
public Double getSpeed() {
return speed;
}
public void setSpeed(Double speed) {
this.speed = speed;
}
public Double getDeg() {
return deg;
}
public void setDeg(Double deg) {
this.deg = deg;
}
}
City is missing the end curly brace at the end of the first line in the JSON. It should be:
"city":{"id":1851632,"name":"Shuzenji"}
You are trying to parse the "list" JSONArray as an array. GSON can only convert JSONArrays into a List and that's why changing list form List[] to ArrayList<List> would fix the issue.
So I am trying to make a weather app, the API works but only in certain areas. For now I am just trying to make a Toast of the API to make sure it works before I go on to do the rest of the app.
public class MainActivity extends AppCompatActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Retrofit
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://api.openweathermap.org/data/2.5/")
.addConverterFactory(GsonConverterFactory.create())
.build();
OpenWeatherMapClient api = retrofit.create(OpenWeatherMapClient.class);
Call<DailyWeather> call = api.getDailyWeather();
call.enqueue(new Callback<DailyWeather>()
{
#Override
public void onResponse(Call<DailyWeather> call, Response<DailyWeather> response)
{
Toast.makeText(MainActivity.this, (response.body().getWeather().getDescription()).toString(), Toast.LENGTH_SHORT).show();
for( Weather w : response.body().getWeather())
{
Log.d("Weather", w.getId().toString());
Log.d("Weather", w.getMain().toString());
Log.d("Weather", w.getDescription().toString());
}
}
So this is my MainActivity.java, if I replace getWeather().getDescription()) with .getCoord().getLat()) it works. The only thing I have noticed is the API section for weather is in sqaure brackets.
So if I run my API searching for 'Birmingham,uk' this is the json (after going through an online parser for easy reading'
{
"coord":{
"lon":-1.9,
"lat":52.48
},
"weather":[
{
"id":802,
"main":"Clouds",
"description":"scattered clouds",
"icon":"03d"
}
],
"base":"stations",
"main":{
"temp":282.57,
"pressure":1008,
"humidity":76,
"temp_min":282.15,
"temp_max":283.15
},
For reference I'll leave the Coord and Weather classes I have in case
the error is in there.
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Coord {
#SerializedName("lon")
#Expose
private Double lon;
#SerializedName("lat")
#Expose
private Double lat;
public Double getLon() {
return lon;
}
public void setLon(Double lon) {
this.lon = lon;
}
public Double getLat() {
return lat;
}
public void setLat(Double lat) {
this.lat = lat;
}
}
And
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Weather {
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("main")
#Expose
private String main;
#SerializedName("description")
#Expose
private String description;
#SerializedName("icon")
#Expose
private String icon;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
}
And the DailyWeather class as requested
public class DailyWeather {
#SerializedName("coord")
#Expose
private Coord coord;
#SerializedName("weather")
#Expose
private List<Weather> weather = null;
#SerializedName("base")
#Expose
private String base;
#SerializedName("main")
#Expose
private Main main;
#SerializedName("visibility")
#Expose
private Integer visibility;
#SerializedName("wind")
#Expose
private Wind wind;
#SerializedName("clouds")
#Expose
private Clouds clouds;
#SerializedName("dt")
#Expose
private Integer dt;
#SerializedName("sys")
#Expose
private Sys sys;
#SerializedName("id")
#Expose
private Integer id;
#SerializedName("name")
#Expose
private String name;
#SerializedName("cod")
#Expose
private Integer cod;
public Coord getCoord() {
return coord;
}
public void setCoord(Coord coord) {
this.coord = coord;
}
public List<Weather> getWeather() {
return weather;
}
public void setWeather(List<Weather> weather) {
this.weather = weather;
}
public String getBase() {
return base;
}
public void setBase(String base) {
this.base = base;
}
public Main getMain() {
return main;
}
public void setMain(Main main) {
this.main = main;
}
public Integer getVisibility() {
return visibility;
}
public void setVisibility(Integer visibility) {
this.visibility = visibility;
}
public Wind getWind() {
return wind;
}
public void setWind(Wind wind) {
this.wind = wind;
}
public Clouds getClouds() {
return clouds;
}
public void setClouds(Clouds clouds) {
this.clouds = clouds;
}
public Integer getDt() {
return dt;
}
public void setDt(Integer dt) {
this.dt = dt;
}
public Sys getSys() {
return sys;
}
public void setSys(Sys sys) {
this.sys = sys;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getCod() {
return cod;
}
public void setCod(Integer cod) {
this.cod = cod;
}
}
The weather variable is a list, so to access it you should do:
List<Weather> weatherList = response.body().getWeather();
if(weatherList!=null && !weatherList.isEmpty()){
Toast.makeText(MainActivity.this, (weatherList.get(0).getDescription()).toString(), Toast.LENGTH_SHORT).show();
}
You weren't able to do getWeather().getDescription() because getWeather() returns a list. So you'd need to select an element in the list to only then do getDescription().