变态的json解析,key为数字,设置没有key!如何解析呢?

导语:

最近做的项目是一个打车类的项目,需要选择地址,而数据是Json数据。因为这些数据不对公司造成任何的损失,也没有涉及到任何的隐私或者商业秘密,所以就写此文,说说暂时的解决方法吧,嘻嘻!

遇到的问题:不是标准的json数据,有些甚至没有key。比如说一开始的北京,0,这些都没有key。另外,有key的都是数字。是数据的话,第一个层级是0~33.然而第二个层级是不定的,也就是不能用for循环啦,哈哈!

先看看数据吧:

数据如下:

全国省市县三级Json数据

解析的核心类:(没有进行封装)

package com.sunofbeaches.jsondemo;

import java.util.Map.Entry;
import java.util.Set;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import android.os.Bundle;
import android.app.Activity;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		parserJson();
	}

	private void parserJson() {
		// 获取到数据
		String jsonString = getResources().getString(R.string.jsonstring);

		// json解析者
		JsonParser jsonParser = new JsonParser();

		// 解析成Json对象
		JsonObject asJsonObject = jsonParser.parse(jsonString)
				.getAsJsonObject();

		// 遍历里头的数据
		Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
		for (Entry<String, JsonElement> entry : entrySet) {

			JsonArray asJsonArray = entry.getValue().getAsJsonArray();
			String asString = asJsonArray.get(0).getAsString();// 省份
			System.out.println("asString--" + asString);

			int asInt = asJsonArray.get(1).getAsInt();// 那个数字
			System.out.println("asInt--" + asInt);

			// 获取到第3个,又是一个json对象
			JsonObject asJsonObject2 = asJsonArray.get(2).getAsJsonObject();

			// 遍历第2级数据
			Set<Entry<String, JsonElement>> entrySet2 = asJsonObject2
					.entrySet();
			for (Entry<String, JsonElement> entry2 : entrySet2) {
				JsonArray asJsonArray2 = entry2.getValue().getAsJsonArray();

				if (asJsonArray2.size() == 1) {// 这一个判断是因为在河北市(42249)里头只有一级,没有下一级了
					String asString2 = asJsonArray2.get(0).getAsString();// 市级
					System.out.println("asString2====" + asString2);

				} else {
					String asString2 = asJsonArray2.get(0).getAsString();// 市级
					System.out.println("asString2====" + asString2);

					int asInt2 = asJsonArray2.get(1).getAsInt();// 数字
					System.out.println("asInt=====" + asInt2);

					// 获取第三级数据(县级/区)
					JsonObject asJsonObject3 = asJsonArray2.get(2)
							.getAsJsonObject();

					// 遍历第三级数据
					Set<Entry<String, JsonElement>> entrySet3 = asJsonObject3
							.entrySet();
					for (Entry<String, JsonElement> entry3 : entrySet3) {
						JsonArray asJsonArray3 = entry3.getValue()
								.getAsJsonArray();
						
						String asString3 = asJsonArray3.get(0).getAsString();// 县级数据
						System.out.println("asString3>>>>>>" + asString3);
					}
				}
			}
		}
	}
}

 封装成对象

因为数据不标准,所以我们不能直接创建一个bean类,用gson直接解析,因为gson的直接解析是使用反射的方法來做的。那么这里也说说吧,如果直接是用bean类來解析的话,需要它的权限所有都是public的,类是public的,里面的成员,所有都是public的,这是第一点。那么第二点就是这个里面的名字要和这个json数据里的名字要一样哦。就是对应的数据名字要一样,原因还是因为使用反射的方法來解析嘛。

 

ok,那么通过上面这个核心方法,我们可以定义出以下的bean类,然后手动地赋值,就可以封装起來了。

主要的bean类

这些bean 结构和Json里的数据是一样的结构,只是名字不一样。因为Java中数字不能作为变量的名字嘛,是吧!这个我们小时候学java就知道啦,标识符的规则。

好的,直接上bean类吧!

这个是整体的bean类

package com.sunofbeaches.jsondemo.bean;

import java.util.List;

public class JsonBean {

	public List<Provinces> Provinces;
}

这个省份的bean类

package com.sunofbeaches.jsondemo.bean;

import java.util.List;

public class Provinces {
	public String provinceName;
	public int shengNumber;
	public List<City> cities;

}

