**版权声明:本文为小斑马伟原创文章,转载请注明出处!
Retrofit:(A type-safe HTTP client for Android and Java)通过注解的方式描述HTTP请求,底层由OKHttp实现 看成是对OKHttp的一次封装,采用注解方式来描述HTTP请求。非常适合RESTFul风格的网络请求,目前版本2.0.0.
一、 RESTful
REST:是 “REpresentational State TRransfer” 的缩写,即"表现层状态转换"。表现层:网络上资源的变现形式(资源:是网络上的一个实体,或者说网络上的具体信息,可以是一段文本、一张图片、一首歌曲、一种服务。总之就是具体的实在。我们可以用一个URI,统一定向符指向它。每种资源对应一个特定的URI,要获取它的资源,就要访问它的URI。因此URI就成为每一个资源的地址,或者独一为二识别符。我们常说的上网就是互联网上的资源的互动,调用它的URI。表现层就是网络资源的一种表现形式。资源是实体信息,它可以多种外在的形式,我们把资源具体呈现出的信息,我们叫它表现层。比如文本可以用txt形式表现,也可以用html形式表现。URI只代表资源的实体。不代表资源的形式。严格上来说,某些文件的后缀名是可以不需要的,因为它是表示格式,表示表现层的范畴。而URI只表示资源的位置。它的具体表现形式,应该在HTTP请求的头部信息中,用Content-Type和Obser形式指定)。
状态转换:客户端通过某种手段使得服务器上资源发生变化,访问一个网站,肯定会涉及到客户端和服务端互动过程,在这个过程中,势必涉及到数据和状态的转换,互联网的协议是HTTP状态的协议,这就意味着所有的状态必须保存在服务器端,如果客户端要操作数据,就必须通过某种手段,让服务器端发生状态转换。而这种转化是建立在表现层上的,所以就是表现层的状态转换。而客户端使用的手段,只能是HTTP的协议,具体的说就是HTPP里面具体四个操作符的动词,GET POST PATH DELETE。
二、 RESRful架构
- 1、每一个URI代表一种资源,而不是对资源的一种操作。
- 2、客户端和服务器之间,传递这种资源的某种表现层。
- 3、客户端通过HTTP动作,对服务端资源进行操作。
三、Retrofit引入
compile’com.squareup.retrofit2:retrofit:2.0.1'
四、Retrofit请求网络流程*
定义一个URL:http://192.168.31.242:8080/android/user/users
-
3.1 定义一个接口对象
public interface IUserInfo { GET("users") Call
- > getUsers();
}
-
3.2 构造Retrofit对象
Retrofit retrofit = new Retrofit.Builder() .baseUrl("http://192.168.31.242:8080/android/user/") .addConverterFactory(GsonConverterFactory.create()) //json格式转换器 .build();
-
3.3 拿到接口对象的实例
IUserInfo userInfo = retrofit.create(IUserInfo.class);
-
4.3由接口对象生成call对象,并执行网络请求
Call
- > call = userInfo.getUsers();
call.enqueue(new Callback
- >() {
@Override
public void onResponse(Call
- > call, Response
- > response)
{
Log.i(TAG,"onResponse:"+response.body()+"");
}
@Override
public void onFailuse(Call
- >call, Throwable t){}
});
五、Retrofit常用注解 - @Path
1.用于访问zhangsan的信息
http://192.168.1.102:8080/android/user/users/zhangsan
2.用于访问lisi的信息
http://192.168.1.102:8080/android/user/users/lisi
这种风格URL只是符合RESTful的设计风格的,URL只表示资源信息,因为我们在这个URL看不到任何的网络信息的请求。这个请求在我们的html方法中来执行。这种的类型的API就是RESRful的API。
public interface IUserInfo {
@GET("{username}") //占位符 通过传递来到参数进行替换
Call getUser(@Path("username") String username);
}
//Call call = userInfo.getUser("zhangsan")
Call call = userInfo.getUser("lisi");
五、Retrofit常用注解 - @Query
1.用于访问zhangsan的信息
http://192.168.1.102:8080/android/user/users/?name=zhangsan
2.用于访问lisi的信息
http://192.168.1.102:8080/android/user/users/?name=lisi
public interface IUserInfo {
GET("users")
Call> getUsersByName(@Query("name") String name); //定义一个key:name 后面传递来的参数。通过Query注解来拼接,把key:name和后面传递来的name拼接成一个键值对。然后把这个键值对加到URL后面。
}
//Call> call = userInfo.getUserByName("zhangsan");
Call> call = userInfo.getUserByName("lisi");
定义一个key:name 后面传递来的参数。通过Query注解来拼接,把key:name和后面传递来的name拼接成一个键值对。然后把这个键值对加到URL后面。
六、Retrofit常用注解 - @Body(一般用于POST)请求
public interface IUserInfo {
@POST("users")
Call> addUser(@Body User user);
}
Call call = userInfo.addUser(new User(236,"zhangsan")); //把一个json对象的字符串发送给服务器的
通过POST定义是一个POST请求,POST后面的请求的值和baseUrl组成一个完成的请求的URL的路径,然后定义了一个方法addUser添加用户,通过Body注解在调用这个方法的时候,只需要传递一个对象。这个注解自动把这个对象转换成json字符串。添加到我们网络请求的Body中,发给服务器。定义这个接口后,如果我们添加一个张三,通过userInfo事例的addUser方法,传递来一个User就OK。
七、Retrofit常用注解 - @FormUrlEncoded 表示以表单的形式传递键值对。
public interface IUserInfo {
@POST("register")
@FormUrlEncoded
Call register(@Field("userid") String userid, @Field("username") String username);
}
Call call = userInfo.register("123","zhangsan"); //FormUrlEncoded注解自动的将123和zhangsan 以及userid和username拼接成键值对的方式,发送给服务器。
八、Retrofit常用注解 - @Multipart (表示单文件上传)
public interface IUserInfo {
@Multipart //多个Part
@POST("register")
Call register(@Part MultipartBody.Part icon, @Part("userid") RequestBody userid); //1.part 表示上传的文件,第二个part表示是一个键值对,表示用户的ID
}
发起GET请求
private void getRequest() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
IGetInfos getInfos = retrofit.create(IGetInfos.class);
Call call = getInfos.getCategories();
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
ResponseCategory responseCategory = response.body();
Log.i("data","onResponse() success !!");
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
private String baseUrl = "http://35.185.149.228";
private class ResponseCategory {
public int status;
public List date;
public class CategoryMode {
public int id;
public String name;
}
}
private interface IGetInfos {
@GET("user/get-big-direction")
Call getCategories();
}
发起POST上传键值对(登录)
private void postPairs() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
IUserLogin userLogin = retrofit.create(IUserLogin.class);
Call call = userLogin.login("sda","233");
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
RespLoginModel responseCategory = response.body();
Log.i("data","onResponse() success !!");
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
public class RespLoginModel {
public int status;
public User data;
public class User {
private String id;
private String username;
private String avatar;
}
}
public interface IUserLogin{
@POST("user/do-login")
@FormUrlEncoded
Call login(@Field("login-username") String username,@Field("login-password") String password);
}
上传文件
private void upLoad() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(GsonConverterFactory.create())
.build();
IUpLoadIcon upLoadIcon = retrofit.create(IUpLoadIcon.class);
File file = new File(Environment.getExternalStorageDirectory()+"ic_laucher.png");
RequestBody photoBody = RequestBody.create(MediaType.parse("imge/png"),file);
MultipartBody.Part phone = MultipartBody.Part.createFormData("uplaodImg[file]",file.getName(),photoBody);
Call call = upLoadIcon.upLoadIcon(phone);
call.enqueue(new Callback() {
@Override
public void onResponse(Call call, Response response) {
RespUpLoadModel responseCategory = response.body();
Log.i("data","onResponse() success !!");
}
@Override
public void onFailure(Call call, Throwable t) {
}
});
}
public class RespUpLoadModel {
private int status;
private Img data;
private class Img {
private String img_url;
}
}
public interface IUpLoadIcon {
@POST("file/upload-img")
@Multipart
Call upLoadIcon(@Part MultipartBody.Part phone);
}
Retrofit网络请求:本质上是OKHttp完成,而Retrofit仅负责网路请求的接口的封装。实际上就是使用Retrofit的接口封装我们请求的参数Hearder头部,URL信息等等,最后交给OKHttp来完成后续的网路请求操作。在服务端返回数据给我们,OkHttp将原始的接口交给Retrofit。Retrofit根据用户的需求对结果进行不同类型的解析。
Retrofit进行网络请求的主要步骤:
1.创建描述网络请求的接口
定义方法和相应的注解:其内部通过动态代理的模式,将我们接口和它的注解转换成一个HTTP请求,最后再去执行我们的HTTP请求。
接口里面的方法和参数,都必须要用注解的方式标注,否者不标注就会出错。
2.创建Retrofit实例
3.创建网络请求接口实例并配置网络请求参数
4.发送网络请求(异步或者同步)
5.处理服务器返回的数据