表现形式:实体类->第三方框架->服务器返回的jso字符串代表的实体类
优点:用实体类代表请求参数,可以建请求基类。方便管理,且可把网络请求都放一个文件中,避免大量无用代码
缺点:用了反射。其他未知
1.最终表现形式此处是封装okhttp
private void start() {
JiuDianbin bin=new JiuDianbin();
bin.Environment="2";
bin.RegionId=1;
NetCenter.getHotelList(bin, Resonse_HotelList.class, new OkttpUtils.MResponse() {
@Override
public void success(Object object) {
Resonse_HotelList hotelList= (Resonse_HotelList) object;
if(hotelList.Hotels.size()!=0){
HotelBin hotelBin = hotelList.Hotels.get(0);
text.setText(hotelBin.Address);
}
}
@Override
public void faild(String string) {
Log.i("http",string);
}
@Override
public void error(String string) {
Log.i("http",string);
}
});
}
备注:jiudianbin 是请求的实体类,有2个属性,
Resonse_HotelList是网络接口返回的数据的实体类,第三个参数是自定义的一个回调接口。
2.android所有网络请求的方法放在一个文件中 便于管理
public class NetCenter {
/**
* 获取酒店信息
*/
public static<T extends ResponseBaseBin> void getHotelList(Object bin, final Class<T> tClass, final
OkttpUtils.MResponse mresponse){
String url = "xxxxxxxxxxxxxxxxx";
OkttpUtils.sendPost(url,bin,tClass,mresponse);
}
}
备注;此处多了一个url,存放一个项目中所有的网络请求,
ResponseBaseBin是所有网络接口返回的数据的基类,所有的json数据的类 都是继承他,此处有2个属性
一个是状态码一个是消息,当状态码为1时代表成功,为2时代表失败,此处是和后台协商返回的状态码。
StatusCode 和 StatusMessage
3,下面是主要封装的代码
步骤1:首先得把传进来的第二个参数,请求的类,转换成第三方框架需要的类,此处转成okttp需要的RequestBody
步骤2:根据网络请求参数和url,网络请求
步骤3:根据传进来的第三个参数tClass使用Gson转换json数据
步骤4:把转换好的数据传递给回调接口。
步骤5:根据实际情况,此处OKttp返回的数据的接口在子线程,需要进入主线程(很多框架最后都不需要这一步)
下面是具体代码:
package com.example.com.okhttp;
import android.os.Handler;
import android.util.Log;
import com.google.gson.Gson;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
/**
* Created by 胡楠奇 on 2016/12/8.
*/
public class OkttpUtils {
private static Handler handler=new Handler();
public static <T extends ResponseBaseBin> void sendPost(String url, Object bin, final Class<T> tClass, final
MResponse mresponse) {
Log.i("http","请求地址:"+url);
OkHttpClient httpClient = new OkHttpClient();
RequestBody requestBody = ZOkHttpFrom.getRequestBody(bin.getClass(), bin);
Request request=new Request.Builder().url(url).post(requestBody).build();
httpClient.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {//这里是网址找不到就会进入
final String s = e.toString();
handler.post(new Runnable() {
@Override
public void run() {
mresponse.error(s);
}
});
}
@Override
public void onResponse(Call call, final Response response) throws IOException {
final String errocode = response.toString();
if(response.isSuccessful()){
String json = response.body().string();
Log.i("http","返回数据:"+json);
Gson gson=new Gson();
final T t = gson.fromJson(json, tClass);
if(t.StatusCode==1){//这里根据实际情况,此处是后台返回1成功,
handler.post(new Runnable() {//进入主线程
@Override
public void run() {
mresponse.success(t);
}
});
}else{
handler.post(new Runnable() {
@Override
public void run() {
mresponse.faild(t.StatusMessage);
}
});
}
}else{//这里代表服404等错误
handler.post(new Runnable() {
@Override
public void run() {
mresponse.error(errocode);
}
});
}
}
});
}
interface MResponse {
/**
* 请求成功返回,返回状态码显示成功
* @param object
*/
void success(Object object);
/**
* 请求成功,返回的状态码显示失败
* @param string
*/
void faild(String string);
/**
* 网络请求错误,包括链接无效,404等
* @param string
*/
void error(String string);
}
}
4.转换实体类的方法
主要是通过反射然后来将自定义实体类转换成需要的实体类
Field[] field = clazz.getFields()获取所有属性,然后全部转化成字符串
public static RequestBody getRequestBody(Class<?> clazz, Object object){
HashMap<String,Object> data=getValuesHash(clazz,object);
FormBody.Builder builder = new FormBody.Builder();
Iterator<Map.Entry<String,Object>> iter = data.entrySet().iterator();
StringBuilder post=new StringBuilder();
while (iter.hasNext()) {
Map.Entry<String,Object> entry = (Map.Entry<String,Object>) iter.next();
Object value=entry.getValue();
if(TextUtils.isEmpty(String.valueOf(value))||TextUtils.isEmpty(entry.getKey())){
continue;
}
builder.add(entry.getKey(),String.valueOf(value));
post.append(entry.getKey()+"="+String.valueOf(value)+"&");
}
Log.i("http","post数据:"+post.toString());
return builder.build();
}
备注:此处显示获取所有属性存储在hashmap中,然后把map里面的数据全部添加到
RequestBody 中,
5.注意各种log,最终调试时会输出,请求地址,请求参数,返回数据,方便调试,还可以自定log,控制开关,正式版的时候关闭就行
6.此处封装的pos请求,表单,其他的第三方框架都差不多可以这样。
7.完成后就能像第一步一样,建立一个请求类,建立一个返回的数据的类,然后方便的进行网络请求了,请求类如果有必要也可以建立一个基类方便管理修改