Retrofit框架例子-@path参数和@Query参数

Retrofit网络通信框架

Retrofit官方Github地址

github官方:retrofit
samples 目录有官方的调用例子
官方教程

引入Retrofit依赖:

//代码仓库地址
repositories {
    maven { url 'https://oss.jfrog.org/libs-snapshot' }
}
//添加如下依赖
dependencies {
    //Retrofit
    compile 'com.squareup.retrofit2:retrofit:2.3.0'
    compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'
    //由于返回的数据为json类型,这里我们需要在studio中添加Gson的依赖:
    compile 'com.squareup.retrofit2:converter-gson:2.3.0'
}

数据源1采用百度反地理编码的web api

http://api.map.baidu.com/telematics/v3/reverseGeocoding?location=116.3017193083,40.050743859593&coord_type=gcj02&output=json&ak=zUCOoHeth4BDeasrlkiGsTuHNeEfizxA&mcode=DB:92:E3:B4:54:9E:68:60:47:DD:0B:8A:75:3D:DA:E1:AB:91:DD:FB;czg.baidumapsdk.demo

Retrofit框架例子-@path参数和@Query参数_第1张图片
image.png

用chrome浏览器访问后的到的json数据,利用android studio 的GsonFormat 插件生成对应的实体类ReverseGeocodingResult

Retrofit框架例子-@path参数和@Query参数_第2张图片
image.png

接口定义 --LocationService接口

为了进一步说明,我法说明的内容放在下面的代码中

/**
 * Created by younghare on 2017/9/26.\
 * Retrofit turns your HTTP API into a Java interface
 *如
 * http://api.map.baidu.com/telematics/v3/reverseGeocoding?location=116.3017193083,40.050743859593&coord_type=gcj02&output=json&ak=zUCOoHeth4BDeasrlkiGsTuHNeEfizxA&mcode=DB:92:E3:B4:54:9E:68:60:47:DD:0B:8A:75:3D:DA:E1:AB:91:DD:FB;czg.baidumapsdk.demo
 * url参数
 *   version=v3
 *   funcType = reverseGeocoding
 * url地址?后面的参数是
 *   location=地理坐标 如:116.3017193083,40.050743859593
 *   coord_type =编码 如: gcj02
 *   output = 输出格式 如:json
 *   ak =apkkey 如 :E4805d16520de693a3fe707cdc962045
 *   mcode =密钥 如:DB:92:E3:B4:54:9E:68:60:47:DD:0B:8A:75:3D:DA:E1:AB:91:DD:FB;czg.baidumapsdk.demo
 *
 *
 */

public interface LocationService {
    static final  String Host = "http://api.map.baidu.com/telematics/";
    /**
     * method 表示请求的方法,区分大小写
     * path表示路径
     * hasBody表示是否有请求体
     */
//    @GET("v3/weather")

    //包括@path参数(Url中多级目录参数)和@Query参数(Url?中带的参数)
    @HTTP(method = "GET", path = "{version}/{funcType}", hasBody = false)
    //url 中有参数用@Path引入   version =v3  ; funcType =reverseGeocoding
    //url 参数在url ? 之后参数用 @Query引入

    retrofit2.Call getReverseGeocoding(@Path("version") String version,@Path("funcType") String funcType,
                                                     @Query("location") String location, @Query("coord_type") String coord_type,
                                                     @Query("output") String output, @Query("ak") String ak,
                                                     @Query("mcode") String mcode
    );


    //没有Url中的path参数
    @GET("reverseGeocoding")
    retrofit2.Call getReverseGeocoding_noPath(
                                                              @Query("location") String location, @Query("coord_type") String coord_type,
                                                              @Query("output") String output, @Query("ak") String ak,
                                                              @Query("mcode") String mcode
    );




}

包含@path和@query参数的调用方法

    private void getDataByRetrofit() {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(LocationService.Host)
                .build();

        
        LocationService locationService =retrofit.create(LocationService.class);
        retrofit2.Call call = locationService.getReverseGeocoding(
                "v3","reverseGeocoding",
                "116.3017193083,40.050743859593","gcj02",
                "json","E4805d16520de693a3fe707cdc962045",
                "DB:92:E3:B4:54:9E:68:60:47:DD:0B:8A:75:3D:DA:E1:AB:91:DD:FB;czg.baidumapsdk.demo"
        );
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    System.out.println(response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }

            @Override
            public void onFailure(Call call, Throwable t) {
                t.printStackTrace();

            }
        });


    }

