使用Retrofit 2映射API

时间:2017-12-28 03:18:56

标签: java android

我正在尝试使用Android应用中来自天气网站的API返回的数据:https://openweathermap.org/current

我使用的是使用邮政编码的GET方法,并在上页显示了响应示例。

这是:

{"coord":{"lon":-122.09,"lat":37.39},
"sys":{"type":3,"id":168940,"message":0.0297,"country":"US","sunrise":1427723751,"sunset":1427768967},
"weather":[{"id":800,"main":"Clear","description":"Sky is Clear","icon":"01n"}],
"base":"stations",
"main":{"temp":285.68,"humidity":74,"pressure":1016.8,"temp_min":284.82,"temp_max":286.48},
"wind":{"speed":0.96,"deg":285.001},
"clouds":{"all":0},
"dt":1427700245,
"id":0,
"name":"Mountain View",
"cod":200}

这是我的"结果"类:

public class WeatherResults {

        private Integer temp;

        public Integer getTemperature() {
            return temp;
        }
    }

这是我写的用于向OpenWeather发送请求的接口:

public interface WeatherClient {

    @GET("/data/2.5/weather?zip={zipcode}&APPID=xxx")
    Call<WeatherResults> weatherReturned(@Query("zipcode") String zipcode);
    //@Path("zip")
}

以下是我与Retrofit 2互动的地方:

Retrofit.Builder builder = new Retrofit.Builder()
                .baseUrl("https://api.openweathermap.org/")
                .addConverterFactory(GsonConverterFactory.create());

        Retrofit retrofit = builder.build();

        WeatherClient client = retrofit.create(WeatherClient.class);
        Call<WeatherResults> call = client.weatherReturned("08003)");

        call.enqueue(new Callback<WeatherResults>()
        {
            @Override
            public void onResponse
            (Call < WeatherResults > call, Response < WeatherResults > response){
                WeatherResults weatherReturned = response.body();
                Log.e("Weather", Integer.toString(weatherReturned.getTemperature()));
         //       Toast.makeText(this, Integer.toString(weatherReturned.getTemperature()), Toast.LENGTH_LONG).show();

            }

            @Override
            public void onFailure (Call < WeatherResults > call, Throwable t){
            Toast.makeText(MainActivity.this, "error", Toast.LENGTH_SHORT).show();
            }
        });

    }

我有两个问题:

  1. 我在Android Studio 3中遇到编译错误:网址查询字符串&#34; zip = {zipcode}&amp; APPID = xxx&#34;一定不能更换块。对于动态查询参数,请使用@Query。我不知道如何解决这个问题。
  2. 我很确定我的结果课中没有正确的代码,但我无法弄清楚它应该是什么样的。
  3. 非常感谢任何帮助。

3 个答案:

答案 0 :(得分:0)

retrofit query parameter url parameter解析错误,您正在使用query parameter。这就是您要格式化public interface WeatherClient { @GET("/data/2.5/weather") Call<WeatherResults> weatherReturned( @Query("zip") String zipcode, @Query("APPID") String appId ); }

的方式
QUANTIZED_UINT8

答案 1 :(得分:0)

  

我在Android Studio 3中遇到编译错误:URL查询字符串“zip = {zipcode}&amp; APPID = xxx”必须没有替换块。对于动态查询参数,请使用@Query。我不明白如何解决这个问题。

错误代码提及的“替换块”是用大括号包围的路径的一部分。在您的情况下,这是E V。当您需要动态路径(如{zipcode})时,会使用此“替换”技术,但您只需要动态查询字符串。为此,您只需使用group/{id}/users注释,Retrofit将自动为您构建查询字符串。

您的原始@Query使用此:@GET。只有/data/2.5/weather?zip={zipcode}&APPID=xxx部分是路径,所以这应该是/data/2.5/weather注释中的全部内容。其余的是查询字符串。您在@GET注释中使用的字符串将用作键,您传递的值将用作值。

总之,你可以通过这个获得你想要的东西:

@Query
  

我很确定我的结果类中没有正确的代码,但我无法弄清楚它应该是什么样的。

这是api响应的格式化和修剪版本:

@GET("/data/2.5/weather")
Call<WeatherResults> weatherReturned(@Query("zip") String zipCode,
                                     @Query("APPID") String appId);

我假设您要查找的{ "coord": {...}, "sys": {...}, "weather": [...], "base": "stations", "main": { "temp": 285.68, "humidity": 74, "pressure": 1016.8, "temp_min": 284.82, "temp_max": 286.48 }, "wind": {...}, "clouds": {...}, "dt": 1427700245, "id": 0, "name": "Mountain View", "cod": 200 } 字段是temp对象的子字段。您的响应类需要表示此顶级对象,因此您需要创建(至少)两个类:一个用于表示main对象,另一个用于表示顶级响应。

main

答案 2 :(得分:0)

  1. Tenten的答案适合排名第一。 你不需要在url上写查询参数,因此只需要这个url&#34; /data/2.5/weather"。

  2. 您的结果类应该与您的json具有相同的结构,并且最低限度应该包含最多的json对象。 您可以使用http://www.jsonschema2pojo.org/之类的工具自动创建pojo,只需确保为Json选择源类型。