Я пытался пару дней заставить SimpleXML работать с Retorfix и проанализировать xml-ответ NOAA.Данные поступают со следующего URL: https://www.aviationweather.gov/adds/dataserver_current/httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=1.5&stationString=KOJA
Я продолжаю получать сообщения об ошибках в поле METAR:
onFailure: NOAA: org.simpleframework.xml.core.ValueRequiredException: невозможноудовлетворить @ org.simpleframework.xml.Attribute (empty =, name =, required = true) в поле 'metar' private us.sensornet.aviationweatherapp.data.noaa.METAR us.sensornet.aviationweatherapp.data.noaa.Data.metar для класса us.sensornet.aviationweatherapp.data.noaa.Data в строке 9
Я попытался изменить тип поля с METAR на String и обратно.Я пробовал разные аннотации.Я не могу понять, в чем проблема.
Для краткости я перечислю здесь только те классы, которые мне важны:
package us.sensornet.aviationweatherapp.data.noaa;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Response {
@SerializedName("errors")
@Expose
private String errors;
@SerializedName("time_Taken_ms")
@Expose
private String time_taken_ms;
@SerializedName("Data_Source")
@Expose
private Data_source data_source;
@SerializedName("Request")
@Expose
private Request request;
@SerializedName("Request_Index")
@Expose
private String request_index;
@SerializedName("Data")
@Expose
private Data data;
@SerializedName("Warnings")
@Expose
private String warnings;
@SerializedName("version")
@Expose
private String version;
public Response() {
/* Empty Constructor */
}
public String getErrors ()
{
return errors;
}
public void setErrors (String errors)
{
this.errors = errors;
}
public String getTime_taken_ms ()
{
return time_taken_ms;
}
public void setTime_taken_ms (String time_taken_ms)
{
this.time_taken_ms = time_taken_ms;
}
public Data_source getData_source ()
{
return data_source;
}
public void setData_source (Data_source data_source)
{
this.data_source = data_source;
}
public Request getRequest ()
{
return request;
}
public void setRequest (Request request)
{
this.request = request;
}
public String getRequest_index ()
{
return request_index;
}
public void setRequest_index (String request_index)
{
this.request_index = request_index;
}
public Data getData ()
{
return data;
}
public void setData (Data data)
{
this.data = data;
}
public String getWarnings ()
{
return warnings;
}
public void setWarnings (String warnings)
{
this.warnings = warnings;
}
public String getVersion ()
{
return version;
}
public void setVersion (String version)
{
this.version = version;
}
@Override
public String toString()
{
return "ClassPojo [errors = "+errors+", time_taken_ms = "+time_taken_ms+", data_source = "+data_source+", request = "+request+", request_index = "+request_index+", data = "+data+", warnings = "+warnings+", version = "+version+"]";
}
}
Класс данных:
package us.sensornet.aviationweatherapp.data.noaa;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
import org.simpleframework.xml.Attribute;
public class Data
{
@SerializedName("num_result")
@Expose
@Attribute(required = false)
private String num_results;
@SerializedName("METAR")
@Expose
@Attribute(required = true)
private METAR metar;
@SerializedName("meta")
@Expose
@Attribute(required = false)
private String meta;
public void setMeta(String meta) {
this.meta = meta;
}
public String getMeta() {
return meta;
}
public String getNum_results ()
{
return num_results;
}
public void setNum_results (String num_results)
{
this.num_results = num_results;
}
public METAR getMetar ()
{
return metar;
}
public void setMETAR (METAR metar)
{
this.metar = metar;
}
@Override
public String toString()
{
return "ClassPojo [num_results = "+num_results+", metar = "+ metar +"]";
}
}
Класс METAR:
package us.sensornet.aviationweatherapp.data.noaa;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class METAR
{
@SerializedName("sea_level_pressure_mb")
@Expose
private String sea_level_pressure_mb;
@SerializedName("wind_dir_degrees")
@Expose
private String wind_dir_degrees;
@SerializedName("altim_in_hg")
@Expose
private String altim_in_hg;
@SerializedName("observation_time")
@Expose
private String observation_time;
@SerializedName("temp_c")
@Expose
private String temp_c;
@SerializedName("visibility_statute_mi")
@Expose
private String visibility_statute_mi;
@SerializedName("flight_category")
@Expose
private String flight_category;
@SerializedName("maxT_c")
@Expose
private String maxT_c;
@SerializedName("raw_text")
@Expose
private String raw_text;
@SerializedName("sky_condition")
@Expose
private Sky_condition[] sky_condition;
@SerializedName("minT_c")
@Expose
private String minT_c;
@SerializedName("dewpoint")
@Expose
private String dewpoint_c;
@SerializedName("metar_type")
@Expose
private String metar_type;
@SerializedName("wind_speed_kt")
@Expose
private String wind_speed_kt;
@SerializedName("three_hr_pressure_tendency_mb")
@Expose
private String three_hr_pressure_tendency_mb;
@SerializedName("longitude")
@Expose
private String longitude;
@SerializedName("latitude")
@Expose
private String latitude;
@SerializedName("station_id")
@Expose
private String station_id;
@SerializedName("elevation_m")
@Expose
private String elevation_m;
@SerializedName("quality_control_flags")
@Expose
private Quality_control_flags quality_control_flags;
public String getSea_level_pressure_mb ()
{
return sea_level_pressure_mb;
}
public void setSea_level_pressure_mb (String sea_level_pressure_mb)
{
this.sea_level_pressure_mb = sea_level_pressure_mb;
}
public String getWind_dir_degrees ()
{
return wind_dir_degrees;
}
public void setWind_dir_degrees (String wind_dir_degrees)
{
this.wind_dir_degrees = wind_dir_degrees;
}
public String getAltim_in_hg ()
{
return altim_in_hg;
}
public void setAltim_in_hg (String altim_in_hg)
{
this.altim_in_hg = altim_in_hg;
}
public String getObservation_time ()
{
return observation_time;
}
public void setObservation_time (String observation_time)
{
this.observation_time = observation_time;
}
public String getTemp_c ()
{
return temp_c;
}
public void setTemp_c (String temp_c)
{
this.temp_c = temp_c;
}
public String getVisibility_statute_mi ()
{
return visibility_statute_mi;
}
public void setVisibility_statute_mi (String visibility_statute_mi)
{
this.visibility_statute_mi = visibility_statute_mi;
}
public String getFlight_category ()
{
return flight_category;
}
public void setFlight_category (String flight_category)
{
this.flight_category = flight_category;
}
public String getMaxT_c ()
{
return maxT_c;
}
public void setMaxT_c (String maxT_c)
{
this.maxT_c = maxT_c;
}
public String getRaw_text ()
{
return raw_text;
}
public void setRaw_text (String raw_text)
{
this.raw_text = raw_text;
}
public Sky_condition[] getSky_condition ()
{
return sky_condition;
}
public void setSky_condition (Sky_condition[] sky_condition)
{
this.sky_condition = sky_condition;
}
public String getMinT_c ()
{
return minT_c;
}
public void setMinT_c (String minT_c)
{
this.minT_c = minT_c;
}
public String getDewpoint_c ()
{
return dewpoint_c;
}
public void setDewpoint_c (String dewpoint_c)
{
this.dewpoint_c = dewpoint_c;
}
public String getMetar_type ()
{
return metar_type;
}
public void setMetar_type (String metar_type)
{
this.metar_type = metar_type;
}
public String getWind_speed_kt ()
{
return wind_speed_kt;
}
public void setWind_speed_kt (String wind_speed_kt)
{
this.wind_speed_kt = wind_speed_kt;
}
public String getThree_hr_pressure_tendency_mb ()
{
return three_hr_pressure_tendency_mb;
}
public void setThree_hr_pressure_tendency_mb (String three_hr_pressure_tendency_mb)
{
this.three_hr_pressure_tendency_mb = three_hr_pressure_tendency_mb;
}
public String getLongitude ()
{
return longitude;
}
public void setLongitude (String longitude)
{
this.longitude = longitude;
}
public String getLatitude ()
{
return latitude;
}
public void setLatitude (String latitude)
{
this.latitude = latitude;
}
public String getStation_id ()
{
return station_id;
}
public void setStation_id (String station_id)
{
this.station_id = station_id;
}
public String getElevation_m ()
{
return elevation_m;
}
public void setElevation_m (String elevation_m)
{
this.elevation_m = elevation_m;
}
public Quality_control_flags getQuality_control_flags ()
{
return quality_control_flags;
}
public void setQuality_control_flags (Quality_control_flags quality_control_flags)
{
this.quality_control_flags = quality_control_flags;
}
@Override
public String toString()
{
return "ClassPojo [sea_level_pressure_mb = "+sea_level_pressure_mb+", wind_dir_degrees = "+wind_dir_degrees+", altim_in_hg = "+altim_in_hg+", observation_time = "+observation_time+", temp_c = "+temp_c+", visibility_statute_mi = "+visibility_statute_mi+", flight_category = "+flight_category+", maxT_c = "+maxT_c+", raw_text = "+raw_text+", sky_condition = "+sky_condition+", minT_c = "+minT_c+", dewpoint_c = "+dewpoint_c+", metar_type = "+metar_type+", wind_speed_kt = "+wind_speed_kt+", three_hr_pressure_tendency_mb = "+three_hr_pressure_tendency_mb+", longitude = "+longitude+", latitude = "+latitude+", station_id = "+station_id+", elevation_m = "+elevation_m+", quality_control_flags = "+quality_control_flags+"]";
}
}
Класс NOAAWeather
package us.sensornet.aviationweatherapp.network.noaaweather;
import org.simpleframework.xml.convert.AnnotationStrategy;
import org.simpleframework.xml.core.Persister;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.simplexml.SimpleXmlConverterFactory;
public class NOAAWeatherClient {
private static Retrofit retrofit = null;
public static Retrofit getClient(String baseUrl) {
OkHttpClient.Builder OkHttpClient = new OkHttpClient.Builder();
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
OkHttpClient.addInterceptor(logging);
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(SimpleXmlConverterFactory.createNonStrict(
new Persister(new AnnotationStrategy())))
.client(OkHttpClient.build())
.build();
}
return retrofit;
}
}
Класс NOAAWeatherService
package us.sensornet.aviationweatherapp.network.noaaweather;
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
import us.sensornet.aviationweatherapp.data.noaa.Response;
public interface NOAAWeatherService {
// dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=1.5&stationString=KBIL
@GET("httpparam?dataSource=metars&requestType=retrieve&format=xml&hoursBeforeNow=1.5")
Call<Response> getMetar(@Query("stationString") String icao);
}
Класс ApiUtil
package us.sensornet.aviationweatherapp.network;
import us.sensornet.aviationweatherapp.network.avwx.AVWXClient;
import us.sensornet.aviationweatherapp.network.avwx.AVWXService;
import us.sensornet.aviationweatherapp.network.geocodexyz.GeoCodeXYZClient;
import us.sensornet.aviationweatherapp.network.geocodexyz.GeoCodeXYZService;
import us.sensornet.aviationweatherapp.network.noaaweather.NOAAWeatherClient;
import us.sensornet.aviationweatherapp.network.noaaweather.NOAAWeatherService;
public class ApiUtil {
public static final String BASE_URL = "https://avwx.rest/api/";
public static final String NOAA_BASE_URL = "https://www.aviationweather.gov/adds/dataserver_current/";
public static final String GEOCODE_BASE_URL = "https://geocode.xyz/";
public static AVWXService getAVWXService() {
return AVWXClient.getClient(BASE_URL).create(AVWXService.class);
}
public static NOAAWeatherService getNOAAWeatherService() {
return NOAAWeatherClient.getClient(NOAA_BASE_URL).create(NOAAWeatherService.class);
}
public static GeoCodeXYZService getGeoCodeService() {
return GeoCodeXYZClient.getClient(GEOCODE_BASE_URL).create(GeoCodeXYZService.class);
}
}
Я включилURL для API с точным запросом, который я делаю.Я попытался включить это здесь, но я либо получаю ошибку форматирования, либо он вырывает теги xml.Так что перейдите по ссылке выше, и вы увидите точный ответ, который я получаю.Спасибо, что взглянули на это:
Я вижу несколько результатов METAR в результатах.Что-то, чего я не видел при тестировании API в браузере перед кодированием.Это может быть проблемой.Однако, пожалуйста, посмотрите на это и дайте мне знать, если есть другие проблемы.Я думаю, что я могу просто сделать список в модели данных? enter code here