现在项目用的的Retrofit 来加载网络,本来之前就应该研究一下的,一直拖到现在。还不晚……
今天好好的研究了一下,记录一下。
首先去官方文档了解,翻译之后发现很多词不达意,凑巧发现一篇文章Android网络请求库 - Say hello to retrofit.对官网的讲解很详细。感兴趣的小伙伴可以去看看。
Retrofit是什么?
Retrofit其实我们可以理解为OKHttp的加强版,,它也是一个网络加载框架。底层是使用OKHttp封装的。准确来说,网络请求的工作本质上是OkHttp完成,而 Retrofit 仅负责网络请求接口的封装。它的一个特点是包含了特别多注解,方便简化你的代码量。并且还支持很多的开源库。
Retrofit的优点
- 解耦
我们在请求接口数据的时候,API接口定义和API接口使用总是相互影响,什么传参、回调等,耦合在一块。有时候我们会考虑一下怎么封装我们的代码让这两个东西不那么耦合,这个就是Retrofit的解耦目标,也是它的最大的特点。
Retrofit为了实现解耦,使用了特别多的设计模式 - 可以配置不同HttpClient来实现网络请求,如OkHttp、HttpClient...
- 支持同步、异步和RxJava
- 可以配置不同的反序列化工具来解析数据,如json、xml...
- 请求速度快,使用非常方便灵活
maven引入jar包
<!-- 引入 retrofit 网络加载框架-->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>org.ligboy.retrofit2</groupId>
<artifactId>converter-fastjson</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-scalars</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>logging-interceptor</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.8.1</version>
</dependency>
使用Retrofit大致分三个步骤:
(1)retrofit将Http API 转化成了java 接口形式,所以我们要提供一个接口类
public interface HttpService {
/**
* 获取公告详情
* @param cardNumber
* @param articleId
* @param sign
* @return
*/
@GET("/message/getArticleDetail")
Call<BaseVO<Article>> getArticle(@Query("cardNumber") String cardNumber, @Query("articleId") String articleId,
@Query("sign") String sign);
}
(2) 创建 HttpConfig
package com.baojian.zhang.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.fastjson.FastJsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;
/**
*
* 功能:网络请求工具<br>
* 作者:张tt<br>
* 时间:2018年8月15日<br>
* 版本:1.0<br>
*
*/
@Configuration
public class HttpConfig {
@Value("${isDebug}")
private boolean isDebug;
// 中心服务器url
@Value("${api.server.url}")
private String apiServerUrl;
private Logger logger = LoggerFactory.getLogger(HttpConfig.class);
/**
* 获取Retrofit
* @return
*/
@Bean
public Retrofit getRetrofit(){
// 创建okhttp客户端
OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
// 调试模式开启打印返回信息
if (isDebug) {
HttpLoggingInterceptor logging = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
@Override
public void log(String message) {
logger.debug(message);
}
});
logging.setLevel(HttpLoggingInterceptor.Level.BASIC);
// 添加log打印
okHttpBuilder.addInterceptor(logging);
}
OkHttpClient okHttpClient = okHttpBuilder.build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(apiServerUrl)
.addConverterFactory(FastJsonConverterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.client(okHttpClient).build();
return retrofit;
}
}
(3) 然后就可以对 HttpService 的方法进行同步或异步的调用进行网络访问,也就是说可以通过call对象获得数据:(可以使用enqueue 或者 execute来执行发起请求,enqueue是是异步执行,而 execute是同步执行。)
/**
* 测试接口调用
* @param cardNUmber
* @return
*/
@RequestMapping(value="getArticle", method=RequestMethod.GET)
@ApiOperation(value="测试接口调用", response=BaseVO.class)
public BaseVO<Article> getArticle (@RequestParam(value="cardNumber", required=true)@ApiParam(name="cardNumber",value="用户卡号") String cardNUmber,
@RequestParam(value="articleId", required=true)@ApiParam(name="articleId", value="文章编号", required=true) String articleId){
try {
// retrofit自动注入
HttpService httpService = retrofit.create(HttpService.class);
BaseVO<Article> body = httpService.getArticle(cardNUmber, articleId, "1").execute().body();
return body;
} catch (IOException e) {
e.printStackTrace();
return new BaseVO<>(11, "服务器内部错误");
}
}
通过上面的三个步骤,我们会发现 Retrofit 的使用非常的方便,尤其是它的注解调用和优雅的API转化为方法。每一个方法都会对应着一个Http的注解,总共有GET, POST, PUT, DELETE,HEAD五个内嵌的注解,参数也支持多项形式。