您的位置:首页 > 理论基础 > 计算机网络

如何使用gson解析泛型形参并返回相对应的类

2016-04-30 10:22 459 查看
在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

//网络请求接口回调,这里使用了泛型,不考虑用interface
package 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”),这样使用起来会更方便。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android 泛型 网络