iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android M(6.x)使用OkHttp包解析和发送JSON请求的教程
  • 616
分享到

Android M(6.x)使用OkHttp包解析和发送JSON请求的教程

okhttpJSON教程Android 2022-06-06 08:06:10 616人浏览 薄情痞子
摘要

关于Android 6.0 Android老版本网络请求: 1,HttpUrlConnection 2,Apache Http Client Android6.0版本网络请求:

关于Android 6.0
Android老版本网络请求:
1,HttpUrlConnection
2,Apache Http Client
Android6.0版本网络请求:
1,HttpUrlConnection
2,OkHttp
Android6.0版本废弃了老的网络请求,那么它的优势是什么呢?
1,支持SPDY,共享同一个Socket来处理同一个服务器的所有请求
2,如果SPDY不可用,则通过连接池来减少请求延时
3,无缝的支持GZIP来减少数据流量
4,缓存响应数据来减少重复的网络请求

post请求发送给服务器JSON

我们先来看一个样例,详细的请求发送我们下面还会讲.


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);
 //开启一个线程,做联网操作
 new Thread() {
  @Override
  public void run() {
   postJson();
  }
 }.start();
}
 private void postJson() {
 //申明给服务端传递一个json串
 //创建一个OkHttpClient对象
 OkHttpClient okHttpClient = new OkHttpClient();
 //创建一个RequestBody(参数1:数据类型 参数2传递的json串)
 RequestBody requestBody = RequestBody.create(JSON, json);
 //创建一个请求对象
 Request request = new Request.Builder()
   .url("http://192.168.0.102:8080/TestProject/JsonServlet")
   .post(requestBody)
   .build();
 //发送请求获取响应
 try {
 Response response=okHttpClient.newCall(request).execute();
  //判断请求是否成功
  if(response.isSuccessful()){\
   //打印服务端返回结果
   Log.i(TAG,response.body().string());
  }
 } catch (IOException e) {
  e.printStackTrace();
 }
}
}

SPDY(读作“SPeeDY”)是Google开发的基于tcp的应用层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验。SPDY并不是一种用于替代HTTP的协议,而是对HTTP协议的增强。新协议的功能包括数据流的多路复用、请求优先级以及HTTP报头压缩。谷歌表示,引入SPDY协议后,在实验室测试中页面加载速度比原先快64%。
ZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在linux中经常会用到后缀为.gz的文件,它们就是GZIP格式的。现今已经成为Internet 上使用非常普遍的一种数据压缩格式,或者说一种文件格式。
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术。大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度。这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载. 一般服务器中都安装有这个功能模块的。

JSON解析
这里我们将采用json统一泛型解析,与一些Java的反射机制来解析泛型对象Class<?>:
1.首先我们声明一个TypeInfo.java类用来封装泛型相关属性


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()返回表示此类型实际类型参数的 Type 对象的数组。
   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;
   // 表示一种元素类型是参数化类型或者类型变量的数组类型
   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 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
  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获取参数化类型的数组,泛型可能有多个
   Type[] args = ((ParameterizedType) type).getActualTypeArguments();
   if (args != null && args.length > 0) {
    return new TypeInfo(args[0]);
   }
  }
  return null;
 }
}

3.接下来重点来了,声明一个json解析工具类ReqJsonUtils.java,主要用于通过TypeInfo相关属性进行不同类型的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 {
 //基本类型映射关系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);
 }
 
 public static <T> T parseHttpResult(TypeInfo type, String jsonData) throws JSONException {
  // 处理Void类型的返回值
  if (Void.class.isAssignableFrom(type.getComponentType())) {
   return null;
  }
  //获取当前type的数据类型
  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();
  //声明结果对象
  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;
 }
 
 public static boolean isPrimitiveOrWrapper(Class clazz) {
  return (clazz.isPrimitive() || isPrimitiveWrapper(clazz));
 }
 
 public static boolean isPrimitiveWrapper(Class clazz) {
  return primitiveWrapperTypeMap.containsKey(clazz);
 }
}

如何使用?
1.实现解析


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

2.发送请求


  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>();//基础类型
您可能感兴趣的文章:详解Android中使用OkHttp发送HTTP的post请求的方法Android中使用OkHttp包处理HTTP的get和post请求的方法详解Android的OkHttp包编写异步HTTP请求调用的方法Android基于OkHttpUtils网络请求的二次封装Android使用OkHttp请求自签名的https网站的示例Android Okhttp请求查询购物车的实例代码Android中okhttp3使用详解Android OkHttp的简单使用和封装详解Android小知识之OkHttp的2种请求方式详解


--结束END--

本文标题: Android M(6.x)使用OkHttp包解析和发送JSON请求的教程

本文链接: https://www.lsjlt.com/news/24682.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作