Retrofit各个注解的含义及作用(项目经验和单个注解解释)

具体用法参照 Retrofit官网

简介

提示依赖 https://www.jianshu.com/p/6534f3ef58cc

  • 是一个基于okhttp的网络请求框架
  • 通过注解配置网络请求参数
  • 图片链接和图片上传
  • 支持同步和异步网络请求
  • 支持多种数据的解析,提供对Rxjava的支持
  • 可拓展性好,高度封装,简洁易用

步骤

  • 添加Retrofit库的依赖
  • 创建接收服务器返回数据的类
  • 创建用于描述网络请求的接口
  • 创建 Retrofit 实例
  • 创建 网络请求接口实例 并 配置网络请求参数
  • 发送网络请求(异步 / 同步)
  • 处理数据
image

1. GET

  • http://192.168.43.173/api/trades

//简单的get请求(没有参数)
@GET("trades")
Call getItem();

  • http://192.168.43.173/api/trades/{userId}

//简单的get请求(URL中带有参数)
@GET("News/{userId}")
Call getItem(@Path("userId") String userId);

//简单的get请求(URL中带有两个参数)
@GET("News/{userId}")
Call getItem(@Path("userId") String userId,@Path("type") String type);

  • http://192.168.43.173/api/trades?userId={用户id}

//参数在url问号之后
@GET("trades")
Call getItem(@Query("userId") String userId);

  • http://192.168.43.173/api/trades?userId={用户id}&type={类型}
    (两种方法)

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

@GET("trades")
Call getItem(
@Query("userId") String userId,
@QueryMap Map map);

  • http://www.wanandroid.com/project/list/1/json?cid=294

@GET("{a}/json?")
Call beanCall(@Path("a") int a, @Query("cid") String cid);

其他拼接方式

@GET
Call getImageList3(@Url String url);

@GET
Call getImageList4(@Url String url,@Query("uid") String uid);

2. POST

  • http://192.168.43.173/api/trades/{userId}

