Retrofit基础讲解(上)

一.简介

Retrofit是Square 公司开发的一款正对Android 网络请求的框架。底层基于OkHttp 实现。

Retrofit官网地址:Retrofit

RetrofitGItHub地址GitHub - square/retrofit: A type-safe HTTP client for Android and the JVM

二.注解详解

Retrofit的一大特点就是注解,下面讲解常用的注解

1.和请求方法相关的注解

<1> get

@GET("openapi.dokeyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue")
Call<ResponseBody> getFanYiData();

<2> post

@FormUrlEncoded
@POST("openapi.do")
Call<ResponseBody> login(@Field("keyfrom") String param1, @Field("key") String params2, @Field("type") String param3, @Field("doctype") String param4, @Field("version") String param5, @Field("q") String param6);

<3> head

<4> put

<5> delete

<6> patch

2.和参数相关的注解

<1> Path

用于替换请求地址,作用于方法参数。

@GET("{public}")
Call<BaseResult<List<User>>> getUser(@Path("public") String path);

<2> Field

用于表单字段参数,(需要配合FormUrlEncoded使用)作用于方法参数。

@FormUrlEncoded
@POST("public")
Call<BaseResult> addUser(@Field("userName") String userName);

<3> Multipart

指请求体是一个支持文件上传的Form表单,Content-Type=multipart/form-data,需要和参数类注解@Part,@PartMap搭配使用。

@Multipart
@POST("public")
Call<BaseResult> uploadFile(@Part MultipartBody.Part file);

 @Multipart
@POST("users/image")
Call<BaseResponse<String>> uploadFilesWithParts(@Part() List<MultipartBody.Part> parts);

 @POST("users/image")
Call<BaseResponse<String>> uploadFileWithRequestBody(@Body  MultipartBody multipartBody);

注意:

使用@Multipart注解方法,并用@Part注解方法参数,类型是List< okhttp3.MultipartBody.Part>。
不使用@Multipart注解方法,直接使用@Body注解方法参数,类型是okhttp3.MultipartBody。

<4> FormUrlEncoded

指请求体是一个Form表单,Content-Type=application/x-www-form-urlencoded,需要和参数类注解@Field,@FieldMap搭配使用。

@FormUrlEncoded
@POST("login")
Flowable<HttpResult<UserInfoData>> login(@FieldMap Map<String, String> map);

@FormUrlEncoded
@POST("public")
Call<BaseResult> addUser(@Field("userName") String userName);

<5> Streaming

指响应体的数据以流的形式返回,如果不使用默认会把数据全部加载到内存,所以下载文件时需要加上这个注解。

@Streaming
@GET("download")
Call<ResponseBody> downloadFile();

<6> FieldMap

用于表单字段参数,接收Map实现多个参数,(需要配合FormUrlEncoded使用)作用于方法参数。

@FormUrlEncoded
@POST("public")
Call<BaseResult> addUser(@FieldMap Map<String,String> fieldMap);

<7> Part

用于表单字段参数,适用于文件上传,(需要配合Multipart使用)作用于方法参数。

@Multipart
@POST("public")
Call<BaseResult> uploadFile(@Part MultipartBody.Part file);

<8> PartMap

用于表单字段参数,适用于文件上传,(需要配合Multipart使用)作用于方法参数。

@Multipart
@POST("public")
Call<BaseResult> uploadFile(@PartMap Map<String,RequestBody> RequestBodyMap);

<9> Query

用于条件字段参数,作用于方法参数(主要在GET中使用)。

@GET("public")
Call<BaseResult<List<User>>> getUser(@Query("userId") String userId);

<10> QueryMap

用于条件字段参数,作用于方法参数(主要在GET中使用)。

@GET("public")
Call<BaseResult<List<User>>> getUser(@QueryMap Map<String,String> map);

<11> Body

