美文网首页Android 开发必备网络
Retrofit各个注解的含义及作用(项目经验和单个注解解释)

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

作者: 总会颠沛流离 | 来源:发表于2019-05-06 22:22 被阅读4次
    具体用法参照 Retrofit官网

    简介

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

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

    步骤

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

    1. GET

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

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

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

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

    @GET("trades")
    Call<TradesBean> getItem(@QueryMap Map<String, String> map);

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

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

    其他拼接方式

    @GET
    Call<ImageBean> getImageList3(@Url String url);

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

    2. POST

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

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

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

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

    其他拼接方式

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

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

    3. PUT

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

    4. DELETE

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

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

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

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

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

    1、ApiService

     /**
     * 登录
     */
    @Headers("Content-Type:application/json")
    @POST("user/login")
    Observable<ResponseBody> 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<String, String> 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<ResponseBody> responseBodyObservable = apiServices.login(body);
        responseBodyObservable.observeOn(AndroidSchedulers.mainThread())
                .subscribeOn(Schedulers.io())
                .subscribe(new Observer<ResponseBody>() {
                    @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<ResponseBody> 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<ResponseBody> call = myServer.getDownList(body);
            call.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    try {
                        Log.i("response",response.body().string());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onFailure(Call<ResponseBody> 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<ResponseBody> phoneLogin(@PartMap Map<String, RequestBody> requestBodyMap);
    
    2、当数据量小的情况下用方法2
    /**
     * 登录
     */
    @Multipart
    @POST("users/login")
    Call<JsonObject> phoneLogin(@Part("nickname") RequestBody username, @Part("password")  RequestBody password);
    
    2、转为form-data
     /**
     * 转换为 form-data
     *
     * @param requestDataMap
     * @return
     */
    public static Map<String, RequestBody> generateRequestBody(Map<String, String> requestDataMap) {
        Map<String, RequestBody> 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<InfoBean> 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<InfoBean> observable = myServer.getData("d56ea66e7ee741f498ca51242c8c6394","ad30af17a2ad44fca00a2d3f7e16c004");
        observable.subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Observer<InfoBean>() {
                    @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各个注解的含义及作用(项目经验和单个注解解释)

        本文链接:https://www.haomeiwen.com/subject/njyjoqtx.html