//需要补全URL,post的数据只有一条reason
@FormUrlEncoded
@POST("trades/{userId}")
Call postResult(@Path("userId") String userId,
@Field("reason") String reason;

  • http://192.168.43.173/api/trades/{userId}?token={token}

//需要补全URL,问号后需要加token,post的数据只有一条reason
@FormUrlEncoded
@POST("trades/{userId}")
Call postResult(
@Path("userId") String userId,
@Query("token") String token,
@Field("reason") String reason;

//post一个对象
@POST("trades/{userId}")
Call postResult(
@Path("userId") String userId,
@Query("token") String token,
@Body TradesBean bean;

//用不同注解post一个实体
@POST("trades/{userId}")
Call postResult(
@Part("entity") TradesBean bean;

其他拼接方式

@POST("login")
@FormUrlEncoded
Call login1(@Field("username") String username,@Field("password") String pw);

@POST
@FormUrlEncoded
Call login3(@Url String url,@Field("username") String username,@Field("password") String password);

3. PUT

//put一个实体
@PUT("trade/carInfo/{pid}")
Call putInfo
@Path("pid") Int pid,
@Body CarInfoBean carInfoBean;)

4. DELETE

http://192.168.43.173/api/trades/{userId}

//补全url
@DELETE("trades/{userId}")
Call deleteInfo(
@Path("userId") String userId;

http://192.168.43.173/api/trades/{userId}?token={token}

//补全url并且后面还token
@DELETE("trades/{userId}")
Call deleteInfo(
@Path("userId") String userId,
@Query("token") String token;)

5. 以Json格式提交数据 (模拟登录功能)两种方法

1、ApiService

 /**
 * 登录
 */
@Headers("Content-Type:application/json")
@POST("user/login")
Observable login(@Body RequestBody requestBody);

2、创建一个Bean类

public class UserBean {
private String nickname;
private String password;

public UserBean(String nickname, String password) {
    this.nickname = nickname;
    this.password = password;
}

public String getNickname() {
    return nickname;
}

public void setNickname(String nickname) {
    this.nickname = nickname;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

}

3、将Bean类通过Gson转为json体

Gson gson = new Gson();
HashMap map = new HashMap<>();
map.put("nickname", "123456");
map.put("password, "abcdefg");
String jsonBody = gson.toJson(map);

/ / 此时的jsonBody打印出来的结果
// {"password":"abcdefg","nickname":"123456"}

4、Retrofit请求头是否携带 如果请求带请求头 用方法一,如果不带请求头 用方法二,请求头需要添加的数据根据需求自行添加

1、不带请求头
private void useRetrofit(String url) {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    apiServices = retrofit.create(ApiService.class);
}
2、带请求头
   private void useHeaderRetrofit(String url) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            Request request = original.newBuilder()
                    .addHeader("Content-Type", "application/json;charset=utf-8")
                    .build();

            return chain.proceed(request);
        }
    });
    OkHttpClient client = builder.build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(client)
            .build();
    apiServices = retrofit.create(ApiService.class);
}

5、网络请求的代码

   RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), requestBody);
    Observable responseBodyObservable = apiServices.login(body);
    responseBodyObservable.observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io())
            .subscribe(new Observer() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {
                    Log.d("TAG", "e:" + e);
                }

                @Override
                public void onNext(ResponseBody responseBody) {

                    try {
                        String string = responseBody.string();
                        Log.d("TAG", string);
                        callBack.onSuccess((T) string);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

第二种(简单方法)

String base_url = "https://www.firstgainfo.com/firstga/app/news/";

1. ApiService
//requestBody 获取下拉刷新数据
@Headers({"Content-Type:application/json"})
@POST("downListNews")
Call getDownList(@Body RequestBody body);
2 MainActivity中
private void getDownListData(){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(MyServer.base_url)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    MyServer myServer = retrofit.create(MyServer.class);
    JSONObject param = new JSONObject();
    try {
        param.put("userId","d56ea66e7ee741f498ca51242c8c6394");
        param.put("newsId","ad30af17a2ad44fca00a2d3f7e16c004");
        RequestBody body = RequestBody.create(MediaType.parse("application/json"),param.toString());
        Call call = myServer.getDownList(body);
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) {
                try {
                    Log.i("response",response.body().string());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(Call call, Throwable t) {
                Log.i("onFailure",t.getMessage());
            }
        });
    } catch (JSONException e) {
        e.printStackTrace();
    }

}

6 以form-data格式提交数据 (模拟登录功能)

1、ApiService
1、当数据量大的情况下用方法1 推荐此方法 处理数据时方便一些
/**
 * 登录
 */
@Multipart
@POST("users/login")
Observable phoneLogin(@PartMap Map requestBodyMap);
2、当数据量小的情况下用方法2
/**
 * 登录
 */
@Multipart
@POST("users/login")
Call phoneLogin(@Part("nickname") RequestBody username, @Part("password")  RequestBody password);
2、转为form-data
 /**
 * 转换为 form-data
 *
 * @param requestDataMap
 * @return
 */
public static Map generateRequestBody(Map requestDataMap) {
    Map requestBodyMap = new HashMap<>();
    for (String key : requestDataMap.keySet()) {
        RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),
                requestDataMap.get(key) == null ? "" : requestDataMap.get(key));
        requestBodyMap.put(key, requestBody);
    }
    return requestBodyMap;
}
3、Retrofit请求头是否携带 如果请求带请求头 用方法一,如果不带请求头 用方法二
1、不带请求头
 private void useRetrofit(String url) {
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();
    apiServices = retrofit.create(ApiService.class);
}
2、带请求头
  private void useHeaderRetrofit(String url) {
    OkHttpClient.Builder builder = new OkHttpClient.Builder();
    builder.addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request original = chain.request();
            Request request = original.newBuilder()
                    .addHeader("Content-Type", "application/json;charset=utf-8")
                    .build();

            return chain.proceed(request);
        }
    });
    OkHttpClient client = builder.build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .client(client)
            .build();
    apiServices = retrofit.create(ApiService.class);
}

第二种 (简单)

1. ApiService

String base_url = "https://www.firstgainfo.com/firstga/app/news/";

//获取详情数据
@Headers({"Content-Type:application/x-www-form-urlencoded"})
@POST("info")
@FormUrlEncoded
Observable getData(@Field("userId") String userId, @Field("newsId") String newsId);
2. MainActivity
private void getData(){
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(MyServer.base_url)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .build();
    MyServer myServer = retrofit.create(MyServer.class);
    Observable observable = myServer.getData("d56ea66e7ee741f498ca51242c8c6394","ad30af17a2ad44fca00a2d3f7e16c004");
    observable.subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(InfoBean body) {
                    showInfo(body.getData().getContent());
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });

}

拼接经验

  • Path是网址中的参数,例如:trades/{userId}
  • Query是问号后面的参数,例如:trades/{userId}?token={token}
  • QueryMap 相当于多个@Query
  • Field用于Post请求,提交单个数据,然后要加@FormUrlEncoded
  • Body相当于多个@Field,以对象的方式提交
  • @Streaming:用于下载大文件
  • @Header,@Headers、加请求头
Gson解析报错的原因
  • 参数拼接错误
  • 看报错信息,一般封装出问题
  • 对象改为 requestBody给泛型
  • 采用原生解析

单个注解的含义及作用

你可能感兴趣的:(Retrofit各个注解的含义及作用(项目经验和单个注解解释))