作用于方法参数。

 @POST("public")
 Call<BaseResult<List<User>>> getUser(@Body( User user);

注意:

<1> 使用Post请求方式

(1) 表单提交:建议使用Field或FieldMap+FormUrlEncoded,以键值对上传到服务器。

(2) JSON提交:建议使用@Body,大部分都是实体类,最后将实体类转换为JSON,上传服务器。



<2> 使用GET请求方式

(1) 建议使用Query或QueryMap都是将参数拼接在url后面的。

三.代码实现

1.Gradle依赖

implementation 'com.squareup.retrofit2:retrofit:2.7.0'

2.接口

package com.wjn.rxdemo.retrofit.only;

import java.util.Map;

import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;

/**
 * 翻译接口
 */
public interface FanYiService {

    /**
     * 翻译模块Get请求
     */

    @GET("openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue")
    Call<ResponseBody> getFanYiByGet();

    /**
     * 翻译模块Post请求 Field方式 单个参数逐一传参
     */

    @FormUrlEncoded
    @POST("openapi.do")
    Call<ResponseBody> getFanYiByPost(@Field("keyfrom") String param1, @Field("key") String params2, @Field("type") String param3, @Field("doctype") String param4, @Field("version") String param5, @Field("q") String param6);

    /**
     * 翻译模块Post请求 FieldMap 集合传参
     */

    @FormUrlEncoded
    @POST("openapi.do")
    Call<ResponseBody> getFanYiByPost(@FieldMap Map<String, String> map);

}

3.测试页面

package com.wjn.networkdemo.retrofit.only;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.wjn.networkdemo.R;

import java.io.IOException;
import java.util.HashMap;

import okhttp3.HttpUrl;
import okhttp3.Request;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;

public class RetrofitActivity extends AppCompatActivity {

    private Retrofit mRetrofit;
    private FanYiService mFanYiService;
    private String mBaseUrl = "http://fanyi.youdao.com/";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_retrofit);

        //获取Retrofit对象
        mRetrofit = new Retrofit.Builder()
                .baseUrl(mBaseUrl)//设置BaseUrl 必须以'/'结尾
                .build();

        //Get请求
        findViewById(R.id.activity_retrofit_textview1).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                getData();
            }
        });

        //Post请求 单一参数
        findViewById(R.id.activity_retrofit_textview2).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                postData();
            }
        });

        //Post请求 集合参数
        findViewById(R.id.activity_retrofit_textview3).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                postMapData();
            }
        });

    }

    /**
     * Retrofit Get请求
     */

    private void getData() {
        if (null != mRetrofit) {
            mFanYiService = mRetrofit.create(FanYiService.class);
            Call<ResponseBody> getCall = mFanYiService.getFanYiByGet();
            getCall.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    if (null == call || null == response) return;

                    //参数call信息打印
                    boolean canceled = call.isCanceled();
                    Request request = call.request();
                    HttpUrl url = request.url();
                    String method = request.method();
                    Log.d("RetrofitActivity", "Get请求onResponse方法canceled----:" + canceled);
                    Log.d("RetrofitActivity", "Get请求onResponse方法url.toString()----:" + url.toString());
                    Log.d("RetrofitActivity", "Get请求onResponse方法method----:" + method);

                    //参数response信息打印
                    String result = null;//报文 获取报文必须判断响应是否成功
                    if (response.isSuccessful()) {
                        try {
                            result = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        String msg = response.toString();
                        int code = response.code();
                        boolean isSuccess = response.isSuccessful();
                        Log.d("RetrofitActivity", "Get请求onResponse方法result----:" + result);
                        Log.d("RetrofitActivity", "Get请求onResponse方法msg----:" + msg);
                        Log.d("RetrofitActivity", "Get请求onResponse方法code----:" + code);
                        Log.d("RetrofitActivity", "Get请求onResponse方法isSuccess----:" + isSuccess);
                    } else {
                        Log.d("RetrofitActivity", "Get请求onResponse方法isSuccess----:" + false);
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    Log.d("RetrofitActivity", "Get请求onFailure方法result2----:" + t.getMessage());
                }
            });
        }
    }

    /**
     * Retrofit Post请求 单一参数
     */

    private void postData() {
        if (null != mRetrofit) {
            mFanYiService = mRetrofit.create(FanYiService.class);
            Call<ResponseBody> postCall = mFanYiService.getFanYiByPost("imoocdict123456", "324273592", "data", "json", "1.1", "red");
            postCall.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    if (null == call || null == response) return;

                    //参数call信息打印
                    boolean canceled = call.isCanceled();
                    Request request = call.request();
                    HttpUrl url = request.url();
                    String method = request.method();
                    Log.d("RetrofitActivity", "Post请求onResponse方法canceled----:" + canceled);
                    Log.d("RetrofitActivity", "Post请求onResponse方法url.toString()----:" + url.toString());
                    Log.d("RetrofitActivity", "Post请求onResponse方法method----:" + method);

                    //参数response信息打印
                    String result = null;//报文 获取报文必须判断响应是否成功
                    if (response.isSuccessful()) {
                        try {
                            result = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        String msg = response.toString();
                        int code = response.code();
                        boolean isSuccess = response.isSuccessful();
                        Log.d("RetrofitActivity", "Post请求onResponse方法result----:" + result);
                        Log.d("RetrofitActivity", "Post请求onResponse方法msg----:" + msg);
                        Log.d("RetrofitActivity", "Post请求onResponse方法code----:" + code);
                        Log.d("RetrofitActivity", "Post请求onResponse方法isSuccess----:" + isSuccess);
                    } else {
                        Log.d("RetrofitActivity", "Post请求onResponse方法isSuccess----:" + false);
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    Log.d("RetrofitActivity", "Post请求onFailure方法result2----:" + t.getMessage());
                }
            });
        }
    }

    /**
     * Retrofit Post请求 集合参数
     */

    private void postMapData() {
        if (null != mRetrofit) {
            mFanYiService = mRetrofit.create(FanYiService.class);
            HashMap<String, String> map = new HashMap<>();
            map.put("keyfrom", "imoocdict123456");
            map.put("key", "324273592");
            map.put("type", "data");
            map.put("doctype", "json");
            map.put("version", "1.1");
            map.put("q", "red");
            Call<ResponseBody> postCall = mFanYiService.getFanYiByPost(map);
            postCall.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    if (null == call || null == response) return;

                    //参数call信息打印
                    boolean canceled = call.isCanceled();
                    Request request = call.request();
                    HttpUrl url = request.url();
                    String method = request.method();
                    Log.d("RetrofitActivity", "Post Map 请求onResponse方法canceled----:" + canceled);
                    Log.d("RetrofitActivity", "Post Map 请求onResponse方法url.toString()----:" + url.toString());
                    Log.d("RetrofitActivity", "Post Map 请求onResponse方法method----:" + method);

                    //参数response信息打印
                    String result = null;//报文 获取报文必须判断响应是否成功
                    if (response.isSuccessful()) {
                        try {
                            result = response.body().string();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        String msg = response.toString();
                        int code = response.code();
                        boolean isSuccess = response.isSuccessful();
                        Log.d("RetrofitActivity", "Post Map 请求onResponse方法result----:" + result);
                        Log.d("RetrofitActivity", "Post Map 请求onResponse方法msg----:" + msg);
                        Log.d("RetrofitActivity", "Post Map 请求onResponse方法code----:" + code);
                        Log.d("RetrofitActivity", "Post Map 请求onResponse方法isSuccess----:" + isSuccess);
                    } else {
                        Log.d("RetrofitActivity", "Post Map 请求onResponse方法isSuccess----:" + false);
                    }
                }

                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
                    Log.d("RetrofitActivity", "Post Map 请求onFailure方法result2----:" + t.getMessage());
                }
            });
        }
    }

}

