欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android M(6.x)使用OkHttp包解析和發(fā)送JSON請求的教程

 更新時間:2016年07月13日 15:16:23   作者:總李寫代碼  
Android 6.0采用的SPDY支持HTTP上GZIP壓縮的傳輸,這使得OkHttp包的功能能夠進一步被利用,本文我們來總結(jié)一下Android M(6.0)使用OkHttp包解析和發(fā)送JSON請求的教程

關(guān)于Android 6.0
Android老版本網(wǎng)絡(luò)請求:
1,HttpUrlConnection
2,Apache Http Client
Android6.0版本網(wǎng)絡(luò)請求:
1,HttpUrlConnection
2,OkHttp
Android6.0版本廢棄了老的網(wǎng)絡(luò)請求,那么它的優(yōu)勢是什么呢?
1,支持SPDY,共享同一個Socket來處理同一個服務(wù)器的所有請求
2,如果SPDY不可用,則通過連接池來減少請求延時
3,無縫的支持GZIP來減少數(shù)據(jù)流量
4,緩存響應(yīng)數(shù)據(jù)來減少重復(fù)的網(wǎng)絡(luò)請求

post請求發(fā)送給服務(wù)器JSON:

我們先來看一個樣例,詳細的請求發(fā)送我們下面還會講.

public class MainActivity extends AppCompatActivity {

public static final String TAG = "MainActivity";
public static final MediaType JSON=MediaType.parse("application/json; charset=utf-8");
@Override
protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 //開啟一個線程,做聯(lián)網(wǎng)操作
 new Thread() {
  @Override
  public void run() {

   postJson();
  }
 }.start();
}

 private void postJson() {
 //申明給服務(wù)端傳遞一個json串
 //創(chuàng)建一個OkHttpClient對象
 OkHttpClient okHttpClient = new OkHttpClient();
 //創(chuàng)建一個RequestBody(參數(shù)1:數(shù)據(jù)類型 參數(shù)2傳遞的json串)
 RequestBody requestBody = RequestBody.create(JSON, json);
 //創(chuàng)建一個請求對象
 Request request = new Request.Builder()
   .url("http://192.168.0.102:8080/TestProject/JsonServlet")
   .post(requestBody)
   .build();
 //發(fā)送請求獲取響應(yīng)
 try {
 Response response=okHttpClient.newCall(request).execute();
  //判斷請求是否成功
  if(response.isSuccessful()){\
   //打印服務(wù)端返回結(jié)果
   Log.i(TAG,response.body().string());

  }
 } catch (IOException e) {
  e.printStackTrace();
 }

}

}

SPDY(讀作“SPeeDY”)是Google開發(fā)的基于TCP的應(yīng)用層協(xié)議,用以最小化網(wǎng)絡(luò)延遲,提升網(wǎng)絡(luò)速度,優(yōu)化用戶的網(wǎng)絡(luò)使用體驗。SPDY并不是一種用于替代HTTP的協(xié)議,而是對HTTP協(xié)議的增強。新協(xié)議的功能包括數(shù)據(jù)流的多路復(fù)用、請求優(yōu)先級以及HTTP報頭壓縮。谷歌表示,引入SPDY協(xié)議后,在實驗室測試中頁面加載速度比原先快64%。
ZIP最早由Jean-loup Gailly和Mark Adler創(chuàng)建,用于UNⅨ系統(tǒng)的文件壓縮。我們在Linux中經(jīng)常會用到后綴為.gz的文件,它們就是GZIP格式的。現(xiàn)今已經(jīng)成為Internet 上使用非常普遍的一種數(shù)據(jù)壓縮格式,或者說一種文件格式。
HTTP協(xié)議上的GZIP編碼是一種用來改進WEB應(yīng)用程序性能的技術(shù)。大流量的WEB站點常常使用GZIP壓縮技術(shù)來讓用戶感受更快的速度。這一般是指WWW服務(wù)器中安裝的一個功能,當有人來訪問這個服務(wù)器中的網(wǎng)站時,服務(wù)器中的這個功能就將網(wǎng)頁內(nèi)容壓縮后傳輸?shù)絹碓L的電腦瀏覽器中顯示出來.一般對純文本內(nèi)容可壓縮到原大小的40%.這樣傳輸就快了,效果就是你點擊網(wǎng)址后會很快的顯示出來.當然這也會增加服務(wù)器的負載. 一般服務(wù)器中都安裝有這個功能模塊的。

