1.什么是网络接口
应用程序接口(API:application programming interface)是一组定义、程序及协议的集合,通过 API 接口实现计算机软件之间的相互通信。API 的一个主要功能是提供通用功能集。程序员通过使用 API 函数开发应用程序,从而可以避免编写无用程序,以减轻编程任务。
2.调取网络接口的基本流程
Android端应用程序首先按某种格式向某个URL发送请求数据(request),服务端接收到请求数据之后会给服务端返回相应的数据
3.调取网络接口的方式
常用的方法有两种,分别是post方法和get方法,他们两者的区别是:
1.get是从服务器上获取数据,post是向服务器传送数据。
2.get方式是直接在请求的url地址后面添加请求信息,而post方式是将请求字段放在HEADER里,用户不可见。
3. get传送的数据量较小,不能大于2KB。post传送的数据量较大,一般被默认为不受限制。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
4. get安全性非常低,post安全性较高。但是执行效率却比Post方法好。
建议:
1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;
2、在做数据查询时,建议用Get方式;而在做数据添加、修改或删除时,建议用Post方式;
4.Android发起网络请求的方式
1.java.net包中的HttpURLConnection类
2.第三方框架如OKHttp,Volley,Retrofit等等。
实验室中,我推荐使用Retrofit作为网络请求的标准框架,但是如果你有自己更喜欢的框架,我们并不会做硬性要求。
5.Retrofit的使用
http://square.github.io/retrofit/ Retrofit的说明文档。
1.为什么使用Retrofit
retrofit使用简单性能优越,并且可以和RxJava进行结合,这些优势使它成为了目前最流行的网络请求类库。
2.如何使用
首先我们要在项目中导入Retrofit,这里只讨论AndroidStudio的导入方法:
方法一:在gradle中的dependencies中添加compile 'com.squareup.retrofit2:retrofit:2.1.0'。
方法二:在AndroidStudio2.2版本之前,你可以点击File->Project Structure->app进入如下界面
点击+号选择Library Dependency,输入retrofit进行搜索,选择最新版本即可,比较推荐使用这种方法进行导包。
首先我们需要一个接口
先讲讲GET方法:
Retrofit使用Java接口的方式来编辑http api:
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
在Get中写的是url的后缀如http://write.blog.csdn.net/postedit的postedit,在{}中被@Path的属性代替。
Call的泛型中是所接收数据的类型。
然后这样进行接口调用
你也可以加入Query参数:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
你也可以加入Query参数:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
普通传json:
目前实验室一般以http + json的方式提交请求数据,而如果是单纯提交json数据的接口,Retrofit会自动把实体类的数据转化为json格式
所以在准备调取接口时先写一个请求体的实体类,比如一个登录业务:
public class LoginUser {
public String loginname;
public String password;
public LoginUser(String loginname, String password) {
this.loginname = loginname;
this.password = password;
}
}
那么在接口中写的方法就是这样的:
@POST("NewLifeBeta/TeaLogin")
Call<UserEntity> login(@Body LoginUser loginUser);
关于提交json数据的详细方法我在
另一篇博客中有详细说明。
表单提交:
如果要求用表单提交数据那么:
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
注意:@FormUrlEncoded代表该次请求为表单提交,方法中的@Field参数代表表单的键值对,@Field括号内为key,外面的参数为value。
其他提交格式请参考官方文档,这里我就不再描述了。
还需要一个保存结果的实体类
比如:
public class UserEntity {
@SerializedName("resultCode")
private int resultCode;
@SerializedName("resultMessage")
private String resultMessage;
@SerializedName("data")
private User user;
public UserEntity(int resultCode, String resultMessage, User user) {
this.resultCode = resultCode;
this.resultMessage = resultMessage;
this.user = user;
}
public int getResultCode() {
return resultCode;
}
public void setResultCode(int resultCode) {
this.resultCode = resultCode;
}
public String getResultMessage() {
return resultMessage;
}
public void setResultMessage(String resultMessage) {
this.resultMessage = resultMessage;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
注意:如果你想让返回的json数据直接解析到对应的属性上,你就要引入retrofit的转换工厂,这里推荐gson工厂,在project structure中搜索retrofit找到converter-gson导入即可,然后在属性上方注释@SerializedName("data"),括号内为json的解析字段。
正式开始调用
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("url")
.addConverterFactory(GsonConverterFactory.create())
.build();
RetrofitWork retrofitWork = retrofit.create(RetrofitWork.class);
Call<UserEntity> login = retrofitWork.login(loginUser);
login.enqueue(this);
@Override
public void onResponse(Call<UserEntity> call, Response<UserEntity> response) {
Toast.makeText(MainActivity.this, "success", Toast.LENGTH_SHORT).show();
}
@Override
public void onFailure(Call<UserEntity> call, Throwable t) {
Toast.makeText(MainActivity.this, "fail" + t.toString(), Toast.LENGTH_SHORT).show();
}
注意:1.addConverterFactory(GsonConverterFactory.create())为转换工厂,需要导入对应的包。
2.baseUrl中填入自己的url,建议不要全填,只要填公用部分就可以,可以复用。
3.login后有
几种方法,enqueue为异步执行,execute为同步,一般都采用异步模式调接口,因为网络请求是耗时操作,会阻塞主线程。
4.请求成功时回调onSuccess方法,失败调用onFailure方法,onSuccess中response.body()可返回泛型类型的实体对象。
6.常见案例(具有实验室特色)
1.伪表单提交
特征:看起来是表单提交(然后后端也是这么跟你说的),结果根据键值对进行提交发现不能收到返回。最后发现后端原来是只要接受一个json数据之后再将就送数据中的键值对提取出来,所以在发起请求的时候只要向后端用表单提交的方式提交一个jsonObject对象即可,并且@Field中的参数可以为任意值(包括空).
分辨方法:尝试或者与后端进行交流,看文档基本看不出个所以然。
应对方法:重要的是接口中方法的写法,这种情况的写法应该为
@FormUrlEncoded
@POST("/ReturnSoftContent_json.aspx")
Call<AboutUsEntity> aboutUs(@Field("contenttype") JSONObject jsonObject);
2.真表单提交(method + parament)
这是实验室之后主流的调接口方式,格式为:method:value
parament:value
特征:看一眼就知道啦,一般parament中为一个json对象。
分辨方法:一目了然。
应对方法:
@FormUrlEncoded
@POST("Users.aspx")
Call<RemoteDataResult<UserEntity>> login(@Field("method") String method
, @Field("parament") JSONObject jsonObject);
3.单纯的json提交
特征:就是提交一个json
应对方法:
@POST("NewLifeBeta/TeaLogin")
Call<UserEntity> login(@Body LoginUser loginUser);
这种方法我在上文中有详细描述。
7.总结
由于后端的写法即将统一,所以经过指示,也将android的调取接口方法进行统一,写这篇文章一来告诉大家Retrofit的使用方法以及规范写法,二来也给从未接触网络接口的同学们提供方便,不过凡事自己探索出来才是对自己最有益处的,别人给你铺好了路但是自己没有研究过的话,一旦出了问题根本无从下手,只能四处寻找帮助,所以我建议大家只将这篇文章作为一个参考,因为很多地方我也只是点到为止,许多东西还要留给大家自己摸索(其实我自己对Retrofit也不是全懂,好多东西自己也没有用过),哦对了,老鸟们就不要理我了,如果文章有误,请指出,最后给大家一个扣丁学堂的Retrofit视频作为参考:
点击打开链接