4.结果

<1> Get请求

D/RetrofitActivity: Get请求onResponse方法canceled----:false



D/RetrofitActivity: Get请求onResponse方法url.toString()----:http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue



D/RetrofitActivity: Get请求onResponse方法method----:GET



D/RetrofitActivity: Get请求onResponse方法result----:{"translation":["蓝色的"],"basic":{"us-phonetic":"bluː","phonetic":"bluː","uk-phonetic":"bluː","explains":["adj. 蓝色的;忧郁的,悲观的;(由于冷或呼吸困难)发青的,青紫的;(电影、玩笑或故事)色情的,黄色的;(肉)未熟的;(政治上)保守的","n. 蓝色;蓝色物品;(牛津或剑桥大学的运动员)蓝色荣誉者;失误;红发人;打架","vt. (使)变成蓝色;把......染成蓝色;给\u2026\u2026上蓝色漂白剂;挥霍(钱财)","n. (Blue) (英、美、加、澳、新)布卢(人名)"]},"query":"blue","errorCode":0,"web":[{"value":["蓝色的","刀枪不入","蓝色橙味糖浆"],"key":"blue"},{"value":["蓝月","蓝月亮","千载难逢的时机"],"key":"Blue Moon"},{"value":["青尼罗省","青尼罗河","蓝色尼罗河"],"key":"Blue Nile"}]}