JSON解析
這里我們將采用json統(tǒng)一泛型解析,與一些Java的反射機制來解析泛型對象Class<?>:
1.首先我們聲明一個TypeInfo.java類用來封裝泛型相關(guān)屬性

import java.lang.reflect.Array;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class TypeInfo {
 //Type泛型對象類型
 private Class<?> componentType;
 //Type所屬對象類型
 private Class<?> rawType;
 //type
 private Type type;

 private TypeInfo(Class<?> rawType, Class<?> componentType) {

  this.componentType = componentType;
  this.rawType = rawType;
 }

 public static TypeInfo createArrayType(Class<?> componentType) {
  return new TypeInfo(Array.class, componentType);
 }

 public static TypeInfo createNormalType(Class<?> componentType) {
  return new TypeInfo(null, componentType);
 }

 public static TypeInfo createParameterizedType(Class<?> rawType, Class<?> componentType) {
  return new TypeInfo(rawType, componentType);
 }

 public TypeInfo(Type type) {
  this.type = type;
  if (type instanceof ParameterizedType) {
   //返回 Type 對象,表示聲明此類型的類或接口。
   this.rawType = (Class<?>) ((ParameterizedType) type).getRawType();
   //getActualTypeArguments()返回表示此類型實際類型參數(shù)的 Type 對象的數(shù)組。
   Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
   this.componentType = (Class<?>) actualTypeArguments[0];
   // typeReference=new TypeReference<Map<componentType,componentType>>(){};

  } else if (type instanceof GenericArrayType) {
   //返回 Type 對象,表示聲明此類型的類或接口。
   this.rawType = Array.class;
   // 表示一種元素類型是參數(shù)化類型或者類型變量的數(shù)組類型
   this.componentType = (Class<?>) ((GenericArrayType) type).getGenericComponentType();
  } else {
   this.componentType = (Class<?>) type;
  }
 }

 public Type getType() {
  return type;
 }

 public Class<?> getComponentType() {
  return componentType;
 }


 public Class<?> getRawType() {
  return rawType;
 }

}

2.聲明ReqClassUtils.java類 用于通過反射機制獲取泛型對象的TypeInfo

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class ReqClassUtils {

 public static TypeInfo getCallbackGenericType(Class<?> clazz) {
  //獲得帶有泛型的父類
  Type genericSuperclass = clazz.getGenericSuperclass();//Type是 Java 編程語言中所有類型的公共高級接口。它們包括原始類型、參數(shù)化類型、數(shù)組類型、類型變量和基本類型。
  TypeInfo type = getGetnericType(genericSuperclass);
  if (type == null) {
   Type[] genericInterfaces = clazz.getGenericInterfaces();
   if (genericInterfaces != null && genericInterfaces.length > 0) {
    type = getGetnericType(genericInterfaces[0]);
   }
  }
  return type;
 }

 private static TypeInfo getGetnericType(Type type) {
  if (type != null && type instanceof ParameterizedType) {
   //getActualTypeArguments獲取參數(shù)化類型的數(shù)組,泛型可能有多個
   Type[] args = ((ParameterizedType) type).getActualTypeArguments();
   if (args != null && args.length > 0) {
    return new TypeInfo(args[0]);
   }
  }
  return null;
 }
}

3.接下來重點來了,聲明一個json解析工具類ReqJsonUtils.java,主要用于通過TypeInfo相關(guān)屬性進行不同類型的json解析

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import java.lang.reflect.Array;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import static com.alibaba.fastjson.JSON.parseObject;

public class ReqJsonUtils {

 //基本類型映射關(guān)系Map
 private static final Map primitiveWrapperTypeMap = new HashMap(8);

