如何使用gson解析泛型形参并返回相对应的类
来源:互联网 发布:网络引导安装系统 编辑:程序博客网 时间:2024/06/01 17:21
在android实际开发中,我们在请求网络数据的时候,服务器返回的通常都是json字符串,我们需要将json转化成我们需要的类,当然这些通常是使用gson来完成的,过程大概就是要判断解析后的类是否存在,类是否有效,类字段是否有值,其实这些逻辑都差不多,所以就会导致有很多重复的地方,这个时候我就想到用泛型来处理这个过程。
先看看我新建的项目空间:
类文件介绍
HttpResponse.java
//网络请求数据所对应的java类//code:0表示请求数据成功;不为0则表示失败//msg:如果网络请求失败,代表失败原因//result:实际业务数据public class HttpResponse { private String msg; private String code; private Object result; public String getMsg() { return msg; } public String getCode() { return code; } public Object getResult() { return result; } public void setMsg(String msg) { this.msg = msg; } public void setCode(String code) { this.code = code; } public void setResult(Object result) { this.result = result; }}
MyListener.java
//网络请求接口回调,这里使用了泛型,不考虑用interfacepackage study.fanxing.bean;public abstract class MyListener<T> { public abstract void success(T t); public abstract void fail(String msg);}
Student.java和Teacher.java(这两个是业务类,为了方便测试,这两个类的字段都是一样的)
package study.fanxing.bean;public class Student { private String name; private String address; private int age; private String sex; public Student() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; }}
Test1.java
package study.fanxing.test;import com.google.gson.Gson;import study.fanxing.bean.HttpResponse;import study.fanxing.bean.MyListener;import study.fanxing.bean.Student;import study.fanxing.bean.Teacher;public class Test1 { public static Gson gson=new Gson(); //模拟实际的网络请求,注意这里只传了一个参数 public static <T> void requestNetworkData(MyListener<T> listener) { HttpResponse response=null; try { response=gson.fromJson(getJson(), HttpResponse.class); }catch(Exception e) { e.printStackTrace(); } //数据解析并且请求成功 if(response!=null && response.getCode().equals("0")) { String type=TTypeUtils.getTType(listener.getClass()); if(type!=null && type.length()>0) { T t=null; try { String json=gson.toJson(response.getResult()); Class<T> clazz=(Class<T>) Class.forName(type); t=gson.fromJson(json, clazz); }catch(Exception e) { e.printStackTrace(); } if(t!=null) listener.success(t); else showError(response, listener); } else { showError(response, listener); } } else { showError(response, listener); } } //处理请求错误,解析错误这种情况 private static void showError(HttpResponse response,MyListener listener) { if(response!=null && response.getMsg()!=null && response.getMsg().length()>0) listener.fail(response.getMsg()); else listener.fail("网络错误"); } //请求student接口 public static void testRequestStudent() { requestNetworkData(new MyListener<Student>() { @Override public void success(Student student) { // TODO Auto-generated method stub System.out.println("student:"); System.out.println("name:"+student.getName()); System.out.println("sex:"+student.getSex()); System.out.println("address:"+student.getAddress()); System.out.println("age:"+student.getAge()); } @Override public void fail(String msg) { // TODO Auto-generated method stub System.out.println(msg); } }); } //请求teacher接口 public static void testRequestTeacher() { requestNetworkData(new MyListener<Teacher>() { @Override public void success(Teacher t) { // TODO Auto-generated method stub System.out.println("teacher:"); System.out.println("name:"+t.getName()); System.out.println("sex:"+t.getSex()); System.out.println("address:"+t.getAddress()); System.out.println("age:"+t.getAge()); } @Override public void fail(String msg) { // TODO Auto-generated method stub System.out.println(msg); } }); } //生成测试json public static void createJson() { HttpResponse response=new HttpResponse(); response.setCode("0"); response.setMsg("成功"); Student student=new Student(); student.setName("张三"); student.setAddress("中国"); student.setAge(15); student.setSex("男"); response.setResult(student); System.out.println(gson.toJson(response)); } public static String getJson() { return "{\"msg\":\"成功\",\"code\":\"0\",\"result\":{\"name\":\"张三\",\"address\":\"中国\",\"age\":15,\"sex\":\"男\"}}"; } public static void main(String[] args) {// createJson(); testRequestStudent(); testRequestTeacher(); }}
TTypeUtils.java
package study.fanxing.test;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;//这个类很关键,用来获取泛型类里面泛型的实际类型public class TTypeUtils { public static String getTType(Class<?> clazz) { Type mySuperClassType=clazz.getGenericSuperclass(); Type[] types=((ParameterizedType)mySuperClassType).getActualTypeArguments(); if(types!=null && types.length>0) { String[] TType=types[0].toString().split(" "); if(TType!=null && TType.length>1) { return TType[1]; } } return null; }}
那我们来看一下运行的效果:
从结果上看,已经正确的解析了json。从整个网络请求来看,只需要传入一个MyListener(T:具体的类类型,例如Student,Teacher)就可以获取实际的业务类,不需要每次都要判断一大推HttpResponse的逻辑,使用起来非常方便。当然如果返回的业务json是一个数组,我相信也可以做出来,大家可以自己试试。
当然还有可以优化的地方,例如HttpResponse里面的result字段可以没有,可以在MyListener.java类里面定义result字段,这样使用android官方自带的JSONObject获取result:JSONObject.optString(“result”),这样使用起来会更方便。
0 0
- 如何使用gson解析泛型形参并返回相对应的类
- 使用MyBatis指定返回结果与实体属性相对应的方法
- Gson解析List为空应如何解决
- 使用Gson解析Retrofit返回结果
- 使用gson配合Retrofit2解析服务器返回
- Gson的使用——Gson解析json数组并展示在ListView控件上
- Gson的使用——Gson解析json数组并展示在ListView控件上
- Gson的使用——Gson解析json数组并展示在ListView控件上
- 查询数据库中的表,返回字段相对应的数据类型!
- 如何使用Gson工具类,以及使用listview加载相应的解析项
- 如何使用Gson工具类,以及使用listview加载相应的解析项
- 如何使用Gson工具类,以及使用listview加载相应的解析项
- Gson 解析json的使用
- JSON解析 Gson的使用
- 从程序到进程:谈谈可执行文件是如何与进程相对应并最终被CPU执行的。
- XML动态生成相对应的类
- 使用Gson解析管理类
- Gson解析 并反转
- extjs2下拉树选项框comboxWithTree(支持异步加载子节点)
- 【转】小波变换通俗解释
- Java 中泛型的协变
- C#中Internal关键字的总结
- ubuntu 14.04 java开发环境搭建 jdk 以及 inteliJ IDEA安装
- 如何使用gson解析泛型形参并返回相对应的类
- ARM汇编 – (2) ARM程序状态寄存器
- 十、森林与并查集---(2)并查集的创建
- 个人总结 Yii 部分关键代码
- 最大熵简介
- ListView 中嵌入GridView去滚动效果
- HttpURLConnection请求
- HTML列表
- 【转】查询表结构