遇到又长又复杂的Json格式的网络请求,如果没有gson,那就是相当头疼的事情了。
有了Gson这个神器,一切问题都不是问题!
本人当看到这个json请求示例时,心里也是打鼓:
{
"service_ver": "1.0",
"bot_name": "xx",
"bot_ver": "1",
"user_id": "xx",
"bot_mode": 0,
"query": "你叫什么",
"req_type": "chat",
"send_time_ms": "1454319650000",
"query_time_ms": "1454319650000",
"debug": 1,
"callback_msg": "anything here will send back",
"stat_info": {
"device_id": "asdwrgh",
"user_group": "user",
"os": "android",
"os_ver": "1.4.0"
},
"location": {
"la": 40.0433,
"lo": 116.269,
"address": "深圳市南山区xx路",
"country": "中国",
"province": "广东省",
"city": "深圳市",
"district": "南山区",
"street": "xx路"
}
}
在没有Gson的时候,就得用JsonObject或JsonArray来拼接,这么多参数,这么长的json,拼到猴年马月?
用Gson的话,就简单了,导入Gson依赖后,把这个请求示例复制一下,创建一个实体类,打开GsonFormat插件,黏贴这个请求示例进去并确定,实体类便生成好了。
public class Ask {
private String service_ver;
private String bot_name;
private String bot_ver;
private String user_id;
private int bot_mode;
private String query;
private String req_type;
private String send_time_ms;
private String query_time_ms;
private int debug;
private String callback_msg;
private StatInfoBean stat_info;
private LocationBean location;
public String getService_ver() {
return service_ver;
}
public void setService_ver(String service_ver) {
this.service_ver = service_ver;
}
public String getBot_name() {
return bot_name;
}
public void setBot_name(String bot_name) {
this.bot_name = bot_name;
}
public String getBot_ver() {
return bot_ver;
}
public void setBot_ver(String bot_ver) {
this.bot_ver = bot_ver;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public int getBot_mode() {
return bot_mode;
}
public void setBot_mode(int bot_mode) {
this.bot_mode = bot_mode;
}
public String getQuery() {
return query;
}
public void setQuery(String query) {
this.query = query;
}
public String getReq_type() {
return req_type;
}
public void setReq_type(String req_type) {
this.req_type = req_type;
}
public String getSend_time_ms() {
return send_time_ms;
}
public void setSend_time_ms(String send_time_ms) {
this.send_time_ms = send_time_ms;
}
public String getQuery_time_ms() {
return query_time_ms;
}
public void setQuery_time_ms(String query_time_ms) {
this.query_time_ms = query_time_ms;
}
public int getDebug() {
return debug;
}
public void setDebug(int debug) {
this.debug = debug;
}
public String getCallback_msg() {
return callback_msg;
}
public void setCallback_msg(String callback_msg) {
this.callback_msg = callback_msg;
}
public StatInfoBean getStat_info() {
return stat_info;
}
public void setStat_info(StatInfoBean stat_info) {
this.stat_info = stat_info;
}
public LocationBean getLocation() {
return location;
}
public void setLocation(LocationBean location) {
this.location = location;
}
public static class StatInfoBean {
private String device_id;
private String user_group;
private String os;
private String os_ver;
public String getDevice_id() {
return device_id;
}
public void setDevice_id(String device_id) {
this.device_id = device_id;
}
public String getUser_group() {
return user_group;
}
public void setUser_group(String user_group) {
this.user_group = user_group;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
public String getOs_ver() {
return os_ver;
}
public void setOs_ver(String os_ver) {
this.os_ver = os_ver;
}
}
public static class LocationBean {
private double la;
private double lo;
private String address;
private String country;
private String province;
private String city;
private String district;
private String street;
public double getLa() {
return la;
}
public void setLa(double la) {
this.la = la;
}
public double getLo() {
return lo;
}
public void setLo(double lo) {
this.lo = lo;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
}
}
同理可以生成接受的json对应的实体类Answer.class,这里按下不表。
接下来就是写网络请求了,这里我用okHttp3,根据要求,使用post请求
public class HttpRequest {
private static final String TAG = "HttpRequest";
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
private String AnswerText=null;//文字回答
private TrioHttpRequest(){
}
private static class HttpRequestInstance{
private static final HttpRequest INSTANCE=new HttpRequest();
}
/*
** 静态内部类单例模式,线程安全,延迟加载,效率高
*/
public static HttpRequest getInstance(){
return HttpRequestInstance.INSTANCE;
}
/*
**发起网络请求,text是用户说的话,requestType是请求类型
*/
private void Request(String text,String requestType,String address,okhttp3.Callback callback){
String time= String.valueOf(System.currentTimeMillis());
OkHttpClient client=new OkHttpClient();
Ask ask=new Ask();//Ask类里的所有set方法全部set入参数
ask.setService_ver("1.0");
ask.setBot_name("xxx");
ask.setBot_ver("1");
ask.setUser_id("xxx");
ask.setBot_mode(0);
ask.setQuery(text);
ask.setReq_type(requestType);
ask.setSend_time_ms(time);
ask.setQuery_time_ms(time);
ask.setCallback_msg("anything here will send back");
Ask.StatInfoBean statInfoBean=new Ask.StatInfoBean();//Ask两个内部类的set方法也要set入参数
statInfoBean.setDevice_id("xxx");
statInfoBean.setUser_group("user");
statInfoBean.setOs("android");
statInfoBean.setOs_ver("4.2.0");
Ask.LocationBean locationBean=new Ask.LocationBean();
locationBean.setLo(116.269);
locationBean.setLa(40.0433);
locationBean.setAddress("xxx");
locationBean.setCountry("中国");
locationBean.setProvince("广东省");
locationBean.setCity("深圳市");
locationBean.setDistrict("南山区");
locationBean.setStreet("xx路");
ask.setStat_info(statInfoBean);//最后需要把Ask的两个内部类的对象set好
ask.setLocation(locationBean);
Gson gson=new Gson();
String askjson=gson.toJson(ask);//生成json字符串
Log.e(TAG, "askjson== "+askjson);
RequestBody requestBody=RequestBody.create(JSON,askjson);//生成json请求体
Request request=new Request.Builder()
.url(address)
.post(requestBody)//post方式发起请求
.build();
client.newCall(request).enqueue(callback);//异步操作,不会阻塞线程
}
/* askText是用户说的话
*/
public void getAnswer(final String askText){
Request(askText,"chat","http://xxxxx",new okhttp3.Callback(){
@Override
public void onFailure(okhttp3.Call call, IOException e) {
AnswerText="服务连接出现问题,请稍后再试";
}
@Override
public void onResponse(okhttp3.Call call, Response response) throws IOException {
String responseData=response.body().string();
Log.e(TAG, "ResponseJson=="+responseData);
Gson gson=new Gson();
try {
Answer answer=gson.fromJson(responseData,Answer.class);
//获得json串,赋到Answer.class中,也就是接收json的实体类,然后通过gson.fromJson获得Answer对象的,设置这个对象的引用为answer
AnswerText=answer.getData().get(0).getResults().get(0).getReply().getContent();
//只需要用Answer对象的引用answer来行使一系列get方法即可获取需要的参数
Message msg=new Message();
msg.what=1;//消息标志
handler.sendMessage(msg);//发消息给主线程Handler
} catch (Exception e) {
e.printStackTrace();
AnswerText="服务连接出现问题,请稍后再试";
Log.e(TAG, "解析失败=="+e.toString() );
}
}
});
}
/*
** 用于接收聊天信息获取成功的消息,并展示
*/
private MyHandler handler = new MyHandler(this);
static class MyHandler
extends Handler {
WeakReference<HttpRequest> reference;
MyHandler(HttpRequest httpRequest) {
reference = new WeakReference<>(httpRequest);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what==1){
//这里做展示说话的逻辑,即ui操作
}
}
}
}
其实很简单,只需要把请求json实体类的set方法全部用来set入需要的参数,一个不剩,就可以使用gson.toJson(请求json实体类的对象引用)方法生成json字符串啦,是不是很简单?
解析就更简单了:
json接收实体类名 对象引用名=gson.fromJson(响应体的String,json接收实体类名.class);
然后拿着这个对象引用就可以一路使用get方法直到get到你要的数据哦!