 static {
  //添加基本類型
  primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
  primitiveWrapperTypeMap.put(Byte.class, byte.class);
  primitiveWrapperTypeMap.put(Character.class, char.class);
  primitiveWrapperTypeMap.put(Double.class, double.class);
  primitiveWrapperTypeMap.put(Float.class, float.class);
  primitiveWrapperTypeMap.put(Integer.class, int.class);
  primitiveWrapperTypeMap.put(Long.class, long.class);
  primitiveWrapperTypeMap.put(Short.class, short.class);
 }

 /**
  * 將JSON字符串轉(zhuǎn)換成指定的用戶返回值類型
  *
  * @param type
  * @param jsonData
  * @return
  * @throws JSONException
  */
 public static <T> T parseHttpResult(TypeInfo type, String jsonData) throws JSONException {
  // 處理Void類型的返回值
  if (Void.class.isAssignableFrom(type.getComponentType())) {
   return null;
  }
  //獲取當前type的數(shù)據(jù)類型
  Class<?> rawType = type.getRawType();
  //是否是Array
  boolean isArray = rawType != null && Array.class.isAssignableFrom(rawType);
  //是否是Collection
  boolean isCollection = rawType != null && Collection.class.isAssignableFrom(rawType);
  //是否是Map
  boolean isMap = rawType != null && Map.class.isAssignableFrom(rawType);
  //獲取泛型類型
  Class<?> componentType = type.getComponentType();
  //聲明結(jié)果對象
  T result = null;
  if (isCollection) {//處理collection
   result = (T) JSON.parseArray(jsonData, componentType);
  } else if (isArray) {//處理array
   result = (T) JSON.parseArray(jsonData, componentType).toArray();
  } else if (isMap) {//處理Map
   result = (T) JSONObject.parseObject(jsonData, type.getType());
  } else if (componentType.isAssignableFrom(String.class)) {//處理字符串返回值
   return (T) jsonData;
  } else {
   // 接口的返回類型如果是簡單類型,則會封裝成為一個json對象,真正的對象存儲在value屬性上
   if (isPrimitiveOrWrapper(componentType)) {
    result = (T) parseObject(jsonData);
   } else {
    //處理自定義對象
    result = (T) parseObject(jsonData, componentType);
   }
  }
  return result;
 }

 /**
  * 判斷是否是基本數(shù)據(jù)類型
  *
  * @param clazz
  * @return
  */
 public static boolean isPrimitiveOrWrapper(Class clazz) {
  return (clazz.isPrimitive() || isPrimitiveWrapper(clazz));
 }

 /**
  * 判斷是否是基本數(shù)據(jù)類型
  *
  * @param clazz
  * @return
  */
 public static boolean isPrimitiveWrapper(Class clazz) {
  return primitiveWrapperTypeMap.containsKey(clazz);
 }
}

如何使用?
1.實現(xiàn)解析

 TypeInfo typeInfo = ReqClassUtils.getCallbackGenericType(callBack.getClass());
 callBack.onReqSuccess(ReqJsonUtils.parseHttpResult(typeInfo, jsonData));

2.發(fā)送請求

  HashMap<String, String> paramsMap = new HashMap<>();
  paramsMap.put("sourceType", "2");
  paramsMap.put("sourceDesc", "[Android]" + Build.VERSION.RELEASE + "[Mobel]" + Build.BRAND + " " + Build.MODEL + Build.DEVICE);
  HashMap<String, String> params = dealStringBody(paramsMap);
  RequestManager.getInstance(this).requestAsyn("xxx/actionUrl", RequestManager.TYPE_POST_JSON, params, new ReqCallBack<String>() {

   @Override
   public void onReqSuccess(String result) {
    request_tv.setText(result);
   }

   @Override
   public void onReqFailed(String errorMsg) {

   }
  });

3.支持類型

  new ReqCallBack<List<Object>>();//集合collection
  new ReqCallBack<Map<String, User>>();//map
  new ReqCallBack<Void>();//Void
  new ReqCallBack<Long>();//基礎(chǔ)類型

 

相關(guān)文章

最新評論