市级的bean类

package com.sunofbeaches.jsondemo.bean;

import java.util.List;

public class City {
	public String cityName;
	public int chengshiNumber;
	public List<Country> countries;
}

镇/区级的bean类

package com.sunofbeaches.jsondemo.bean;

public class Country {
	public String countryNmae;
}

有了bean类之后,我们可以对数据进行封装,因为前面我们已经解析了数据嘛!

数据封装:

数据封装核心类,其实和这个解析类在一起了,那么个类的功能就是解析数据,并封装数据,返回一个bean类

package com.sunofbeaches.jsondemo;

import java.util.ArrayList;
import java.util.Map.Entry;
import java.util.Set;

import android.content.Context;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.orange.jsondemo.R;
import com.sunofbeaches.jsondemo.bean.City;
import com.sunofbeaches.jsondemo.bean.Country;
import com.sunofbeaches.jsondemo.bean.JsonBean;
import com.sunofbeaches.jsondemo.bean.Provinces;

public class GetAllDatasBean {

	public JsonBean getAllDatas(Context context) {

		// 整体Bean类
		JsonBean bean = new JsonBean();
		bean.Provinces = new ArrayList<Provinces>();

		// 获取到数据
		String jsonString = context.getResources().getString(
				R.string.jsonstring);

		// json解析者
		JsonParser jsonParser = new JsonParser();

		// 解析成Json对象
		JsonObject asJsonObject = jsonParser.parse(jsonString)
				.getAsJsonObject();

		// 遍历里头的数据
		Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet();
		for (Entry<String, JsonElement> entry : entrySet) {

			// 省bean类
			Provinces province = new Provinces();
			province.cities = new ArrayList<City>();

			JsonArray asJsonArray = entry.getValue().getAsJsonArray();
			String asString = asJsonArray.get(0).getAsString();// 省份

			// 赋值
			province.provinceName = asString;
			System.out.println("asString>>" + asString);

			int asInt = asJsonArray.get(1).getAsInt();// 那个数字

			// 赋值
			province.shengNumber = asInt;

			// 获取到第3个,又是一个json对象
			JsonObject asJsonObject2 = asJsonArray.get(2).getAsJsonObject();

			// 遍历第2级数据
			Set<Entry<String, JsonElement>> entrySet2 = asJsonObject2
					.entrySet();
			for (Entry<String, JsonElement> entry2 : entrySet2) {
				JsonArray asJsonArray2 = entry2.getValue().getAsJsonArray();

				// 市bean类
				City city = new City();
				city.countries = new ArrayList<Country>();

				if (asJsonArray2.size() == 1) {// 这一个判断是因为在河北市(42249)里头只有一级,没有下一级了
					String asString2 = asJsonArray2.get(0).getAsString();// 市级

					city.cityName = asString2;
					city.chengshiNumber = -1;// 表示没有
					city.countries = null;// 表示没有,使用的时候要记得判断

				} else {
					String asString2 = asJsonArray2.get(0).getAsString();// 市级

					// 赋值
					city.cityName = asString2;

					int asInt2 = asJsonArray2.get(1).getAsInt();// 数字

					// 赋值
					city.chengshiNumber = asInt2;

					// 获取第三级数据(县级/区)
					JsonObject asJsonObject3 = asJsonArray2.get(2)
							.getAsJsonObject();

					// 遍历第三级数据
					Set<Entry<String, JsonElement>> entrySet3 = asJsonObject3
							.entrySet();
					for (Entry<String, JsonElement> entry3 : entrySet3) {
						JsonArray asJsonArray3 = entry3.getValue()
								.getAsJsonArray();

						String asString3 = asJsonArray3.get(0).getAsString();// 县级数据

						// 县级/区数据bean类
						Country country = new Country();

						country.countryNmae = asString3;
						city.countries.add(country);// 添加县/区
					}
				}
				province.cities.add(city);
			}
			bean.Provinces.add(province);
		}
		return bean;
	}

}

到这里,数据已经完成了解析,也完成了封装,可以直接得到一个包含了所有数据的类。那么怎么使用呢?下面,就通过一个例子來使用一下这面里的数据吧!

省市镇三级联动例子(使用数据)

布局如下:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >

    <Spinner
        android:id="@+id/provinces"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <Spinner
        android:id="@+id/cities"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

    <Spinner
        android:id="@+id/countries"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1" />

