我想检索并转换后的JSON响应并将其转换为对象列表。
这是我的JSON响应示例,仅包含两个元素:
{
"nhits":395,
"parameters":{
"dataset":[
"sanisettesparis2011"
],
"timezone":"UTC",
"rows":2,
"format":"json"
},
"records":[
{
"datasetid":"sanisettesparis2011",
"recordid":"cb7aee1791ccce595e97d98fc0f72d05709abf52",
"fields":{
"objectid":10,
"arrondissement":"02",
"nom_voie":"BOULEVARD DE SEBASTOPOL",
"geom_x_y":[
48.864828018946774,
2.351611260829617
],
"geom":{
"type":"Point",
"coordinates":[
2.351611260829617,
48.864828018946774
]
},
"y":129375.048287,
"x":601106.877435,
"numero_voie":"85",
"identifiant":"2/102",
"horaires_ouverture":"6 h - 22 h"
},
"geometry":{
"type":"Point",
"coordinates":[
2.351611260829617,
48.864828018946774
]
},
"record_timestamp":"2018-09-30T22:00:19+00:00"
},
{
"datasetid":"sanisettesparis2011",
"recordid":"a47c22cf2fd31ba6b4a1ac6d1d2c699f92ee659a",
"fields":{
"objectid":12,
"arrondissement":"02",
"nom_voie":"RUE REAUMUR",
"geom_x_y":[
48.86679354449764,
2.34957136374784
],
"geom":{
"type":"Point",
"coordinates":[
2.34957136374784,
48.86679354449764
]
},
"y":129593.588071,
"x":600957.183947,
"numero_voie":"73",
"identifiant":"2/105",
"horaires_ouverture":"6 h - 22 h"
},
"geometry":{
"type":"Point",
"coordinates":[
2.34957136374784,
48.86679354449764
]
},
"record_timestamp":"2018-09-30T22:00:19+00:00"
}
]
}
如您所见,这是一个复杂的JSON响应。我感兴趣的字段如下:
我的改装实现如下:
加强保护
public class RetrofitClientInstance {
private static Retrofit retrofit;
private static final String BASE_URL = "https://opendata.paris.fr/";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
Gson gson =
new GsonBuilder()
.registerTypeAdapter(Toilet.class, new MyDeserializer())
.create();
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
return retrofit;
}
}
MYDESERIALIZER
public class MyDeserializer implements JsonDeserializer<Toilet>
{
@Override
public Toiletdeserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "records" element from the parsed JSON
JsonElement records = je.getAsJsonObject().get("records").getAsJsonArray();
Log.d("test", records.toString());
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(records, Toilet.class);
}
}
GETDATASERVICE
public interface GetDataService {
@GET("api/records/1.0/search/")
Call<List<TestListModel>> getAllToilets(@Query("dataset") String dataset, @Query("rows") int numRows);
}
主要呼叫
GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
Call<List<Toilet>> call = service.getAllToilets("sanisettesparis2011", 1);
call.enqueue(new Callback<List<Toilet>>() {
@Override
public void onResponse(Call<List<Toilet>> call, retrofit2.Response<List<Toilet>> response) {
Log.d(TAG, response.body().toString());
}
@Override
public void onFailure(Call<List<Toilet>> call, Throwable t) {
t.printStackTrace();
if (t instanceof IOException) {
Toast.makeText(SplashActivity.this, "Network error. Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(SplashActivity.this, "Conversion issue", Toast.LENGTH_SHORT).show();
}
}
});
厕所模型
public class Toilet {
@SerializedName("arrondissement")
private int arrondissement;
@SerializedName("nom_voie")
private String street_name;
@SerializedName("geom_x_y")
private double[] coords;
@SerializedName("numero_voie")
private String street_number;
@SerializedName("horaires_ouverture")
private String opening_hours;
public Toilet(int arrondissement, String street_name, double[] coords, String street_number, String opening_hours){
this.arrondissement = arrondissement;
this.street_name = street_name;
this.coords = coords;
this.street_number = street_number;
this.opening_hours = opening_hours;
}
public int getArrondissement() {
return arrondissement;
}
public void setArrondissement(int arrondissement) {
this.arrondissement = arrondissement;
}
public String getStreet_name() {
return street_name;
}
public void setStreet_name(String street_name) {
this.street_name = street_name;
}
public double[] getCoords() {
return coords;
}
public void setCoords(double[] coords) {
this.coords = coords;
}
public String getStreet_number() {
return street_number;
}
public void setStreet_number(String street_number) {
this.street_number = street_number;
}
public String getOpening_hours() {
return opening_hours;
}
public void setOpening_hours(String opening_hours) {
this.opening_hours = opening_hours;
}
}
启动我的应用程序时,出现此错误:
java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $
我想这意味着我的解串器没有正确格式化,但是我不知道如何使用这种JSON响应架构正确实现翻新。
此操作的目标是检索具有我之前列出的属性的Toilet
对象的列表。
感谢您的帮助!
答案 0 :(得分:1)
在Model类下面复制您的JSON
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class Toilet {
/**
* nhits : 395
* parameters : {"dataset":["sanisettesparis2011"],"timezone":"UTC","rows":2,"format":"json"}
* records : [{"datasetid":"sanisettesparis2011","recordid":"cb7aee1791ccce595e97d98fc0f72d05709abf52","fields":{"objectid":10,"arrondissement":"02","nom_voie":"BOULEVARD DE SEBASTOPOL","geom_x_y":[48.864828018946774,2.351611260829617],"geom":{"type":"Point","coordinates":[2.351611260829617,48.864828018946774]},"y":129375.048287,"x":601106.877435,"numero_voie":"85","identifiant":"2/102","horaires_ouverture":"6 h - 22 h"},"geometry":{"type":"Point","coordinates":[2.351611260829617,48.864828018946774]},"record_timestamp":"2018-09-30T22:00:19+00:00"},{"datasetid":"sanisettesparis2011","recordid":"a47c22cf2fd31ba6b4a1ac6d1d2c699f92ee659a","fields":{"objectid":12,"arrondissement":"02","nom_voie":"RUE REAUMUR","geom_x_y":[48.86679354449764,2.34957136374784],"geom":{"type":"Point","coordinates":[2.34957136374784,48.86679354449764]},"y":129593.588071,"x":600957.183947,"numero_voie":"73","identifiant":"2/105","horaires_ouverture":"6 h - 22 h"},"geometry":{"type":"Point","coordinates":[2.34957136374784,48.86679354449764]},"record_timestamp":"2018-09-30T22:00:19+00:00"}]
*/
@SerializedName("nhits")
private int nhits;
@SerializedName("parameters")
private ParametersBean parameters;
@SerializedName("records")
private List<RecordsBean> records;
public int getNhits() {
return nhits;
}
public void setNhits(int nhits) {
this.nhits = nhits;
}
public ParametersBean getParameters() {
return parameters;
}
public void setParameters(ParametersBean parameters) {
this.parameters = parameters;
}
public List<RecordsBean> getRecords() {
return records;
}
public void setRecords(List<RecordsBean> records) {
this.records = records;
}
public static class ParametersBean {
/**
* dataset : ["sanisettesparis2011"]
* timezone : UTC
* rows : 2
* format : json
*/
@SerializedName("timezone")
private String timezone;
@SerializedName("rows")
private int rows;
@SerializedName("format")
private String format;
@SerializedName("dataset")
private List<String> dataset;
public String getTimezone() {
return timezone;
}
public void setTimezone(String timezone) {
this.timezone = timezone;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
public List<String> getDataset() {
return dataset;
}
public void setDataset(List<String> dataset) {
this.dataset = dataset;
}
}
public static class RecordsBean {
/**
* datasetid : sanisettesparis2011
* recordid : cb7aee1791ccce595e97d98fc0f72d05709abf52
* fields : {"objectid":10,"arrondissement":"02","nom_voie":"BOULEVARD DE SEBASTOPOL","geom_x_y":[48.864828018946774,2.351611260829617],"geom":{"type":"Point","coordinates":[2.351611260829617,48.864828018946774]},"y":129375.048287,"x":601106.877435,"numero_voie":"85","identifiant":"2/102","horaires_ouverture":"6 h - 22 h"}
* geometry : {"type":"Point","coordinates":[2.351611260829617,48.864828018946774]}
* record_timestamp : 2018-09-30T22:00:19+00:00
*/
@SerializedName("datasetid")
private String datasetid;
@SerializedName("recordid")
private String recordid;
@SerializedName("fields")
private FieldsBean fields;
@SerializedName("geometry")
private GeometryBean geometry;
@SerializedName("record_timestamp")
private String recordTimestamp;
public String getDatasetid() {
return datasetid;
}
public void setDatasetid(String datasetid) {
this.datasetid = datasetid;
}
public String getRecordid() {
return recordid;
}
public void setRecordid(String recordid) {
this.recordid = recordid;
}
public FieldsBean getFields() {
return fields;
}
public void setFields(FieldsBean fields) {
this.fields = fields;
}
public GeometryBean getGeometry() {
return geometry;
}
public void setGeometry(GeometryBean geometry) {
this.geometry = geometry;
}
public String getRecordTimestamp() {
return recordTimestamp;
}
public void setRecordTimestamp(String recordTimestamp) {
this.recordTimestamp = recordTimestamp;
}
public static class FieldsBean {
/**
* objectid : 10
* arrondissement : 02
* nom_voie : BOULEVARD DE SEBASTOPOL
* geom_x_y : [48.864828018946774,2.351611260829617]
* geom : {"type":"Point","coordinates":[2.351611260829617,48.864828018946774]}
* y : 129375.048287
* x : 601106.877435
* numero_voie : 85
* identifiant : 2/102
* horaires_ouverture : 6 h - 22 h
*/
@SerializedName("objectid")
private int objectid;
@SerializedName("arrondissement")
private String arrondissement;
@SerializedName("nom_voie")
private String nomVoie;
@SerializedName("geom")
private GeomBean geom;
@SerializedName("y")
private double y;
@SerializedName("x")
private double x;
@SerializedName("numero_voie")
private String numeroVoie;
@SerializedName("identifiant")
private String identifiant;
@SerializedName("horaires_ouverture")
private String horairesOuverture;
@SerializedName("geom_x_y")
private List<Double> geomXY;
public int getObjectid() {
return objectid;
}
public void setObjectid(int objectid) {
this.objectid = objectid;
}
public String getArrondissement() {
return arrondissement;
}
public void setArrondissement(String arrondissement) {
this.arrondissement = arrondissement;
}
public String getNomVoie() {
return nomVoie;
}
public void setNomVoie(String nomVoie) {
this.nomVoie = nomVoie;
}
public GeomBean getGeom() {
return geom;
}
public void setGeom(GeomBean geom) {
this.geom = geom;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public String getNumeroVoie() {
return numeroVoie;
}
public void setNumeroVoie(String numeroVoie) {
this.numeroVoie = numeroVoie;
}
public String getIdentifiant() {
return identifiant;
}
public void setIdentifiant(String identifiant) {
this.identifiant = identifiant;
}
public String getHorairesOuverture() {
return horairesOuverture;
}
public void setHorairesOuverture(String horairesOuverture) {
this.horairesOuverture = horairesOuverture;
}
public List<Double> getGeomXY() {
return geomXY;
}
public void setGeomXY(List<Double> geomXY) {
this.geomXY = geomXY;
}
public static class GeomBean {
/**
* type : Point
* coordinates : [2.351611260829617,48.864828018946774]
*/
@SerializedName("type")
private String type;
@SerializedName("coordinates")
private List<Double> coordinates;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Double> getCoordinates() {
return coordinates;
}
public void setCoordinates(List<Double> coordinates) {
this.coordinates = coordinates;
}
}
}
public static class GeometryBean {
/**
* type : Point
* coordinates : [2.351611260829617,48.864828018946774]
*/
@SerializedName("type")
private String type;
@SerializedName("coordinates")
private List<Double> coordinates;
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public List<Double> getCoordinates() {
return coordinates;
}
public void setCoordinates(List<Double> coordinates) {
this.coordinates = coordinates;
}
}
}
}
在从改造中获得响应时,会得到这样的数据
在这里我使用static
位置获取数据
GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
Call<List<Toilet>> call = service.getAllToilets("sanisettesparis2011", 1);
call.enqueue(new Callback<List<Toilet>>() {
@Override
public void onResponse(Call<List<Toilet>> call, retrofit2.Response<List<Toilet>> response) {
Log.d(TAG, response.body().toString());
String arrondissement_0=response.body().getRecords().get(0).getFields().getArrondissement();
String arrondissement_1=response.body().getRecords().get(1).getFields().getArrondissement();
String nom_voie_0=response.body().getRecords().get(0).getFields().getNomVoie();
String nom_voie_1=response.body().getRecords().get(1).getFields().getNomVoie();
double geom_x_y_0=response.body().getRecords().get(0).getFields().getGeomXY().get(0);
double geom_x_y_1=response.body().getRecords().get(0).getFields().getGeomXY().get(1);
String numero_voie_0=response.body().getRecords().get(0).getFields().getNumeroVoie();
String numero_voie_1=response.body().getRecords().get(1).getFields().getNumeroVoie();
String horaires_ouverture_0=response.body().getRecords().get(0).getFields().getHorairesOuverture();
String horaires_ouverture_1=response.body().getRecords().get(1).getFields().getHorairesOuverture();
}
@Override
public void onFailure(Call<List<Toilet>> call, Throwable t) {
t.printStackTrace();
if (t instanceof IOException) {
Toast.makeText(SplashActivity.this, "Network error. Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(SplashActivity.this, "Conversion issue", Toast.LENGTH_SHORT).show();
}
}
});
要为任何响应创建模型类,您可以使用plugin
为GsonFormat
步骤:创建空类>按alt + insert>选择GsonFormat>粘贴JSON>完成
检查这张图片
答案 1 :(得分:0)
首先将您的JSON响应放在JsonSchema2pojo。它将为您提供GSON模型。将这些模型添加到您的项目中。 然后,您可以获取所需的字符串。
GetDataService apiInterface = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
//Example ~ ModelClassName
Call<Example> call = apiInterface.getAllToilets(
dataset,
numRows);
call.enqueue(new Callback<Example>() {
@Override
public void onResponse(Call<Example> call, Response<Example> response) {
if (response.isSuccessful()) {
Example exam = response.body();
String arrondissement = exam.getRecords().getFields().getArrondissement();
//Same for others
} else {
Toasty.error(Main.this,
"Error => " + response.errorBody(), Toast.LENGTH_SHORT).show();
}
}
@Override
public void onFailure(Call<Example> call, Throwable t) {
call.cancel();
Toasty.error(Main.this,
"Error: "+ t.getLocalizedMessage(), Toast.LENGTH_SHORT).show();
}
在需要数据的地方添加它。
答案 2 :(得分:0)
“记录”对象是厕所列表,因此您应该添加另一个仅包含厕所列表的模型(例如,名为“厕所”)