D/RetrofitActivity: Get请求onResponse方法msg----:Response{protocol=http/1.1, code=200, message=OK, url=http://fanyi.youdao.com/openapi.do?keyfrom=imoocdict123456&key=324273592&type=data&doctype=json&version=1.1&q=blue}



D/RetrofitActivity: Get请求onResponse方法code----:200



D/RetrofitActivity: Get请求onResponse方法isSuccess----:true

<2> Post请求 单个参数逐一传参

D/RetrofitActivity: Post请求onResponse方法canceled----:false



D/RetrofitActivity: Post请求onResponse方法url.toString()----:http://fanyi.youdao.com/openapi.do



D/RetrofitActivity: Post请求onResponse方法method----:POST



D/RetrofitActivity: Post请求onResponse方法result----:{"translation":["红色的"],"basic":{"us-phonetic":"red","phonetic":"red","uk-phonetic":"red","explains":["adj. 红的,红色的;(毛发)红褐色的;(脸)涨红的;(眼睛)红肿的;革命的,激进的;(人)红种的;(纸牌中)红桃的,红方块的;(葡萄酒)红的;(表示停止)红(灯),红(旗);被禁止的,危险的;(滑雪道上用红色标志指示)第二高难度的;(物理)表示夸克三种颜色之一的红色;赤色的(尤指冷战期间用于指前苏联);沾有鲜血的;(古或诗\/文)流血的;(科萨人)来自传统部落文化的","n. 红色,红颜料;红衣;红葡萄酒;红色物(或人);赤字,亏空;激进分子","n. (Red) 雷德(人名)"]},"query":"red","errorCode":0,"web":[{"value":["红","红色","赤焰战场"],"key":"RED"},{"value":["红线","台北捷运红线","红线机油"],"key":"Red Line"},{"value":["红旗","红旗演习","危险信号"],"key":"red flag"}]}



D/RetrofitActivity: Post请求onResponse方法msg----:Response{protocol=http/1.1, code=200, message=OK, url=http://fanyi.youdao.com/openapi.do}



D/RetrofitActivity: Post请求onResponse方法code----:200



D/RetrofitActivity: Post请求onResponse方法isSuccess----:true

<3> 集合方式传参

D/RetrofitActivity: Post Map 请求onResponse方法canceled----:false



D/RetrofitActivity: Post Map 请求onResponse方法url.toString()----:http://fanyi.youdao.com/openapi.do



D/RetrofitActivity: Post Map 请求onResponse方法method----:POST



D/RetrofitActivity: Post Map 请求onResponse方法result----:{"translation":["红色的"],"basic":{"us-phonetic":"red","phonetic":"red","uk-phonetic":"red","explains":["adj. 红的,红色的;(毛发)红褐色的;(脸)涨红的;(眼睛)红肿的;革命的,激进的;(人)红种的;(纸牌中)红桃的,红方块的;(葡萄酒)红的;(表示停止)红(灯),红(旗);被禁止的,危险的;(滑雪道上用红色标志指示)第二高难度的;(物理)表示夸克三种颜色之一的红色;赤色的(尤指冷战期间用于指前苏联);沾有鲜血的;(古或诗\/文)流血的;(科萨人)来自传统部落文化的","n. 红色,红颜料;红衣;红葡萄酒;红色物(或人);赤字,亏空;激进分子","n. (Red) 雷德(人名)"]},"query":"red","errorCode":0,"web":[{"value":["红","红色","赤焰战场"],"key":"RED"},{"value":["红线","台北捷运红线","红线机油"],"key":"Red Line"},{"value":["红旗","红旗演习","危险信号"],"key":"red flag"}]}



D/RetrofitActivity: Post Map 请求onResponse方法msg----:Response{protocol=http/1.1, code=200, message=OK, url=http://fanyi.youdao.com/openapi.do}



D/RetrofitActivity: Post Map 请求onResponse方法code----:200



D/RetrofitActivity: Post Map 请求onResponse方法isSuccess----:true

5.总结

<1> Retrofit的BaseUrl必须以"/"结尾  否则报错

<2> Retrofit的Post请求须加注释  否则报错

<3> Call方法发起请求可以用两种方式一种enqueue异步 一种execute()同步大多数请求会用异步

<4> onResponse回调(即请求成功的回调)中,除了可以拿到请求的报文,还可以拿到很多其他的信息,比如请求码200,比如请求方法,比如请求Url等等。都是很有用的信息。且 获取报文必须判断响应是否成功

<5> 单独使用Retrofit时,如果不配置CONVERTERS 即合成器 (详解见官网) 报文格式只能是  ResponseBody

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值