只包含@Query的调用方法

    private void getDataByRetrofit_noPath() {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("http://api.map.baidu.com/telematics/v3/")
                .build();

        LocationService locationService =retrofit.create(LocationService.class);
        retrofit2.Call call = locationService.getReverseGeocoding_noPath(
                "116.3017193083,40.050743859593","gcj02",
                "json","E4805d16520de693a3fe707cdc962045",
                "DB:92:E3:B4:54:9E:68:60:47:DD:0B:8A:75:3D:DA:E1:AB:91:DD:FB;czg.baidumapsdk.demo"
                );
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    System.out.println(response.body().string());

                    Map> map = response.headers().toMultimap();
                    System.out.println(map.toString());
                } catch (IOException e) {
                    e.printStackTrace();
                }


            }

            @Override
            public void onFailure(Call call, Throwable t) {
                t.printStackTrace();

            }
        });

    }
Retrofit框架例子-@path参数和@Query参数_第3张图片
image.png

很遗憾的是,虽然这样写属于正常,但百度的web api现在控制的越来越多了,
返回结果报错
{"status":220,"message":"APP Referer校验失败"}

{"status":240,"message":"APP 服务被禁用"}

具体原因参见:百度Web api通过定位获取当前城市的天气预报

没办法我用豆瓣的web api 再实现一下,校验一下正确性。

数据源2采用豆瓣的web api

选用下面这个接口不需要@Query参数哦
豆瓣Api V2 - 开发者
https://api.douban.com/v2/book/12220562

Retrofit框架例子-@path参数和@Query参数_第4张图片
image.png

同样我们需要先数据模型Book

Retrofit框架例子-@path参数和@Query参数_第5张图片
图片.png

接口定义 --BookService

/**
 * https://api.douban.com/v2/book/12220562
 * url参数
 *   type=book
 *   bookId = 12220562
 * url地址?后面的参数是---这里没有
 *
 *
 */

public interface BookService {
    static final  String Host = "https://api.douban.com/v2/";
    /**
     * method 表示请求的方法,区分大小写
     * path表示路径
     * hasBody表示是否有请求体
     */
    @HTTP(method = "GET", path = "{type}/{bookId}", hasBody = false)
    //url 中有参数用@Path引入   version =v3  ; funcType =reverseGeocoding
    //url 参数在url ? 之后参数用 @Query引入
    Call getBookInfo(@Path("type") String type, @Path("bookId") String bookId    );

}

调用代码如下


    //包含@path但没有@Query参数的调用方法
    private void getDouBan_BookInfo() {

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BookService.Host)
                .build();


        BookService bookService =retrofit.create(BookService.class);
        retrofit2.Call call = bookService.getBookInfo(
                "book","12220562"

        );
        //call.execute(); //同步请求
        //call.enqueue(callback); //异步请求
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    String bookInfoResult = response.body().string();
                    System.out.println(bookInfoResult);
                    Book book = new Gson().fromJson(bookInfoResult,Book.class);
                    System.out.println(book.getAlt_title());

                } catch (IOException e) {
                    e.printStackTrace();
                }


            }

            @Override
            public void onFailure(Call call, Throwable t) {
                t.printStackTrace();

            }
        });


    }

Retrofit框架例子-@path参数和@Query参数_第6张图片
图片.png

多个参数在URL问号之后,且个数不确定

    @GET("News")
    Call getItem(@QueryMap Map map);

更多用法参考

官方教程
你真的会用Retrofit2吗?Retrofit2完全教程 -
Android】Retrofit网络请求参数注解,@Path、@Query、@QueryMa...

[用 Retrofit 2 简化 HTTP 请求(]https://www.jianshu.com/p/ebd1b37167e9)

你可能感兴趣的:(Retrofit框架例子-@path参数和@Query参数)