retrofit 2.3.0 接入和使用

本文详细介绍了如何接入和使用Retrofit 2.3.0网络框架,包括添加相关依赖,如okhttp、gson等,并通过一个登录接口的实例,展示了如何定义接口类和进行POST请求。文章还讨论了Retrofit 2.0中baseUrl的特殊要求,以及应对不同服务器接口定义策略的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

开门见山,本文记录了如何接入并使用square出品的retrofit网络框架。

一、准备工作

  • 添加retrofit 的依赖(或直接使用jar包)

这边并不能直接连接网络,所以直接下载jar包并使用了

  • 添加okio依赖或引用jar包

添加jar包之后,还要添加okio的jar包,不然会报错

java.lang.NoClassFoundError:okio.Buffer

这里写图片描述

  • 添加converter-gson的依赖或引用jar包

由于代码中要解析数据到实体类里,retrofit是默认用的Gson来转换的,而且官方也给了一个转换的包,使用也很简单,直接用GsonConverterFactory.create()就能直接转换:

         Retrofit retrofit = new Retrofit.Builder().baseUrl(THost.Host)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
  • 添加okhttp的依赖或引用jar包

这里直接下载的最新版的okhttp的jar包,版本为okhttp-3.8.0,如果不加,则会报错:

这里写图片描述

  • 添加Gson的依赖

这里有个坑,就是gson版本不能太低,这边原本使用的是gson 2.2.4,结果请求是正常的,但是解析会出错,无法得到想要的数据,在onFailure方法里打的log如下:

这里写图片描述

请求是正常的,抓包显示返回正常,但是方法里跑不到onResponse,而是进了onFailure,log显示java.lang.NoSuchMethodError: com.google.gson.Gson.newJsonReader

解决方法是用最新的gson包就行了。这边使用的是gson 2.8.0

总结下,添加的依赖就是这些了:

这里写图片描述

二、开始使用

以一个简单的登录为例,需求如下:

请求地址为http://app.test.com/testapp.php

请求方式为POST,参数有username和pwd,以及一个action,通过表单发送到服务器

我们先定义一个接口类,里面有一个login方法

public interface TestApiService {

    @FormUrlEncoded
    @POST("http://app.test.com/testapp.php")
    Call<TPHPResult<TLogin>> login ( @Field("username") String username,
                                     @Field("pwd") String pwd,
                                     @Field("action") String aciton ) ;
} 

这里用注解表明了login方法的参数形式

  • @Field注解代表参数为表单格式,key为username,value在调用的时候传入。
  • @POST注解里面放的是请求的url地址。

由于参数以表单形式提交,所以方法上还要加@FormUrlEncoded注解

然后再在MainActivity里使用这个方法来实现登录:

public class MainActivity extends AppCompatActivity {

    private String token ;
    private int uid ;

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

        Retrofit retrofit = new Retrofit.Builder().baseUrl("http://app.test.com/testapp.php/")
                .addConverterFactory(GsonConverterFactory.create())
                .build();

        TestApiService service = retrofit.create(TestApiService.class);

        Call<TPHPResult<TLogin>> loginCall = service.login("Naruto", "123456","login");

        //enqueue是异步的,所以可以直接在主线程请求网络
        loginCall.enqueue(new Callback<TPHPResult<TLogin>>() {
                @Override
                public void onResponse(Call<TPHPResult<TLogin>> call, Response<TPHPResult<TLogin>> response) {

                    if (response.code() == 200) {
                        TLogin loginInfo = response.body().getData() ;

                        token = loginInfo.getToken() ;
                        uid = loginInfo.getUid() ;

                        getUserInfo();
                    }
                }

                @Override
                public void onFailure(Call<TPHPResult<TLogin>> call, Throwable throwable) {
                    Toast.makeText(MainActivity.this,"登录错误: " + throwable.toString(),Toast.LENGTH_SHORT).show(); ;
                }
            });
    }
}

在上面可以看到,我们的请求地址末尾是不带”/”的,直接请求带”/”的url会报错404 Not Found,但是代码里的baseUrl里的url为何又有”/”呢?

这是因为,在retrofit2.0以后,规定baseUrl里面的url,必须以”/”结尾,不然会报错:

这里写图片描述

这里要打个岔,说明下服务器接口的定义方式了。

一般来说,很多后台开发人员,都会把调用的方法名字直接放到请求url的后面,比如:
http://app.test.com/testapp.php/login
针对这种定义方式,在请求时,就很简单,只需在baseUrl里放http://app.test.com/testapp.php/

Retrofit retrofit = new Retrofit.Builder().baseUrl("http://app.test.com/testapp.php/")
//略...

,然后在login方法的@POST注解里面放上login

@FormUrlEncoded
@POST("login")
Call<TPHPResult<TLogin>> login(...) //略......

就可以拼接成
http://app.test.com/testapp.php/login

然而,也有的后台人员,定义接口时,让客户端把方法名字当做表单参数传过来,如上面的action字段,里面的值为login,就是我们要请求的接口名字。

请求url永远是一样的,通过action来区别各个接口。

这种情况下,如果服务器不做兼容,那么请求的url只能是不带”/”的,不然就会404 Not Found。 但是由于retrofit 2.0的限制,baseUrl里只能是带”/”的url (http://app.test.com/testapp.php/),这样是访问不到服务器的。怎么办呢?

我们可以在@POST里面放真正的请求地址,这样就能覆盖掉baseUrl里面的url了。那么,为什么不把.baseUrl("")去掉,只在@POST里写url呢?这是因为不写会报错呀 :(

这里写图片描述

总结下使用方法:

首先定义请求的接口类(TestApiService),根据接口参数的格式(表单/键值对/body/etc),请求的格式(POST/GET/etc),以及返回结果T(TPHPResult),来声明一个返回值为Call<T>的login方法

然后定义Retrofit 实例retrofig,通过retrofit实例的create方法创建一个接口类的实例service,调用service实例的login方法生成Call对象,然后再enqueue异步将请求发出去,得到结果并在回调中解析。

可以看得出来,实际上retrofit的使用还是很简单的,当然,这也仅仅是入门而已,真正要用到实际业务上,就要考虑架构和封装了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值