</LinearLayout>

布局

当然,是没有数据的,嘻嘻!

核心类如下:

package com.sunofbeaches.jsondemo;

import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Spinner;
import android.widget.TextView;

import com.orange.jsondemo.R;
import com.sunofbeaches.jsondemo.adapter.MyBaseAdapter;
import com.sunofbeaches.jsondemo.bean.City;
import com.sunofbeaches.jsondemo.bean.Country;
import com.sunofbeaches.jsondemo.bean.JsonBean;
import com.sunofbeaches.jsondemo.bean.Provinces;

public class MainActivity extends Activity {
	private Spinner mProvinces;
	private Spinner mCities;
	private Spinner mCountries;
	private JsonBean mDatas;
	private List<Provinces> mProDatas;
	private List<City> mCitDatas;
	private List<Country> mCounDatas;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		initView();
		initDatas();
		initEvent();

	}

	private void initView() {
		setContentView(R.layout.activity_main);
		mProvinces = (Spinner) this.findViewById(R.id.provinces);
		mCities = (Spinner) this.findViewById(R.id.cities);
		mCountries = (Spinner) this.findViewById(R.id.countries);
	}

	private void initDatas() {

		mDatas = new GetAllDatasBean().getAllDatas(this);

		mProDatas = mDatas.Provinces;
		Log.d("message", mProDatas.size() + ">>>>");

		mProvinces.setAdapter(new ProvincesAdapter(mProDatas));
	}

	private class ProvincesAdapter extends MyBaseAdapter<Provinces> {

		public ProvincesAdapter(List<Provinces> datas) {
			super(datas);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView tv = new TextView(MainActivity.this);
			tv.setText(mProDatas.get(position).provinceName);
			return tv;
		}

	}

	/**
	 * 第二级数据目录
	 */
	private void initSecondDatas(int position) {
		mCitDatas = mProDatas.get(position).cities;

		// 设置适配器
		mCities.setAdapter(new CitiesAdapter(mCitDatas));

	}

	private class CitiesAdapter extends MyBaseAdapter<City> {

		public CitiesAdapter(List<City> datas) {
			super(datas);
		}

		// 复写方法
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView tv = new TextView(MainActivity.this);
			tv.setText(mCitDatas.get(position).cityName);
			return tv;
		}

	}

	private void initCountrieDatas(int position) {

		// 获取数据
		mCounDatas = mCitDatas.get(position).countries;

		// 设置适配器
		mCountries.setAdapter(new CountriesAdapter(mCounDatas));

	}

	private class CountriesAdapter extends MyBaseAdapter<Country> {

		public CountriesAdapter(List<Country> datas) {
			super(datas);
		}

		// 复写一个方法
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			TextView tv = new TextView(MainActivity.this);
			tv.setText(mCounDatas.get(position).countryNmae);
			return tv;
		}
	}

	private void initEvent() {
		// 省级数据监听
		mProvinces.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				initSecondDatas(position);
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {

			}

		});

		// 市级数据监听
		mCities.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {

				// 去设定县级/区的数据
				initCountrieDatas(position);
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {

			}
		});

	}
}

 另外一个抽取类:

package com.sunofbeaches.jsondemo.adapter;

import java.util.List;

import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;

public class MyBaseAdapter<T> extends BaseAdapter {

	private List<T> mDatas;

	// 通过构造函数來获取到数据
	public MyBaseAdapter(List<T> datas) {
		this.mDatas = datas;
	}

	@Override
	public int getCount() {
		if (mDatas != null) {
			return mDatas.size();
		}
		return 0;
	}

	@Override
	public Object getItem(int position) {
		if (mDatas != null) {
			return mDatas.get(position);
		}
		return null;
	}

	@Override
	public long getItemId(int position) {
		if (mDatas != null) {
			return position;
		}
		return 0;
	}

	// 这个方法由子类复写
	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		return null;

	}

}

 结语:

到了这里,相信你已经明白了怎么搞这些数据。数据解析了,类也封装了,数据也使用了,哈哈!如果有什么疑问欢迎到我们的社区讨论哦!

阳光沙滩

或许,你可以分享呢!谢谢哦!

这样吧,最后还是发一个动图看看吧!

数据的封装应用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值