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

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

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

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

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

我們先來(lái)看一個(gè)樣例,詳細(xì)的請(qǐng)求發(fā)送我們下面還會(huì)講.

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);
 //開啟一個(gè)線程,做聯(lián)網(wǎng)操作
 new Thread() {
  @Override
  public void run() {

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

 private void postJson() {
 //申明給服務(wù)端傳遞一個(gè)json串
 //創(chuàng)建一個(gè)OkHttpClient對(duì)象
 OkHttpClient okHttpClient = new OkHttpClient();
 //創(chuàng)建一個(gè)RequestBody(參數(shù)1:數(shù)據(jù)類型 參數(shù)2傳遞的json串)
 RequestBody requestBody = RequestBody.create(JSON, json);
 //創(chuàng)建一個(gè)請(qǐng)求對(duì)象
 Request request = new Request.Builder()
   .url("http://192.168.0.102:8080/TestProject/JsonServlet")
   .post(requestBody)
   .build();
 //發(fā)送請(qǐng)求獲取響應(yīng)
 try {
 Response response=okHttpClient.newCall(request).execute();
  //判斷請(qǐng)求是否成功
  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ò)使用體驗(yàn)。SPDY并不是一種用于替代HTTP的協(xié)議,而是對(duì)HTTP協(xié)議的增強(qiáng)。新協(xié)議的功能包括數(shù)據(jù)流的多路復(fù)用、請(qǐng)求優(yōu)先級(jí)以及HTTP報(bào)頭壓縮。谷歌表示,引入SPDY協(xié)議后,在實(shí)驗(yàn)室測(cè)試中頁(yè)面加載速度比原先快64%。
ZIP最早由Jean-loup Gailly和Mark Adler創(chuàng)建,用于UNⅨ系統(tǒng)的文件壓縮。我們?cè)贚inux中經(jīng)常會(huì)用到后綴為.gz的文件,它們就是GZIP格式的?,F(xiàn)今已經(jīng)成為Internet 上使用非常普遍的一種數(shù)據(jù)壓縮格式,或者說(shuō)一種文件格式。
HTTP協(xié)議上的GZIP編碼是一種用來(lái)改進(jìn)WEB應(yīng)用程序性能的技術(shù)。大流量的WEB站點(diǎn)常常使用GZIP壓縮技術(shù)來(lái)讓用戶感受更快的速度。這一般是指WWW服務(wù)器中安裝的一個(gè)功能,當(dāng)有人來(lái)訪問這個(gè)服務(wù)器中的網(wǎng)站時(shí),服務(wù)器中的這個(gè)功能就將網(wǎng)頁(yè)內(nèi)容壓縮后傳輸?shù)絹?lái)訪的電腦瀏覽器中顯示出來(lái).一般對(duì)純文本內(nèi)容可壓縮到原大小的40%.這樣傳輸就快了,效果就是你點(diǎn)擊網(wǎng)址后會(huì)很快的顯示出來(lái).當(dāng)然這也會(huì)增加服務(wù)器的負(fù)載. 一般服務(wù)器中都安裝有這個(gè)功能模塊的。

JSON解析
這里我們將采用json統(tǒng)一泛型解析,與一些Java的反射機(jī)制來(lái)解析泛型對(duì)象Class<?>:
1.首先我們聲明一個(gè)TypeInfo.java類用來(lái)封裝泛型相關(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泛型對(duì)象類型
 private Class<?> componentType;
 //Type所屬對(duì)象類型
 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 對(duì)象,表示聲明此類型的類或接口。
   this.rawType = (Class<?>) ((ParameterizedType) type).getRawType();
   //getActualTypeArguments()返回表示此類型實(shí)際類型參數(shù)的 Type 對(duì)象的數(shù)組。
   Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
   this.componentType = (Class<?>) actualTypeArguments[0];
   // typeReference=new TypeReference<Map<componentType,componentType>>(){};

  } else if (type instanceof GenericArrayType) {
   //返回 Type 對(duì)象,表示聲明此類型的類或接口。
   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類 用于通過反射機(jī)制獲取泛型對(duì)象的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 編程語(yǔ)言中所有類型的公共高級(jí)接口。它們包括原始類型、參數(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ù)組,泛型可能有多個(gè)
   Type[] args = ((ParameterizedType) type).getActualTypeArguments();
   if (args != null && args.length > 0) {
    return new TypeInfo(args[0]);
   }
  }
  return null;
 }
}

3.接下來(lái)重點(diǎn)來(lái)了,聲明一個(gè)json解析工具類ReqJsonUtils.java,主要用于通過TypeInfo相關(guān)屬性進(jì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;
  }
  //獲取當(dāng)前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é)果對(duì)象
  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 {
   // 接口的返回類型如果是簡(jiǎn)單類型,則會(huì)封裝成為一個(gè)json對(duì)象,真正的對(duì)象存儲(chǔ)在value屬性上
   if (isPrimitiveOrWrapper(componentType)) {
    result = (T) parseObject(jsonData);
   } else {
    //處理自定義對(duì)象
    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.實(shí)現(xiàn)解析

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

2.發(fā)送請(qǐng)求

  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)文章

最新評(píng)論