概述
随着Google对HttpClient 摒弃,和Volley的逐渐没落,OkHttp开始异军突起,而Retrofit则对okHttp进行了强制依赖。
Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端,
如果看源码会发现其实质上就是对okHttp的封装,使用面向接口的方式进行网络请求,利用动态生成的代理类封装了网络接口请求的底层,
其将请求返回javaBean,对网络认证 REST API进行了很好对支持此,使用Retrofit将会极大的提高我们应用的网络体验。
REST
既然是RESTful架构,那么我们就来看一下什么是REST吧。
REST(REpresentational State Transfer)是一组架构约束条件和原则。
RESTful架构都满足以下规则:
(1)每一个URI代表一种资源;
(2)客户端和服务器之间,传递这种资源的某种表现层;
(3)客户端通过四个HTTP动词,对服务器端资源进行操作,实现”表现层状态转化”。
更多关于REST的介绍:什么是REST - GitHub讲解的非常详细
Maven 依赖
<!-- 引入retrofit -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-jackson</artifactId>
<version>2.3.0</version>
</dependency>
Retrofit配置
@Configuration
public class RetrofitAdapter {
@Value("${portal.server}")
private String portalServer;
public Retrofit getRetrofitAdapter(){
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(portalServer)
.addConverterFactory(JacksonConverterFactory.create())
.build();
return retrofit;
}
@Bean
public AccountAPI getAccountAPI(){
return getRetrofitAdapter().create(AccountAPI.class);
}
public interface AccountAPI {
@GET("account/QueryAccountMetaByEmail") Call<AccountMetaBO> queryAccountMetaByEmail(@Header("loginEmail") String loginEmail);
}
retrofit注解:
方法注解,包含
@GET、@POST、@PUT、@DELETE、@PATH、@HEAD、@OPTIONS、@HTTP。
标记注解,包含
@FormUrlEncoded、@Multipart、@Streaming。
参数注解,包含
@Query,@QueryMap、@Body、@Field,@FieldMap、@Part,@PartMap。
其他注解,
@Path、@Header,@Headers、@Url
@HTTP:可以替代其他方法的任意一种
/**
* method 表示请的方法,不区分大小写
* path表示路径
* hasBody表示是否有请求体
*/
@HTTP(method = "get", path = "users/{user}", hasBody = false)
Call<ResponseBody> getFirstBlog(@Path("user") String user);
@Url:使用全路径复写baseUrl,适用于非统一baseUrl的场景。
@GET
Call<ResponseBody> v3(@Url String url);
@Streaming:用于下载大文件
@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl);
ResponseBody body = response.body();
long fileSize = body.contentLength();
InputStream inputStream = body.byteStream();
@Query,@QueryMap:查询参数,用于GET查询,需要注意的是@QueryMap可以约定是否需要encode
@GET("group/users")
Call<List<User>> groupList(@Query("id") int groupId);
//--> http://baseurl/group/users?id=groupId
Call<List<News>> getNews((@QueryMap(encoded=true) Map<String, String> options);
@Body:用于POST请求体,将实例对象根据转换方式转换为对应的json字符串参数,这个转化方式是GsonConverterFactory定义的。
@POST("add")
Call<List<User>> addUser(@Body User user);
@Field,@FieldMap:Post方式传递简单的键值对需要添加@FormUrlEncoded表示表单提交Content-Type:application/x-www-form-urlencoded
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@Part,@PartMap:用于POST文件上传,其中@Part MultipartBody.Part代表文件,@Part(“key”) RequestBody代表参数,需要添加@Multipart表示支持文件上传的表单,Content-Type: multipart/form-data
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") RequestBody description,
@Part MultipartBody.Part file);
// https://github.com/iPaulPro/aFileChooser/blob/master/aFileChooser/src/com/ipaulpro/afilechooser/utils/FileUtils.java
// use the FileUtils to get the actual file by uri
File file = FileUtils.getFile(this, fileUri);
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
// add another part within the multipart request
String descriptionString = "hello, this is description speaking";
RequestBody description =
RequestBody.create(
MediaType.parse("multipart/form-data"), descriptionString);
@Header:header处理,不能被互相覆盖,用于修饰参数
//动态设置Header值
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
等同于 :
//静态设置Header值
@Headers("Authorization: authorization")//这里authorization就是上面方法里传进来变量的值
@GET("widget/list")
Call<User> getUser()
@Headers 用于修饰方法,用于设置多个Header值:
@Headers({
"Accept: application/vnd.github.v3.full+json",
"User-Agent: Retrofit-Sample-App"
})
@GET("users/{username}")
Call<User> getUser(@Path("username") String username);
更详细的参照Ritorfit简书