在Android开发时,很多情况下都会用到请求获取接口数据或者请求向服务器提交数据。
目前较为流行的用法是retrofit2与okhttp3相结合进行网络请求
下面介绍具体使用方法:
目录
介绍封装完成的网络请求包retrofit
CallBack接口
ApiService接口
ApiBuilder类
ApiClient类
retrofit包具体使用
插件GsonFormatPlus设置
插件的具体使用
网络请求的具体模板
GET请求
Post提交数据请求
1.首先介绍封装好的网络请求包retrofit:
retrofit包内有2个Java类与两个Java 接口
ApiBuilder类主要是来建立请求头,而ApiClient类则是进行具体的请求并对请求体解析
CallBack接口内是抽象了请求体的两个解析函数,ApiService内是抽象的请求方法接口
具体代码如下:
2. 导入依赖:
implementation 'com.squareup.okhttp3:okhttp:3.11.0' implementation 'com.squareup.retrofit2:retrofit:2.4.0' implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
public interface CallBack
{ public void onResponse(T data); public void onFail(String msg); }
import java.util.Map; import okhttp3.FormBody; import okhttp3.RequestBody; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.http.Body; import retrofit2.http.FieldMap; import retrofit2.http.FormUrlEncoded; import retrofit2.http.GET; import retrofit2.http.HeaderMap; import retrofit2.http.POST; import retrofit2.http.Path; import retrofit2.http.Query; import retrofit2.http.QueryMap; import retrofit2.http.Url; public interface ApiService { @GET("{name}") Call
getCityAndCommunityData(@Path(value = "name", encoded = true) String name, @Query("cityId") String id); @GET("{name}") Call getNoticeHtml(@Path(value = "name", encoded = true) String name); @POST() Call post(@HeaderMap Map headers, @Url String url, @Body RequestBody body); @POST() Call post( @Url String url, @Body RequestBody body); @POST() Call post( @Url String url, @Body FormBody body); @POST() Call post(@HeaderMap Map headers, @Url String url); @GET() Call get(@HeaderMap Map headers, @Url String url, @QueryMap Map params); @GET("{name}") Call getPaymentList(@Path(value = "name", encoded = true) String name, @Query("houseId") String houseId, @Query("expenseId") String expenseId); @FormUrlEncoded @POST("{name}") Call postUnitData(@Path("name") String name, @FieldMap Map params); @GET("{name}") Call getBoundCommunity(@Path("name") String name); @POST("{name}") Call submitRepair(@Path(value = "name", encoded = true)String name, @Body RequestBody data); }
import java.util.HashMap; import java.util.Map; import okhttp3.RequestBody; public class ApiBuilder { Map
params ; Map headers ; RequestBody body; String url; public ApiBuilder Body(RequestBody body){ this.body = body; return this; } public ApiBuilder Params(Map params) { this.params.putAll(params); return this; } public ApiBuilder Params(String key, String value) { this.params.put(key, value); return this; } public ApiBuilder Headers(Map headers) { this.headers.putAll(headers); return this; } public ApiBuilder Headers(String key, String value) { this.headers.put(key, value); return this; } public ApiBuilder Url(String url) { this.url = url; return this; } public ApiBuilder(String url) { this.setParams(url); } public ApiBuilder() { this.setParams(null); } private void setParams(String url) { this.url = url; this.params = new HashMap<>(); this.headers = new HashMap<>(); } }
import android.content.Context; import android.util.Log; import com.example.hp.brainpower.constant.ConstantUrl; import com.google.gson.Gson; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import okhttp3.Headers; import okhttp3.ResponseBody; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; import retrofit2.Retrofit; public class ApiClient { private static ApiClient instance; /*** * * 构建 retrofit请求 * */ private final static Retrofit retrofit = new Retrofit.Builder() .baseUrl(ConstantUrl.BASE_URL) //这里是你的根Url,最后要用/结尾 .build(); /** * 获取service实例 * * @return get或者post请求接口 */ public ApiService getService() { return retrofit.create(ApiService.class); } /** * 创建请求单例 * * @return */ public static ApiClient getInstance() { if (instance == null) { synchronized (ApiClient.class) { if (instance == null) { instance = new ApiClient(); } } } return instance; } /** * post请求 带token * * @param builder request构建的参数 包含 url header params * @param onCallback rquest 回调 * @param classOf 指定请求的model类型 */ public
void doPost(ApiBuilder builder, final CallBack onCallback, final Class classOf, Context context) { ApiService service = getService(); Call call; /* call = service.post(builder.url, builder.body);*/ call = service.post(builder.headers, builder.url, builder.body); call.enqueue(new Callback () { @Override public void onResponse(Call call, Response response) { Log.d("kevin", String.valueOf(response)); Object o = null; try { if (response.body() == null) { onCallback.onFail("失败" + response.message() + response.code()); } else { String s = response.body().string(); o = new Gson().fromJson(s, classOf); onCallback.onResponse((T) o); } } catch (IOException e) { e.printStackTrace(); String s = e.toString(); onCallback.onFail("失败"); } } @Override public void onFailure(Call call, Throwable t) { onCallback.onFail(t.getMessage()); Log.d("NET---", t.getMessage()); } }); } /** * get请求 带token * * @param builder request构建的参数 包含 url header params * @param onCallback rquest 回调 * @param classOf 指定请求的model类型 * *
* _ = userId,_t = 请求时间,token = MD5(token+_t) */ public
void doGet(ApiBuilder builder, final CallBack onCallback, final Class classOf, final Context context) { ApiService service = getService(); Call call = service.get(checkHeaders(builder.headers), builder.url, checkParams(builder.params)); call.enqueue(new Callback () { @Override public void onResponse(Call call, Response response) { Log.d("result:", response.toString()); Object o = null; try { if (response.body() == null) { String err = response.errorBody().string(); onCallback.onFail("失败"); Log.i("err", err); } else { o = new Gson().fromJson(response.body().string(), classOf); onCallback.onResponse((T) o); } } catch (IOException e) { e.printStackTrace(); onCallback.onFail("失败"); } catch (Exception e) { e.printStackTrace(); onCallback.onFail("异常"); } } @Override public void onFailure(Call call, Throwable t) { onCallback.onFail(t.getMessage()); Log.d("NET---", t.getMessage()); } }); } /** * get请求 不带token * * @param builder request构建的参数 包含 url header params * @param onCallback rquest 回调 * @param classOf 指定请求的model类型 */ public void doGetSaveSession(ApiBuilder builder, final CallBack onCallback, final Class classOf, final Context context) { ApiService service = getService(); Call call = service.get(checkHeaders(builder.headers), builder.url, checkParams(builder.params)); call.enqueue(new Callback () { @Override public void onResponse(Call call, Response response) { Object o = null; try { if (response.body() != null) { o = new Gson().fromJson(response.body().string(), classOf); onCallback.onResponse((T) o); } else { onCallback.onFail("请检查网络重试"); } } catch (IOException e) { e.printStackTrace(); } Headers headers = response.headers(); List cookies = headers.values("Set-Cookie"); if (cookies.size() > 0) { String s = cookies.get(0); String session = s.substring(0, s.indexOf(";")); Log.i("存session", session); } } @Override public void onFailure(Call call, Throwable t) { onCallback.onFail(t.getMessage()); Log.d("NET---", t.getMessage()); } }); } public static Map checkHeaders(Map headers) { if (headers == null) { headers = new HashMap<>(); } //retrofit的headers的值不能为null,此处做下校验,防止出错 for (Map.Entry entry : headers.entrySet()) { if (entry.getValue() == null) { headers.put(entry.getKey(), ""); } } return headers; } public static Map checkParams(Map params) { if (params == null) { params = new HashMap<>(); } //retrofit的params的值不能为null,此处做下校验,防止出错 for (Map.Entry entry : params.entrySet()) { if (entry.getValue() == null) { params.put(entry.getKey(), ""); } } return params; } }
2.retrofit包的具体使用
首先声明ApiBuilder添加请求链接Url、请求头Headers和请求参数Params
然后调用ApiClient.getInstance()的doGet、doPost、doGetSaveSession方法,进行get或post请求
实体类的生成可以通过Android Studio插件GsonFormatPlus即可
插件的具体设置如下:
插件的具体使用如下:
1.新建类,在类内使用Alt Insert(或者类内右击鼠标点击Generate GsonFormatPlus) 即可打开插件窗口
2.在插件的JSON框内粘贴所要获取的接口数据,例如下列数据:
{"message":"Success","success":true,"data":{"total_sc":71.0,"safe_sc":72.0,"experience_sc":61.0,"finance_sc":57.0,"car_sc":72.0}}
点击Format按钮进行JSON数据的格式化,具体如下图:
点击OK按钮,进行类内属性的生成,如有包装类修改为基本类型:
再点击OK按钮即生成所对应接口数据的实体类
进行GET网络请求的具体模版如下:
ApiBuilder builder=new ApiBuilder() .Url("car")//这里填根Url后的部分 .Headers("token",value)//请求头 键,值 .Params("key",value)//请求参数 键,值 .Params("key",value);//参数可以有多个 ApiClient.getInstance().doGet(builder,new CallBack
(){ //BeanClass为解析接口数据得到的实体类 @Override public void onResponse(BeanClass data) { if (data.isSuccess()){ //获取接口数据成功 //请求体处理 }else { //请求失败处理 Activity.this为当前活动.this Toast.makeText(Activity.this,data.getMsg(),Toast.LENGTH_SHORT).show(); } } @Override public void onFail(String msg) { Toast.makeText(Activity.this,msg,Toast.LENGTH_SHORT).show(); } }, BeanClass.class, this); //doPost请求和doGetSaveSession请求类似上述处理
一般post请求需要向后端提交json格式的数据,这里提交的数据我们可以以请求体的形式上传
- 构建请求体
构建请求体是通过HashMap构建,通过添加键值对来添加提交信息,最后再将字典转成JSONObject格式的字符串
具体代码及注释如下:
HashMap
map=new HashMap<>(); map.put("model_id",mode);//向服务器提交的信息 JSONObject object=new JSONObject(map);#HashMap转JSONObject对象 String str=object.toString();#转换成JSON字符串 RequestBody body=RequestBody.create(MediaType.parse("application/json;charset=UTF-8"),str);#创建请求体,create第一个参数是请求头及编码格式,第二个参数是JSON字符串
- Post请求
发送Post请求
ApiBuilder builder=new ApiBuilder().Url(StringConstant.POST_MODEL).Headers("Content-Type","application/json").Body(body); ApiClient.getInstance().doPost(builder, new CallBack
() { @Override public void onResponse(PostCodeBean data) { if (data.getRes()==0){ Toast.makeText(getContext(),"设置成功",Toast.LENGTH_SHORT).show(); }else{ Toast.makeText(getContext(),"设置失败",Toast.LENGTH_SHORT).show(); } } @Override public void onFail(String msg) { System.out.println(msg); } },PostCodeBean.class,getContext());