Android用GSon处理Json数据
来源:互联网 发布:阿里云短信授权委托书 编辑:程序博客网 时间:2024/06/04 17:20
目前解析json有三种工具:org.json(Java常用的解析),fastjson(阿里巴巴工程师开发的),Gson(Google官网出的),解析速度最快的是Gson,下载地址:https://code.google.com/p/google-gson/
什么是JSON:
JSON即JavaScript Object Natation, 它是一种轻量级的数据交换格式, 与XML一样, 是广泛被采用的客户端和服务端交互的解决方案.
JSON对象:
JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, key-value对之间使用逗号分隔. 如:{"name":"coolxing", "age"=24, "male":true, "address":{"street":"huiLongGuan", "city":"beijing", "country":"china"}}. JSON对象的key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况.
JSON数组:
JSON数组(array)以"["开始, 以"]"结束, 数组中的每一个元素可以是string, number, false, true, null, Object对象甚至是array数组, 数组间的元素使用逗号分隔. 如["coolxing", 24, {"street":"huiLongGuan", "city":"beijing", "country":"china"}].
Gson的基本使用方法:
通过获取JsonReader对象解析JSON数据:
String jsonData = "[{\"username\":\"arthinking\",\"userId\":001},{\"username\":\"Jason\",\"userId\":002}]";try{JsonReader reader = new JsonReader(new StringReader(jsonData));reader.beginArray();while(reader.hasNext()){reader.beginObject();while(reader.hasNext()){String tagName = reader.nextName();if(tagName.equals("username")){System.out.println(reader.nextString());}else if(tagName.equals("userId")){System.out.println(reader.nextString());}}reader.endObject();}reader.endArray();}catch(Exception e){e.printStackTrace();}
通过把JSON数据映射成一个对象,使用Gson对象的fromJson()方法获取一个对象数组进行操作:
创建JSON数据对应的一个POJO对象User.java:
public class User {private String username ;private int userId ;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}}
使用Gson对象获取User对象数据进行相应的操作:
Type listType = new TypeToken<LinkedList<User>>(){}.getType();Gson gson = new Gson();LinkedList<User> users = gson.fromJson(jsonData, listType);for (Iterator iterator = users.iterator(); iterator.hasNext();) {User user = (User) iterator.next();System.out.println(user.getUsername());System.out.println(user.getUserId());}
如果要处理的JSON字符串只包含一个JSON对象,则可以直接使用fromJson获取一个User对象:
String jsonData = "{\"username\":\"arthinking\",\"userId\":001}";Gson gson = new Gson();User user = gson.fromJson(jsonData, User.class);System.out.println(user.getUsername());System.out.println(user.getUserId());
数据格式:
- {
- "data": {
- "partnerteamlist": [
- {
- "pteamId": 72825,
- "ptitle": "随摄影/共6套服装/准爸准妈共拍/免费肚画/底片全送。",
- "pteamprice": 288
- },
- {
- "pteamId": 72598,
- "ptitle": "随摄影/拍摄200张/4本相册/品质拍摄/送全新婚纱。",
- "pteamprice": 2888
- },
- {
- "pteamId": 72613,
- "ptitle": "随摄影/送全新婚纱/多外景拍摄/服装不限数量/绝无二次消费!",
- "pteamprice": 3699
- },
- {
- "pteamId": 72638,
- "ptitle": "随摄影/服装不限数量/高品质拍摄260张/送全新婚纱。",
- "pteamprice": 4299
- },
- {
- "pteamId": 72716,
- "ptitle": "随摄影/3组服装造型/内外景拍摄/完全透明消费!",
- "pteamprice": 388
- }
- ],
- "liketeamlist": [
- {
- "lteamId": 65886,
- "ltitle": "爱丽尔婚纱摄影/2本相册/6套服装造型/拍摄不限最低拍摄150张。",
- "limage": "http://img.pztuan.com/upfile/team/2013/0712/201307120257551465.jpg",
- "lteamprice": 518,
- "lmarketprice": 3999
- },
- {
- "lteamId": 57133,
- "ltitle": "陶冶摄影/婚纱闺蜜/6组服装造型/拍摄不低于120张!",
- "limage": "http://img.pztuan.com/upfile/team/2013/0628/201306281115249737.jpg",
- "lteamprice": 580,
- "lmarketprice": 3380
- }
- ],
- "feedbacks": {
- "feedbacklist": [
- {
- "comment": "5分",
- "createtime": "2014.07.08 13:38",
- "score": 5,
- "username": "l***2"
- }
- ],
- "totalcount": 1,
- "totalscore": 5
- }
- },
- "err": null,
- "state": 1
- }
实体类(里面的成员变量和接口的返回值名称一 一对应才能保证解析正确):
- package com.pztuan.entity;
- import java.util.List;
- public class OtherDetail {
- private int state;
- private List<err> err;
- private OtherDetail2 data;
- public int getState() {
- return state;
- }
- public void setState(int state) {
- this.state = state;
- }
- public List<err> getErr() {
- return err;
- }
- public void setErr(List<err> err) {
- this.err = err;
- }
- public OtherDetail2 getData() {
- return data;
- }
- public void setData(OtherDetail2 data) {
- this.data = data;
- }
- public class OtherDetail2 {
- private List<partnerteamlist> partnerteamlist;
- private List<liketeamlist> liketeamlist;
- private List<feedbacks> feedbacks;
- public List<liketeamlist> getLiketeamlist() {
- return liketeamlist;
- }
- public void setLiketeamlist(List<liketeamlist> liketeamlist) {
- this.liketeamlist = liketeamlist;
- }
- public List<feedbacks> getFeedbacks() {
- return feedbacks;
- }
- public void setFeedbacks(List<feedbacks> feedbacks) {
- this.feedbacks = feedbacks;
- }
- public class partnerteamlist {
- private int pteamId;
- private String ptitle;
- private Double pteamprice;
- public int getPteamId() {
- return pteamId;
- }
- public void setPteamId(int pteamId) {
- this.pteamId = pteamId;
- }
- public String getPtitle() {
- return ptitle;
- }
- public void setPtitle(String ptitle) {
- this.ptitle = ptitle;
- }
- public Double getPteamprice() {
- return pteamprice;
- }
- public void setPteamprice(Double pteamprice) {
- this.pteamprice = pteamprice;
- }
- }
- public class liketeamlist {
- private int lteamId;
- private String ltitle;
- private String limage;
- private Double lteamprice;
- private Double lmarketprice;
- public int getLteamId() {
- return lteamId;
- }
- public void setLteamId(int lteamId) {
- this.lteamId = lteamId;
- }
- public String getLtitle() {
- return ltitle;
- }
- public void setLtitle(String ltitle) {
- this.ltitle = ltitle;
- }
- public String getLimage() {
- return limage;
- }
- public void setLimage(String limage) {
- this.limage = limage;
- }
- public Double getLteamprice() {
- return lteamprice;
- }
- public void setLteamprice(Double lteamprice) {
- this.lteamprice = lteamprice;
- }
- public Double getLmarketprice() {
- return lmarketprice;
- }
- public void setLmarketprice(Double lmarketprice) {
- this.lmarketprice = lmarketprice;
- }
- }
- public class feedbacks {
- private int totalcount;
- private Double totalscore;
- private List<feedbacklist> feedbacklist;
- public int getTotalcount() {
- return totalcount;
- }
- public void setTotalcount(int totalcount) {
- this.totalcount = totalcount;
- }
- public Double getTotalscore() {
- return totalscore;
- }
- public void setTotalscore(Double totalscore) {
- this.totalscore = totalscore;
- }
- public List<feedbacklist> getFeedbacklist() {
- return feedbacklist;
- }
- public void setFeedbacklist(List<feedbacklist> feedbacklist) {
- this.feedbacklist = feedbacklist;
- }
- public class feedbacklist {
- private String username;
- private String comment;
- private String createtime;
- private Double score;
- public String getUsername() {
- return username;
- }
- public void setUsername(String username) {
- this.username = username;
- }
- public String getComment() {
- return comment;
- }
- public void setComment(String comment) {
- this.comment = comment;
- }
- public String getCreatetime() {
- return createtime;
- }
- public void setCreatetime(String createtime) {
- this.createtime = createtime;
- }
- public Double getScore() {
- return score;
- }
- public void setScore(Double score) {
- this.score = score;
- }
- }
- }
- public List<partnerteamlist> getPartnerteamlist() {
- return partnerteamlist;
- }
- public void setPartnerteamlist(List<partnerteamlist> partnerteamlist) {
- this.partnerteamlist = partnerteamlist;
- }
- }
- public class err {
- private int code;
- private String msg;
- public int getCode() {
- return code;
- }
- public void setCode(int code) {
- this.code = code;
- }
- public String getMsg() {
- return msg;
- }
- public void setMsg(String msg) {
- this.msg = msg;
- }
- }
- }
注意上面内部类的运用。
解析:
- Gson gson = new Gson();
- OtherDetail d = gson.fromJson(jsonString,Detail.class);//取值的时候就从父类一层一层调子类成员(重要)
若出现引用异常,请查看Java内部类设计原则。
参考:http://www.itzhai.com/android-to-parse-json-data-using-gson.html
http://blog.csdn.net/caijunjun1006/article/details/11762841
在Android中可以使用Gson解析JSON数据
首先,从 code.google.com/p/google-gson/downloads/list下载GsonAPI:
把gson-1.7.jar copy到libs(项目根目录新建一个libs文件夹)中。
通过获取JsonReader对象解析JSON数据:
String jsonData = "[{\"username\":\"arthinking\",\"userId\":001},{\"username\":\"Jason\",\"userId\":002}]";try{JsonReader reader = new JsonReader(new StringReader(jsonData));reader.beginArray();while(reader.hasNext()){reader.beginObject();while(reader.hasNext()){String tagName = reader.nextName();if(tagName.equals("username")){System.out.println(reader.nextString());}else if(tagName.equals("userId")){System.out.println(reader.nextString());}}reader.endObject();}reader.endArray();}catch(Exception e){e.printStackTrace();}
通过把JSON数据映射成一个对象,使用Gson对象的fromJson()方法获取一个对象数组进行操作:
创建JSON数据对应的一个POJO对象User.java:
public class User {private String username ;private int userId ;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public int getUserId() {return userId;}public void setUserId(int userId) {this.userId = userId;}}
使用Gson对象获取User对象数据进行相应的操作:
Type listType = new TypeToken<LinkedList<User>>(){}.getType();Gson gson = new Gson();LinkedList<User> users = gson.fromJson(jsonData, listType);for (Iterator iterator = users.iterator(); iterator.hasNext();) {User user = (User) iterator.next();System.out.println(user.getUsername());System.out.println(user.getUserId());}
如果要处理的JSON字符串只包含一个JSON对象,则可以直接使用fromJson获取一个User对象:
String jsonData = "{\"username\":\"arthinking\",\"userId\":001}";Gson gson = new Gson();User user = gson.fromJson(jsonData, User.class);System.out.println(user.getUsername());System.out.println(user.getUserId());
什么是JSON:
JSON即JavaScript Object Natation, 它是一种轻量级的数据交换格式, 与XML一样, 是广泛被采用的客户端和服务端交互的解决方案.
JSON对象:
JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, key-value对之间使用逗号分隔. 如:{"name":"coolxing", "age"=24, "male":true, "address":{"street":"huiLongGuan", "city":"beijing", "country":"china"}}. JSON对象的key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况.
JSON数组:
JSON数组(array)以"["开始, 以"]"结束, 数组中的每一个元素可以是string, number, false, true, null, Object对象甚至是array数组, 数组间的元素使用逗号分隔. 如["coolxing", 24, {"street":"huiLongGuan", "city":"beijing", "country":"china"}].
JSON数据的解析:
解析JSON数据, 首先需要明确待解析的是JSON Object还是JSON array, 然后需要确定采用哪种解析技术. android平台上一般有2种解析技术可供选择:android内置的org.json包和google的开源gson库. 以下将分别采用这两种技术解析JSON对象和JSON数组.
1. 采用android内置的org.json包解析JSON对象. 假设待解析的JSON数据为json = "{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}", 其中\用于转义表达式中的双引号. 首先定义2个JavaBean:
- package text.com.bean;
- public class Address {
- private String street;
- private String city;
- private String country;
- public Address() {
- super();
- }
- public Address(String street, String city, String country) {
- super();
- this.street = street;
- this.city = city;
- this.country = country;
- }
- public String getStreet() {
- return street;
- }
- public void setStreet(String street) {
- this.street = street;
- }
- public String getCity() {
- return city;
- }
- public void setCity(String city) {
- this.city = city;
- }
- public String getCountry() {
- return country;
- }
- public void setCountry(String country) {
- this.country = country;
- }
- @Override
- public String toString() {
- return "Address [street=" + street + ", city=" + city + ", country="
- + country + "]";
- }
- }
- package text.com.bean;
- public class Person {
- private String name;
- private int age;
- private boolean male;
- private Address address;
- public Person() {
- super();
- }
- public Person(String name, int age, boolean male, Address address) {
- super();
- this.name = name;
- this.age = age;
- this.male = male;
- this.address = address;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public boolean isMale() {
- return male;
- }
- public void setMale(boolean male) {
- this.male = male;
- }
- public Address getAddress() {
- return address;
- }
- public void setAddress(Address address) {
- this.address = address;
- }
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + ", male=" + male
- + ", address=" + address + "]";
- }
- }
首先使用方法一解析代码如下:
- JSONObject jsonObject = new JSONObject(json);
- String name = jsonObject.getString("name");
- int age = jsonObject.getInt("age");
- boolean male = jsonObject.getBoolean("male");
- JSONObject addressJSON = jsonObject.getJSONObject("address");
- String street = addressJSON.getString("street");
- String city = addressJSON.getString("city");
- String country = addressJSON.getString("country");
- Address address = new Address(street, city, country);
- Person person = new Person(name, age, male, address);
- System.out.println(person);
2. 采用gson库解析JSON对象. 假设带解析的JSON数据是json = "{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}", 首先需要到http://code.google.com/p/google-gson/下载jar包, 并将其添加到项目中. 具体的解析代码如下:
- Gson gson = new Gson();
- Person person = gson.fromJson(json, Person.class);
- System.out.println(person);
3. 采用android内置的org.json包解析JSON数组. 假设待解析的JSON数据为json = "[{\"name\":\"coolxing\", \"age\"=24, \"male\":true, \"address\":{\"street\":\"huiLongGuan\", \"city\":\"beijing\", \"country\":\"china\"}}, {\"name\":\"min\", \"age\"=20, \"male\":false, \"address\":{\"street\":\"heiShiJiao\", \"city\":\"daLian\", \"country\":\"china\"}}]", 解析代码如下:
- List<Person> persons = new ArrayList<Person>();
- JSONArray jsonArray = new JSONArray(json);
- for(int i = 0; i < jsonArray.length(); i++) {
- JSONObject jsonObject = jsonArray.getJSONObject(i);
- String name = jsonObject.getString("name");
- int age = jsonObject.getInt("age");
- boolean male = jsonObject.getBoolean("male");
- JSONObject addressJSON = jsonObject.getJSONObject("address");
- String street = addressJSON.getString("street");
- String city = addressJSON.getString("city");
- String country = addressJSON.getString("country");
- Address address = new Address(street, city, country);
- Person person = new Person(name, age, male, address);
- persons.add(person);
- }
- System.out.println(persons);
4. 采用gson库解析JSON数组. 待解析的JSON数据同上, 具体代码为:
- Gson gson = new Gson();
- Type listType = new TypeToken<List<Person>>(){}.getType();
- List<Person> persons = gson.fromJson(json, listType);
测试用例:
- package text.com;
- import java.io.BufferedReader;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.InputStreamReader;
- import java.lang.reflect.Type;
- import java.util.List;
- import text.com.bean.Address;
- import text.com.bean.Person;
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
- public class JsonTest {
- String jsonString = "";
- public static void main(String[] args) {
- // Person p1 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",
- // "30号"));
- // Person p2 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",
- // "30号"));
- // Person p3 = new Person("zhangsan", 12, true, new Address("北京", "海淀区",
- // "30号"));
- // List<Person> list = new ArrayList<Person>();
- // list.add(p1);
- // list.add(p2);
- // list.add(p3);
- // Gson gson = new Gson();
- // Type typeOfT = new TypeToken<List<Person>>(){}.getType();
- // String json = gson.toJson(list, typeOfT);
- // System.out.println("json:"+json);
- // String str = readTxtFile("D:\\cjjworkspace\\Test\\json.txt");
- // System.out.println("文件内容:" + str);
- Gson gson = new Gson();
- // Type typeOfT = new TypeToken<List<Person>>(){}.getType();
- // List<Person> personList = gson.fromJson(str, typeOfT);
- Person p1 = new Person("zhangsan", 12, true, new Address("北京", "海淀区", "30号"));
- Type typeOfT = new TypeToken<Person>(){}.getType();
- String str = gson.toJson(p1, typeOfT);
- System.out.println(str);
- }
- public static String readTxtFile(String filePath) {
- String encoding = "utf-8";
- StringBuilder sb = new StringBuilder();
- try {
- File file = new File(filePath);
- if (file.isFile() && file.exists()) { // 判断文件是否存在
- InputStreamReader read = new InputStreamReader(new FileInputStream(file), encoding);// 考虑到编码格式
- BufferedReader bufferedReader = new BufferedReader(read);
- String str = "";
- while ((str = bufferedReader.readLine()) != null) {
- sb.append(str);
- }
- read.close();
- return sb.toString();
- } else {
- System.out.println("找不到指定的文件");
- return null;
- }
- } catch (Exception e) {
- System.out.println("读取文件内容出错");
- e.printStackTrace();
- }
- return sb.toString();
- }
- }
gson-2.2.4-javadoc.jar
gson-2.2.4-sources.jar
- Android用GSon处理Json数据
- http://www.javaask.com/mobile/android/2011/0420/6948.html
- package com.demo;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.protocol.HTTP;
- import android.util.Log;
- public class WebDataGetApi {
- private static final String TAG = "WebDataGetAPI";
- private static final String USER_AGENT = "Mozilla/4.5";
- protected String getRequest(String url) throws Exception {
- return getRequest(url, new DefaultHttpClient(new BasicHttpParams()));
- }
- protected String getRequest(String url, DefaultHttpClient client)
- throws Exception {
- String result = null;
- int statusCode = 0;
- HttpGet getMethod = new HttpGet(url);
- Log.d(TAG, "do the getRequest,url=" + url + "");
- try {
- getMethod.setHeader("User-Agent", USER_AGENT);
- // HttpParams params = new HttpParams();
- // 添加用户密码验证信息
- // client.getCredentialsProvider().setCredentials(
- // new AuthScope(null, -1),
- // new UsernamePasswordCredentials(mUsername, mPassword));
- HttpResponse httpResponse = client.execute(getMethod);
- // statusCode == 200 正常
- statusCode = httpResponse.getStatusLine().getStatusCode();
- Log.d(TAG, "statuscode = " + statusCode);
- // 处理返回的httpResponse信息
- result = retrieveInputStream(httpResponse.getEntity());
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- throw new Exception(e);
- } finally {
- getMethod.abort();
- }
- return result;
- }
- /**
- * 处理httpResponse信息,返回String
- *
- * @param httpEntity
- * @return String
- */
- protected String retrieveInputStream(HttpEntity httpEntity) {
- int length = (int) httpEntity.getContentLength();
- if (length < 0)
- length = 10000;
- StringBuffer stringBuffer = new StringBuffer(length);
- try {
- InputStreamReader inputStreamReader = new InputStreamReader(
- httpEntity.getContent(), HTTP.UTF_8);
- char buffer[] = new char[length];
- int count;
- while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {
- stringBuffer.append(buffer, 0, count);
- }
- } catch (UnsupportedEncodingException e) {
- Log.e(TAG, e.getMessage());
- } catch (IllegalStateException e) {
- Log.e(TAG, e.getMessage());
- } catch (IOException e) {
- Log.e(TAG, e.getMessage());
- }
- return stringBuffer.toString();
- }
- }
- 二. 建立JsonDataGetApi.java
- package com.demo;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- public class JsonDataGetApi extends WebDataGetApi {
- private static final String BASE_URL = "http://10.0.2.2:82/AccountService/";
- private static final String EXTENSION = "Json/";;
- public JSONObject getObject(String sbj) throws JSONException, Exception {
- return new JSONObject(getRequest(BASE_URL + EXTENSION + sbj));
- }
- public JSONArray getArray(String sbj) throws JSONException, Exception {
- return new JSONArray(getRequest(BASE_URL + EXTENSION + sbj));
- }
- }
- 三. 建立Android端Account模型Account.java
- package com.demo;
- import java.util.Date;
- public class Account {
- public String Name;
- public int Age;
- public String Address;
- public Date Birthday;
- }
- 四. 在我们的主Activity中调用刚才的方法, 在这一步中我们需要引入Google的gson 库gson-1.6.jar至我们的工程(下载地址)
- package com.demo;
- import java.util.Date;
- import org.json.JSONArray;
- import org.json.JSONObject;
- import com.google.gson.Gson;
- import com.google.gson.GsonBuilder;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.TextView;
- import android.widget.Toast;
- public class WebData extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- getJsonData();
- }
- public void getJsonData() {
- JsonDataGetApi api = new JsonDataGetApi();
- JSONArray jArr;
- JSONObject jobj;
- try {
- //调用GetAccountData方法
- jArr = api.getArray("GetAccountData");
- //从返回的Account Array中取出第一个数据
- jobj = jArr.getJSONObject(0);
- GsonBuilder gsonb = new GsonBuilder();
- //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.
- //DateDeserializer ds = new DateDeserializer();
- //给GsonBuilder方法单独指定Date类型的反序列化方法
- //gsonb.registerTypeAdapter(Date.class, ds);
- Gson gson = gsonb.create();
- Account account = gson.fromJson(jobj.toString(), Account.class);
- Log.d("LOG_CAT", jobj.toString());
- ((TextView) findViewById(R.id.Name)).setText(account.Name);
- ((TextView) findViewById(R.id.Age)).setText(account.Age);
- ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday
- .toGMTString());
- ((TextView) findViewById(R.id.Address)).setText(account.Address);
- } catch (Exception e) {
- Toast.makeText(getApplicationContext(), e.getMessage(),
- Toast.LENGTH_LONG).show();
- e.printStackTrace();
- TextView movie_Address = (TextView) findViewById(R.id.Address);
- movie_Address.setText(e.getMessage());
- }
- }
- }
- 五.我们开始构建UI
- 打开layout下的main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView android:id="@+id/Name" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView android:id="@+id/Age" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView android:id="@+id/Birthday" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView android:id="@+id/Address" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
- 在配置好RunConfiguration之后,我们开始运行程序, 查看Log发现有以下错误,
- image
- 意思是说访问被禁止,也就是未授权访问, 其意思并不是我们的服务未授权, 因为Andriod具有很好的很好很好的安全机制, 我们要访问网络必须要经过授权才可以;
- 我们打开res目录下AndroidManifest.xml, 注意字体加粗放大的那句, 就是给我们的程序加入Internet的访问授权.
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.demo"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".WebData"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
- 再次运行程序, 会发现显示如下:
- image
- image
- 从上图中的statuscode = 200来看,说明我们的请求已经成功, 问题出现在Json Parse(Json数据转换/反序列化/格式化)的过程中, 我们现在把从服务器传过来的数据拿出来看看, 在浏览器输入我们的服务地址: http://localhost:82/AccountService/Json/GetAccountData
- [
- {
- "Address": "YouYi East Road",
- "Age": 56,
- "Birthday": "/Date(1298605481453+0800)/",
- "Name": "Bill Gates"
- },
- {
- "Address": "YouYi West Road",
- "Age": 57,
- "Birthday": "/Date(1298605481453+0800)/",
- "Name": "Steve Paul Jobs"
- },
- {
- "Address": "YouYi North Road",
- "Age": 65,
- "Birthday": "/Date(1298605481453+0800)/",
- "Name": "John D. Rockefeller"
- }
- ]
- 我们发现其中的Birthday的结果并非我们想象中yyyy-mm-dd HH:mm:ss类型, 究其原因可以查看MSDN文章《JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 简介》
- 现在我们给我们的GsonBuilder指定Date的序列化方法, 先增加一个Date反序列化的类DateDeserializer.java
- package com.demo;
- import java.lang.reflect.Type;
- import java.util.Date;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import com.google.gson.JsonDeserializationContext;
- import com.google.gson.JsonDeserializer;
- import com.google.gson.JsonElement;
- import com.google.gson.JsonParseException;
- public class DateDeserializer implements JsonDeserializer<Date> {
- public Date deserialize(JsonElement json, Type typeOfT,
- JsonDeserializationContext context) throws JsonParseException {
- String JSONDateToMilliseconds = "\\/(Date\\((.*?)(\\+.*)?\\))\\/";
- Pattern pattern = Pattern.compile(JSONDateToMilliseconds);
- Matcher matcher = pattern.matcher(json.getAsJsonPrimitive()
- .getAsString());
- String result = matcher.replaceAll("$2");
- return new Date(new Long(result));
- }
- }
- 其次修改Activity类中的GetDate方法如下, 注意其中加粗的部分.
- public void getJsonData() {
- JsonDataGetApi api = new JsonDataGetApi();
- JSONArray jArr;
- JSONObject jobj;
- try {
- //调用GetAccountData方法
- jArr = api.getArray("GetAccountData");
- //从返回的Account Array中取出第一个数据
- jobj = jArr.getJSONObject(0);
- GsonBuilder gsonb = new GsonBuilder();
- //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.
- DateDeserializer ds = new DateDeserializer();
- //给GsonBuilder方法单独指定Date类型的反序列化方法
- gsonb.registerTypeAdapter(Date.class, ds);
- Gson gson = gsonb.create();
- Account account = gson.fromJson(jobj.toString(), Account.class);
- Log.d("LOG_CAT", jobj.toString());
- ((TextView) findViewById(R.id.Name)).setText(account.Name);
- ((TextView) findViewById(R.id.Age)).setText(String.valueOf(account.Age));
- ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday
- .toGMTString());
- ((TextView) findViewById(R.id.Address)).setText(account.Address);
- } catch (Exception e) {
- Toast.makeText(getApplicationContext(), e.getMessage(),
- Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- }
- }
- 我们现在再运行程序 :
- image
- 执行成功.
GsonBuilder builder = new GsonBuilder();
// 不转换没有 @Expose 注解的字段
builder.excludeFieldsWithoutExposeAnnotation();
Gson gson = builder.create();
//1、对象转string
Student stu = new Student();
stu.setStudentId(333);
stu.setStudentName("qqq");
String stuStr = gson.toJson(stu);
System.out.println(stuStr); //{"studentName":"qqq","studentId":333}
//2、string转对象
Student user2 = gson.fromJson(stuStr, Student.class);
System.out.println(user2);
String stuTemp = "{\"studentName\":\"qqq2\",\"studentId\":3335}";
Student user4 = gson.fromJson(stuTemp, Student.class);
System.out.println(user4);
//3、对象List转string
List<Student> testBeanList = new ArrayList<Student>();
Student testBean = new Student();
testBean.setStudentId(555);
testBean.setStudentName("552");
testBeanList.add(testBean);
//Gson gsonList = new Gson();
Type type = new TypeToken<List<Student>>(){}.getType(); //指定集合对象属性
String beanListToJson = gson.toJson(testBeanList, type);
System.out.println(beanListToJson); //[{"studentName":"552","studentId":555}]
//集合string转对象list
List<Student> testBeanListFromJson = gson.fromJson(beanListToJson, type);
System.out.println(testBeanListFromJson); //[555:552]
//4、集合如果不指定类型 默认为String
List<String> testList = new ArrayList<String>();
testList.add("first");
testList.add("second");
String listToJson = gson.toJson(testList);
System.out.println(listToJson); //["first","second"]
//5、集合字符串转回来需要指定类型
List<String> testList2 = (List<String>) gson.fromJson(listToJson,
new TypeToken<List<String>>() {
}.getType());
System.out.println(testList2);
//6、 将HashMap字符串转换为 JSON
Map<String, String> testMap = new HashMap<String, String>();
testMap.put("id", "id.first");
testMap.put("name", "name.second");
String mapToJson = gson.toJson(testMap);
System.out.println(mapToJson); //{"id":"id.first","name":"name.second"}
//7、stringMap转对象
Map<String, String> userMap2 = (Map<String, String>) gson.fromJson(mapToJson,
new TypeToken<Map<String, String>>() {
}.getType());
System.out.println(userMap2); //{id=id.first, name=name.second}
//8、对象含有普通对象、集合、map情况
Student user1 = new Student();
user1.setStudentId(1001);
user1.setStudentName("张三");
Student user3 = new Student();
user3.setStudentId(1002);
user3.setStudentName("李四");
Map<String, Student> userMap = new HashMap<String, Student>();
userMap.put("user1", user1);
userMap.put("user3", user3);
List<Student> userList = new ArrayList<Student>();
userList.add(user1);
userList.add(user3);
Teacher groupBean = new Teacher();
groupBean.setStudent(user1);
groupBean.setStus(userList);
groupBean.setMap((HashMap)userMap);
//groupBean.setUserList(userList);
Gson gsonGroup = new Gson();
String sGroupBean = gsonGroup.toJson(groupBean, new TypeToken<Teacher>() {
}.getType());
System.out.println(sGroupBean);
/*{"stus":[{"studentName":"张三","studentId":1001},{"studentName":"李四","studentId":1002}],"student":{"studentName":"张三","studentId":1001},"map":{"user3":{"studentName":"李四","studentId":1002},"user1":{"studentName":"张三","studentId":1001}},"id":0,"age":0}*/
//9、复杂对象string转对象
Teacher groupBean2 = (Teacher) gson.fromJson(sGroupBean,
new TypeToken<Teacher>() {
}.getType());
System.out.println(groupBean2);
package com.andtools;
import com.google.gson.annotations.Expose;
public class Student {
@Expose
private String studentName;
@Expose
private int studentId;
public Student(){}
public Student(int studentId,String studentName){
this.setStudentId(studentId);
this.setStudentName(studentName);
}
public String toString(){
return this.getStudentId() + ":" + this.getStudentName();
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
}
package com.andtools;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.google.gson.annotations.Expose;
public class Teacher {
@Expose
private int id;
@Expose
private String name;
@Expose
private int age;
@Expose
private Student student;
@Expose
private List stus;
@Expose
private HashMap map;
public String toString(){
return this.getId()+":"+this.getName()+":"+this.getAge() +":"+ this.getStudent().toString() + ":" + this.getStus() + ":" + this.getMap();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
public List getStus() {
return stus;
}
public void setStus(List stus) {
this.stus = stus;
}
public HashMap getMap() {
return map;
}
public void setMap(HashMap map) {
this.map = map;
}
}
一. 建立我们包装好的Http请求类文件 WebDataGetApi.java
- package com.demo;
- import java.io.IOException;
- import java.io.InputStreamReader;
- import java.io.UnsupportedEncodingException;
- import org.apache.http.HttpEntity;
- import org.apache.http.HttpResponse;
- import org.apache.http.client.methods.HttpGet;
- import org.apache.http.impl.client.DefaultHttpClient;
- import org.apache.http.params.BasicHttpParams;
- import org.apache.http.protocol.HTTP;
- import android.util.Log;
- public class WebDataGetApi {
- private static final String TAG = "WebDataGetAPI";
- private static final String USER_AGENT = "Mozilla/4.5";
- protected String getRequest(String url) throws Exception {
- return getRequest(url, new DefaultHttpClient(new BasicHttpParams()));
- }
- protected String getRequest(String url, DefaultHttpClient client)
- throws Exception {
- String result = null;
- int statusCode = 0;
- HttpGet getMethod = new HttpGet(url);
- Log.d(TAG, "do the getRequest,url=" + url + "");
- try {
- getMethod.setHeader("User-Agent", USER_AGENT);
- // HttpParams params = new HttpParams();
- // 添加用户密码验证信息
- // client.getCredentialsProvider().setCredentials(
- // new AuthScope(null, -1),
- // new UsernamePasswordCredentials(mUsername, mPassword));
- HttpResponse httpResponse = client.execute(getMethod);
- // statusCode == 200 正常
- statusCode = httpResponse.getStatusLine().getStatusCode();
- Log.d(TAG, "statuscode = " + statusCode);
- // 处理返回的httpResponse信息
- result = retrieveInputStream(httpResponse.getEntity());
- } catch (Exception e) {
- Log.e(TAG, e.getMessage());
- throw new Exception(e);
- } finally {
- getMethod.abort();
- }
- return result;
- }
- /**
- * 处理httpResponse信息,返回String
- *
- * @param httpEntity
- * @return String
- */
- protected String retrieveInputStream(HttpEntity httpEntity) {
- int length = (int) httpEntity.getContentLength();
- if (length < 0)
- length = 10000;
- StringBuffer stringBuffer = new StringBuffer(length);
- try {
- InputStreamReader inputStreamReader = new InputStreamReader(
- httpEntity.getContent(), HTTP.UTF_8);
- char buffer[] = new char[length];
- int count;
- while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {
- stringBuffer.append(buffer, 0, count);
- }
- } catch (UnsupportedEncodingException e) {
- Log.e(TAG, e.getMessage());
- } catch (IllegalStateException e) {
- Log.e(TAG, e.getMessage());
- } catch (IOException e) {
- Log.e(TAG, e.getMessage());
- }
- return stringBuffer.toString();
- }
- }
- package com.demo;
- import org.json.JSONArray;
- import org.json.JSONException;
- import org.json.JSONObject;
- public class JsonDataGetApi extends WebDataGetApi {
- private static final String BASE_URL = "http://10.0.2.2:82/AccountService/";
- private static final String EXTENSION = "Json/";;
- public JSONObject getObject(String sbj) throws JSONException, Exception {
- return new JSONObject(getRequest(BASE_URL + EXTENSION + sbj));
- }
- public JSONArray getArray(String sbj) throws JSONException, Exception {
- return new JSONArray(getRequest(BASE_URL + EXTENSION + sbj));
- }
- }
三. 建立Android端Account模型Account.java
- import java.util.Date;
- public class Account {
- public String Name;
- public int Age;
- public String Address;
- public Date Birthday;
- }
- package com.demo;
- import java.util.Date;
- import org.json.JSONArray;
- import org.json.JSONObject;
- import com.google.gson.Gson;
- import com.google.gson.GsonBuilder;
- import android.app.Activity;
- import android.os.Bundle;
- import android.util.Log;
- import android.widget.TextView;
- import android.widget.Toast;
- public class WebData extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- getJsonData();
- }
- public void getJsonData() {
- JsonDataGetApi api = new JsonDataGetApi();
- JSONArray jArr;
- JSONObject jobj;
- try {
- //调用GetAccountData方法
- jArr = api.getArray("GetAccountData");
- //从返回的Account Array中取出第一个数据
- jobj = jArr.getJSONObject(0);
- GsonBuilder gsonb = new GsonBuilder();
- //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.
- //DateDeserializer ds = new DateDeserializer();
- //给GsonBuilder方法单独指定Date类型的反序列化方法
- //gsonb.registerTypeAdapter(Date.class, ds);
- Gson gson = gsonb.create();
- Account account = gson.fromJson(jobj.toString(), Account.class);
- Log.d("LOG_CAT", jobj.toString());
- ((TextView) findViewById(R.id.Name)).setText(account.Name);
- ((TextView) findViewById(R.id.Age)).setText(account.Age);
- ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday
- .toGMTString());
- ((TextView) findViewById(R.id.Address)).setText(account.Address);
- } catch (Exception e) {
- Toast.makeText(getApplicationContext(), e.getMessage(),
- Toast.LENGTH_LONG).show();
- e.printStackTrace();
- TextView movie_Address = (TextView) findViewById(R.id.Address);
- movie_Address.setText(e.getMessage());
- }
- }
- }
打开layout下的main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView android:id="@+id/Name" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView android:id="@+id/Age" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView android:id="@+id/Birthday" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <TextView android:id="@+id/Address" android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
意思是说访问被禁止,也就是未授权访问, 其意思并不是我们的服务未授权, 因为Andriod具有很好的很好很好的安全机制, 我们要访问网络必须要经过授权才可以;
我们打开res目录下AndroidManifest.xml, 注意字体加粗放大的那句, 就是给我们的程序加入Internet的访问授权.
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.demo"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".WebData"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
从上图中的statuscode = 200来看,说明我们的请求已经成功, 问题出现在Json Parse(Json数据转换/反序列化/格式化)的过程中, 我们现在把从服务器传过来的数据拿出来看看, 在浏览器输入我们的服务地址: http://localhost:82/AccountService/Json/GetAccountData
[ { "Address": "YouYi East Road", "Age": 56, "Birthday": "/Date(1298605481453+0800)/", "Name": "Bill Gates" }, { "Address": "YouYi West Road", "Age": 57, "Birthday": "/Date(1298605481453+0800)/", "Name": "Steve Paul Jobs" }, { "Address": "YouYi North Road", "Age": 65, "Birthday": "/Date(1298605481453+0800)/", "Name": "John D. Rockefeller" }]
我们发现其中的Birthday的结果并非我们想象中yyyy-mm-dd HH:mm:ss类型, 究其原因可以查看MSDN文章《JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 简介》
现在我们给我们的GsonBuilder指定Date的序列化方法, 先增加一个Date反序列化的类DateDeserializer.java
- package com.demo;
- import java.lang.reflect.Type;
- import java.util.Date;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import com.google.gson.JsonDeserializationContext;
- import com.google.gson.JsonDeserializer;
- import com.google.gson.JsonElement;
- import com.google.gson.JsonParseException;
- public class DateDeserializer implements JsonDeserializer<Date> {
- public Date deserialize(JsonElement json, Type typeOfT,
- JsonDeserializationContext context) throws JsonParseException {
- String JSONDateToMilliseconds = "\\/(Date\\((.*?)(\\+.*)?\\))\\/";
- Pattern pattern = Pattern.compile(JSONDateToMilliseconds);
- Matcher matcher = pattern.matcher(json.getAsJsonPrimitive()
- .getAsString());
- String result = matcher.replaceAll("$2");
- return new Date(new Long(result));
- }
- }
- public void getJsonData() {
- JsonDataGetApi api = new JsonDataGetApi();
- JSONArray jArr;
- JSONObject jobj;
- try {
- //调用GetAccountData方法
- jArr = api.getArray("GetAccountData");
- //从返回的Account Array中取出第一个数据
- jobj = jArr.getJSONObject(0);
- GsonBuilder gsonb = new GsonBuilder();
- //Json中的日期表达方式没有办法直接转换成我们的Date类型, 因此需要单独注册一个Date的反序列化类.
- DateDeserializer ds = new DateDeserializer();
- //给GsonBuilder方法单独指定Date类型的反序列化方法
- gsonb.registerTypeAdapter(Date.class, ds);
- Gson gson = gsonb.create();
- Account account = gson.fromJson(jobj.toString(), Account.class);
- Log.d("LOG_CAT", jobj.toString());
- ((TextView) findViewById(R.id.Name)).setText(account.Name);
- ((TextView) findViewById(R.id.Age)).setText(String.valueOf(account.Age));
- ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday
- .toGMTString());
- ((TextView) findViewById(R.id.Address)).setText(account.Address);
- } catch (Exception e) {
- Toast.makeText(getApplicationContext(), e.getMessage(),
- Toast.LENGTH_LONG).show();
- e.printStackTrace();
- }
- }
- }
- <span style="font-family:Arial;BACKGROUND-COLOR: #ffffff"></span>
执行成功.
示例下载
- //转换器
- GsonBuilder builder = new GsonBuilder();
- // 不转换没有 @Expose 注解的字段
- builder.excludeFieldsWithoutExposeAnnotation();
- Gson gson = builder.create();
- //1、对象转string
- Student stu = new Student();
- stu.setStudentId(333);
- stu.setStudentName("qqq");
- String stuStr = gson.toJson(stu);
- System.out.println(stuStr); //{"studentName":"qqq","studentId":333}
- //2、string转对象
- Student user2 = gson.fromJson(stuStr, Student.class);
- System.out.println(user2);
- String stuTemp = "{\"studentName\":\"qqq2\",\"studentId\":3335}";
- Student user4 = gson.fromJson(stuTemp, Student.class);
- System.out.println(user4);
- //3、对象List转string
- List<Student> testBeanList = new ArrayList<Student>();
- Student testBean = new Student();
- testBean.setStudentId(555);
- testBean.setStudentName("552");
- testBeanList.add(testBean);
- //Gson gsonList = new Gson();
- Type type = new TypeToken<List<Student>>(){}.getType(); //指定集合对象属性
- String beanListToJson = gson.toJson(testBeanList, type);
- System.out.println(beanListToJson); //[{"studentName":"552","studentId":555}]
- //集合string转对象list
- List<Student> testBeanListFromJson = gson.fromJson(beanListToJson, type);
- System.out.println(testBeanListFromJson); //[555:552]
- //4、集合如果不指定类型 默认为String
- List<String> testList = new ArrayList<String>();
- testList.add("first");
- testList.add("second");
- String listToJson = gson.toJson(testList);
- System.out.println(listToJson); //["first","second"]
- //5、集合字符串转回来需要指定类型
- List<String> testList2 = (List<String>) gson.fromJson(listToJson,
- new TypeToken<List<String>>() {
- }.getType());
- System.out.println(testList2);
- //6、 将HashMap字符串转换为 JSON
- Map<String, String> testMap = new HashMap<String, String>();
- testMap.put("id", "id.first");
- testMap.put("name", "name.second");
- String mapToJson = gson.toJson(testMap);
- System.out.println(mapToJson); //{"id":"id.first","name":"name.second"}
- //7、stringMap转对象
- Map<String, String> userMap2 = (Map<String, String>) gson.fromJson(mapToJson,
- new TypeToken<Map<String, String>>() {
- }.getType());
- System.out.println(userMap2); //{id=id.first, name=name.second}
- //8、对象含有普通对象、集合、map情况
- Student user1 = new Student();
- user1.setStudentId(1001);
- user1.setStudentName("张三");
- Student user3 = new Student();
- user3.setStudentId(1002);
- user3.setStudentName("李四");
- Map<String, Student> userMap = new HashMap<String, Student>();
- userMap.put("user1", user1);
- userMap.put("user3", user3);
- List<Student> userList = new ArrayList<Student>();
- userList.add(user1);
- userList.add(user3);
- Teacher groupBean = new Teacher();
- groupBean.setStudent(user1);
- groupBean.setStus(userList);
- groupBean.setMap((HashMap)userMap);
- //groupBean.setUserList(userList);
- Gson gsonGroup = new Gson();
- String sGroupBean = gsonGroup.toJson(groupBean, new TypeToken<Teacher>() {
- }.getType());
- System.out.println(sGroupBean);
- /*{"stus":[{"studentName":"张三","studentId":1001},{"studentName":"李四","studentId":1002}],"student":{"studentName":"张三","studentId":1001},"map":{"user3":{"studentName":"李四","studentId":1002},"user1":{"studentName":"张三","studentId":1001}},"id":0,"age":0}*/
- //9、复杂对象string转对象
- Teacher groupBean2 = (Teacher) gson.fromJson(sGroupBean,
- new TypeToken<Teacher>() {
- }.getType());
- System.out.println(groupBean2);
- package com.andtools;
- import com.google.gson.annotations.Expose;
- public class Student {
- @Expose
- private String studentName;
- @Expose
- private int studentId;
- public Student(){}
- public Student(int studentId,String studentName){
- this.setStudentId(studentId);
- this.setStudentName(studentName);
- }
- public String toString(){
- return this.getStudentId() + ":" + this.getStudentName();
- }
- public String getStudentName() {
- return studentName;
- }
- public void setStudentName(String studentName) {
- this.studentName = studentName;
- }
- public int getStudentId() {
- return studentId;
- }
- public void setStudentId(int studentId) {
- this.studentId = studentId;
- }
- }
- package com.andtools;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import com.google.gson.annotations.Expose;
- public class Teacher {
- @Expose
- private int id;
- @Expose
- private String name;
- @Expose
- private int age;
- @Expose
- private Student student;
- @Expose
- private List stus;
- @Expose
- private HashMap map;
- public String toString(){
- return this.getId()+":"+this.getName()+":"+this.getAge() +":"+ this.getStudent().toString() + ":" + this.getStus() + ":" + this.getMap();
- }
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public Student getStudent() {
- return student;
- }
- public void setStudent(Student student) {
- this.student = student;
- }
- public List getStus() {
- return stus;
- }
- public void setStus(List stus) {
- this.stus = stus;
- }
- public HashMap getMap() {
- return map;
- }
- public void setMap(HashMap map) {
- this.map = map;
- }
- }
附件为网上找的文档。
经过比较,gson和其他现有java json类库最大的不同时gson需要序列化得实体类不需要使用annotation来标识需要序列化得字段,同时gson又可以通过使用annotation来灵活配置需要序列化的字段。
下面是一个简单的例子:
public class Person {
private String name;
private int age;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
@Override
public String toString()
{
return name + ":" +age;
}
}
实体很简单,两个字段,当然实体中的字段也可以是List或者Set类型的。
Gson gson = new Gson();
List<Person> persons = new ArrayList<Person>();
for (int i = 0; i < 10; i++) {
Person p = new Person();
p.setName("name" + i);
p.setAge(i * 5);
persons.add(p);
}
String str = gson.toJson(persons);
上面的代码重点是Gson对象,它提供了toJason()方法将对象转换成Json字符串,上面代码的str对象值为:
[{"name":"name0","age":0},{"name":"name1","age":5},{"name":"name2","age":10},{"name":"name3","age":15},{"name":"name4","age":20},{"name":"name5","age":25},{"name":"name6","age":30},{"name":"name7","age":35},{"name":"name8","age":40},{"name":"name9","age":45}]
很标准的json数据,很简单吧,呵呵。
下面来看看gson的反序列化,Gson提供了fromJson()方法来实现从Json相关对象到java实体的方法。
在日常应用中,我们一般都会碰到两种情况,转成单一实体对象和转换成对象列表或者其他结构。
先来看第一种:
比如json字符串为:[{"name":"name0","age":0}]
代码:
Person person = gson.fromJson(str, Person.class);
提供两个参数,分别是json字符串以及需要转换对象的类型。
第二种,转换成列表类型:
代码:
List<Person> ps = gson.fromJson(str, new TypeToken<List<Person>>(){}.getType());
for(int i = 0; i < ps.size() ; i++)
{
Person p = ps.get(i);
System.out.println(p.toString());
}
可以看到上面的代码使用了TypeToken,它是gson提供的数据类型转换器,可以支持各种数据集合类型转换。
Gson的基本使用就是这么多,至于annotation方面可以参考gson的官方文档,希望能对初学java和gson的同学有所帮助。
在Java/Android开发中,我们经常需要从服务器请求信息,返回的数据格式一般都是XML(extensible markup language)或者JSON(JavaScript Object Notation)格式。在Android开发中,轻量级的数据交互首选JSON,但XML依然大量使用在数据量比较大或者特殊字符比较多等数据交换情形,而且XML在可读性方面还是优于JSON格式的。这里简要地记述一下对xml数据解析的三种使用方法,方便日后温习。
XML文档解析可以采用的方法:DOM(Document Object Module)、SAX(Simple API for XML)和PULL方式。DOM和SAX解析方式都已经集成在Java里面了,Sun公司提供了Java API for XML Parsing(JAXP)接口来使用DOM和SAX,我们可以使用任何与JAXP兼容的XML解析器。JAXP接口包含了三个包:
(1)org.w3c.dom W3C推荐的用于XML标准规划文档对象模型的接口。
(2)org.xml.sax 用于对XML进行语法分析的事件驱动的XML简单API(SAX)
(3)javax.xml.parsers解析器工厂工具,可以获得并配置特殊的特殊语法分析器。
而Pull解析方式则需要引入第三方工具包(目前我找到的最新版kxml2-2.3.0.jar,好像还没api文档可供下载http://kxml.objectweb.org)。
DOM方式把一切都当作一个节点,文档节点、元素节点、文本节点、注释节点etc。它把整个XML文档当作一个Document对象,解析时需要把整个xml文档加载到内存中,解析完成后根据XML文档的节点结构生成文件树。可在程序中随意存取文件树,没有次数限制。显然DOM方式并不适合解析大的XML文档,太耗内存。
sax方式具有解析器和事件处理器,解析器负责读取XML文档和向事件处理器发送事件(充当事件源),事件处理器负责对发送的事件响应和进行XML文档处理。SAX方式采用流处理方式,边解析边触发相应的事件。不需要把整个xml文档加载进内存,边解析边丢弃,解析速度快,占用内存少,很适合移动开发。SAX是层次型的解析,只能依次对xml文档的数据流处理一遍,不支持对数据的任意存取操作(自己用变量保存解析结果另说)。使用sax方式不需要事先知道xml文档的每一个节点名称,主要的工作是写事件处理类。
pull方式跟sax方式很像,也是事件驱动型的。pull方式的结构非常简单,最重要的两个方法就是next()和nextToken(),最常用的几个属性【parser是XmlPullParser解析器对象】:
parser.START DOCUMENT
parser.START_TAG
parser.TEXT
parser.END_TAG
parser.END_DOCUMENT
下面贴一下主要的示例代码片段:
首先在tomcat服务器端放一个xml文档person.xml,内容如下:
1 2 3 4 5 6 7 8 9101112131415
<?xml version="1.0" encoding="utf-8"?><persons> <person id="23"> <name>叫兽</name> <age>21</age> </person> <person id="20"> <name>李四</name> <age>25</age> </person> <person id="10"> <name>淫贼</name> <age>20</age> </person></persons>
在客户端程序里面需要写一个类来操作得到的xml节点信息,这里统一都用Person.java类:
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627
public class Person { private int id; private String name; private int age; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person [age=" + age + ", id=" + id + ", name=" + name + "]"; }}
统一使用HttpUtils.java类从tomcat服务器上面得到xml文档的数据流
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829
public class HttpUtils { /** * 根据路径获取服务器端的xml文件数据流 * @param path xml所在的服务器文件路径 * @return InputStream xml文件的数据流 */ public static InputStream getXML(String path) { InputStream inputStream = null; try { URL url = new URL(path); if (url != null) { HttpURLConnection connection = (HttpURLConnection) url .openConnection(); connection.setConnectTimeout(3000); connection.setDoInput(true); connection.setRequestMethod("GET"); int code = connection.getResponseCode(); if (code == 200) {//连接成功 inputStream = connection.getInputStream(); return inputStream; } } } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return null; }}
DOM方式解析xml文档的主要操作:
1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829
public List<Person> getPersons(InputStream inputStream) throws Exception{ List<Person> list=new ArrayList<Person>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();// 创建一个document解析的工厂 DocumentBuilder builder = factory.newDocumentBuilder();//dom解析器,此时整个xml文件已经保存在内存中 Document document = builder.parse(inputStream);//解析xml文件流获得文档对象 Element element = document.getDocumentElement();// 获得文档元素节点// element.getFirstChild()//逐个节点往下读 NodeList personNodeList = element.getElementsByTagName("person"); int len=personNodeList.getLength(); for (int i = 0; i < len; i++) { Element personElement = (Element) personNodeList.item(i); Person person = new Person(); person.setId(Integer.parseInt(personElement.getAttribute("id"))); NodeList childNodes = personElement.getChildNodes(); for (int j = 0; j < childNodes.getLength(); j++) { if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {//判断节点类型为元素节点 if ("name".equals(childNodes.item(j).getNodeName())) {//name子节点 person.setName(childNodes.item(j).getFirstChild() .getNodeValue()); } else if ("age".equals(childNodes.item(j).getNodeName())) {//age子节点 person.setAge(Integer.parseInt(childNodes.item(j) .getFirstChild().getNodeValue())); } } } list.add(person); } return list; }
DOM方式的测试类Test.java
1 2 3 4 5 6 7 8 9101112131415161718192021
public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub String path="http://localhost:8080/myhttp/person.xml"; InputStream inputStream=HttpUtils.getXML(path); DomParseService service=new DomParseService(); try { List<Person> list=service.getPersons(inputStream); for(Person person:list){ System.out.println(person.toString()); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }}
SAX方式主要操作集中在事件处理器上(代码有点多,省略),简要说说这个事件处理类MyHandler.java的实现。这个类需要继承DefaultHandler类,同时在类的构造函数中传入当前解析的节点名称。主要是重写以下几个方法来处理事件:
1.public void startDocument() throws SAXException {//接收文档开始时触发}
2.public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {//接收第一个元素时触发事件
3.public void characters(char[] ch, int start, int length)throws SAXException {//接收元素中字符数据时出发,这里面处理xml文档信息}
4.public void endElement(String uri, String localName, String qName)throws SAXException {//遇到文档结束标记时触发}
SAX方式解析的主要业务逻辑:
1 2 3 4 5 6 7 8 9101112131415
public static List<HashMap<String, String>> readXML( InputStream inputStream, String nodeName) { try { SAXParserFactory spFactory=SAXParserFactory.newInstance();//实例化SAX解析器工厂对象 SAXParser parser=spFactory.newSAXParser();//创建解析器 MyHandler handler=new MyHandler(nodeName);//实例化事件处理器 parser.parse(inputStream, handler);//绑定xml流和事件处理器 inputStream.close(); return handler.getList(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } return null; }
PUll方式解析的主要类PullXMLTools.java(测试代码参考DOM方式):
1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445
public class PullXMLTools { /** * @param inputStream 服务器取得的流 * @param encode 编码格式 * @return * @throws Exception */ public static List<Person> parseXML(InputStream inputStream,String encode) throws Exception{ List<Person> list=null; Person person=null; //创建一个解析器工厂 XmlPullParserFactory factory=XmlPullParserFactory.newInstance(); //获得xml解析类的引用 XmlPullParser parser =factory.newPullParser(); parser.setInput(inputStream, encode); //获得事件的类型 int eventType=parser.getEventType(); while(eventType!=XmlPullParser.END_DOCUMENT){ switch (eventType) { case XmlPullParser.START_DOCUMENT: list=new ArrayList<Person>();//新建一个list存储对象 break; case XmlPullParser.START_TAG: if("person".equals(parser.getName())){ person=new Person(); person.setId(Integer.parseInt(parser.getAttributeValue(0)));//取出属性值 }else if("name".equals(parser.getName())){ person.setName(parser.nextText()); }else if("age".equals(parser.getName())){ person.setAge(Integer.parseInt(parser.nextText()));// } break; case XmlPullParser.END_TAG: if("person".equals(parser.getName())){ list.add(person); person=null; } break; } eventType=parser.next(); } return list; }}
============================================================================================
跟xml解析一样,json也有很多可供选择的解析包,其中比较常用的有jackson、gson、org.json等(PS:据说阿里的fastjson也不错,可惜那个文档真心蛋疼)。Android一开始就自带了org.json的解析包,在Android 3.0开始又集成了google自己的gson解析包,即新增的android.util.JsonReader和android.util.JsonWriter类。由于目前Android 2.3等低版本仍然占有比较大的比重,从兼容性的角度考虑,目前开发中一般还是选择org.json或者导入gson等解析包
json的基本格式
从json的全称JavaScript Object Notation就可以猜测它跟JavaScript的“亲戚”关系,其实这个轻量级的数据交换格式是基于JavaScript的一个子集,说白了就是js的对象和数组。json采用了独立于语言的文本格式,有两种基本数据结构:对象和数组(两者各种嵌套形成较复杂的json数据)。
Json Array放在中括号[]里面,如[a,c,d...],就跟我们熟悉的数组没本质区别。数组中的元素可以是string, number, false, true, null, Object对象甚至是array数组。下面是官网给的图解:
Json Object放在大括号{}里面,表示成键值对{key1:value1, key2:value2, key3:value3,....}。其中(在面向对象的语言里)key为对象的属性,value为对应的属性值。key只能是string类型的, 而value可以是string, number, false, true, null, Object对象甚至是array数组, 也就是说可以存在嵌套的情况。下面是官网给的图解:
解析json数据首先需要知道解析的是json数组还是json对象!下面将简单介绍一下gson和org.json包的基本使用。解析json内容前建议先根据json的内容建立相应的存储或者表示结构,本文例子里面都将使用到一个Person实体类:
1 2 3 4 5 6 7 8 91011121314151617
public class Person { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" name ", age=" age "]"; } //注:这里省略相应的setter和getter方法}
在本文中还用到 一些YY出来的json数据内容:
12345678
private String jsonArray = "[{"name":"Jack","age":20}, {"name":"mike","age":23}," " {"name":"mary","age":22}]";//待解析的json数组,数组元素是嵌套的json对象 private String jsonObject="{"name":"Object","age":30}";//待解析的json对象 private List<Person> persons=new ArrayList<Person>();//假定ArrayList里面的数据需要转换成json格式以供传输//同时在onCreate()里面把persons初始化为: persons.add(new Person("你妹",11 )); persons.add(new Person("你弟",23 )); persons.add(new Person("二货",33 ));
使用gson解析包
要想使用gson解析包必须首先下载并导入解析包,目前我在官网上看到的最新版本是gson-2.2.4.jar。gson里面通常可以采用两种方式来解析一个json格式数据:第一种方式就是采用JsonReader 逐字符解析json,利用beginArray()和endArray()方法来标志整个数组的开始和结束,解析json对象时采用类似的beginObject()和endObject()方法来标记开头和结尾。下面的第一种解析json数组的方法基本是**跟Android 3.0以后自带的android.util.JsonReader里面的解析方式类似**:
1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243
/** * 解析json数组的第一种方式 * @param jsonArray * @return */ public List<Person> parseJson(String jsonArray) { // TODO Auto-generated method stub try { //首先需要一个JsonReader对象,传入一个Reader参数 JsonReader reader=new JsonReader(new StringReader(jsonArray)); reader.beginArray();//根据jsonArray可知道第一步要解析数组 即遇到了数组的"[" while(reader.hasNext()){ arrList.add(readObject(reader));//读取数组元素 } reader.endArray();//解析数组结束 遇到了数组的"]" } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return arrList; } /** * 解析数组里面的json对象组成的元素 * @param reader * @return * @throws Exception */ private Person readObject(JsonReader reader) throws Exception { // TODO Auto-generated method stub String name=null; int age=0; reader.beginObject();//开始解析对象,遇到了数组元素的'{' while(reader.hasNext()){//开始解析对象里面的键值对 String key=reader.nextName();//得到key if(key.equals("name")){ name=reader.nextString();//取得value值 }else if(key.equals("age")){ age=reader.nextInt(); } } reader.endObject();//结束对象的解析 遇到了'}' return new Person(name, age); }
此外,在gson里面还有另外一种集成好的更方便的解析方式,下面这段代码可以达到跟方法一样的解析结果,代码显得更简洁
1 2 3 4 5 6 7 8 91011
/** * 解析json数组的第二种方式 * @param jsonArray * @return */ public List<Person> parseJson2(String jsonArray){ TypeToken<List<Person>> list = new TypeToken<List<Person>>() {}; Gson gson=new Gson(); arrList=gson.fromJson(jsonArray, list.getType()); return arrList; }
如果待解析的json数据是一个简单的json对象,那么可以采用类似方法1中的readObject()的步骤去解析,也可以采用类似方法2中的方式:
1 2 3 4 5 6 7 8 910
/** * 解析一个简单的json对象,效果跟法1中的readObject()方法类似 * @param jsonObject * @return */ public List<Person> parseJsonObject(String jsonObject){ Gson gson=new Gson(); arrList.add(gson.fromJson(jsonObject, Person.class)); return arrList; }
两种方式解析String jsonArray的结果(输出格式按Person类重写的toString()方法):
String jsonObject的解析结果(输出格式按Person类重写的toString()方法):
上面这些两种方法都是关于解析json数据的,比如说服务器给客户端传来的json格式数据就可以采用相似的方式去解析。下面简单介绍一下如何把上面YY出来的List persons里面的内容转变成json数组,以便客户端上传给服务器:
1234
public String toJsonString(List<Person> persons) { Gson gson=new Gson(); return gson.toJson(persons); }
运行结果为:
==========================================================================================================================
使用org.json来解析
Android 里面的org.json包里面有四个类JSONArray、JSONObject、JSONStringer、JSONTokener和一个异常JSONException。这几个类的主要作用为:
- JSONArray:表示的就是上文提到的json数组
- JSONObject:表示的就是上文提到的json对象
- JSONStringer:这个类主要用来生成符合json格式的文本,可以减少由于格式错误导致的程序异常。
- JSONTokener:负责把一个json格式文本转换成相应的对象,这个类既可以把json文本转换成对象(如JSONObject,JSONArray,String,Boolean,Integer,Long,Double or NULL),还可以读取其中的一个个字符(char)。正如官方文档上说的,大多数用户只是使用到这个类的构造方法和nextValue()方法。
JSONArray和JSONObject类
提供的方法主要有:各种构造方法、get××()、opt××(),put(××××)。其中put()方法用来添加或者替换数值,get××和opt××方法在功能上非常类似,都可以根据key或者索引取得json里面的数据项,但它们有个非常重要的区别:
- get××()方法没找到相应key的情况下,会抛出JSONException异常
- opt××()方法没找到相应key的情况下,会返回一个null值,并不会抛出JSONException异常
下面通过一个简单的例子来看看JSONObject类的使用(JSONArray类似,略):
1 2 3 4 5 6 7 8 9101112131415
//JSONObject JSONArray的使用示例 String json="{'name':'阿波','age':30}"; Map<String,Object> map=new HashMap<String, Object>(); map.put("name", "Map"); map.put("age", 11); try {// JSONObject object=new JSONObject(json);//利用String来构造 JSONObject object=new JSONObject(map);//利用map来构造,还有其他构造方法不再罗列了 //两个方法的主要区别上面已经简单介绍了 tv_json.setText("取得的名字:"+ object.getString("name") +"n取得的年龄:" +object.optInt("age")); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); }
解析的结果为:
JSONStringer类
主要的方法有:array()、endArray()、object()、endObject()、key()、value()和toString()。显然这几个方法都是成对使用的,具体点就是:
- object()表明开始一个JSON对象,即添加"{",endObject()表结束,即添加"}";
- array()表明开始一个JSON数组,即添加一个"[" ,endArray()表结束,即添加"]" ;
- key()表示添加一个key,value()表示添加一个value,构成key:value键值对。
简单的使用示例:
1 2 3 4 5 6 7 8 91011121314151617
try { //l利用JSONStringer生成一串json数据,缩进略怪,易懂就行 JSONStringer stringer=new JSONStringer().object() .key("name").value("阿海") .key("age").value("20") .key("address").value("北京海淀") .key("girlfriend") .array() .value("阿猫").value("阿狗").value("阿猪") .endArray() .key("phone").value("13411111111") .endObject(); tv_json.setText("把stringer转成字符串输出:"+stringer.toString());//输出显示 } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); }
得到的结果(如下图)为一个json对象里面嵌套一个简单的json数组,更复杂的json格式文本按这方式建立即可:
JSONTokener类
Android集成的org.json包里面的JSONTokener只有一个构造方法JSONTokener(String in) ,类里面提供了不少方法,但一般常使用的只有nextValue()方法,其他主要方法的详细解释见代码注释。
简单的使用示例:
1 2 3 4 5 6 7 8 910111213141516171819202122
//JSONTokener的使用示例 String json="{'name':'阿波','age':30,'兴趣':['读书','睡觉','吃饭']}"; try { JSONTokener tokener=new JSONTokener(json);//org.json包里面的JSONTokener只有唯一构造函数// JSONObject object=new JSONObject(tokener);//这个也是JSONObject的构造方法之一,将一次性把这个JSONObject读取完// tv_json.setText(object.toString()); String a,b,c,d; a=tokener.nextString('g');//当前位置到第一个 g 中间的内容(不包括当前字符 g ),即 {'name':'阿波','a b=String.valueOf(tokener.next());//从当前所在位置(age的'g'处)继续往下读一个字符(若遇到中文也是一个字符) ,即 e c=String.valueOf(tokener.next(10));//age后面数10个字符,即 ':30,'兴趣': //读取下一个JSONObject,JSONArray,String,Boolean,Integer,Long,Double or NULL JSONArray array=(JSONArray) tokener.nextValue();//读取下一个JSONArray,即 ['读书','睡觉','吃饭'] d=String.valueOf(tokener.nextClean());//读取下一个非空白或者评论内容的字符,这里即 } tv_json.setText("tokener.nextString('g')=" a +"ntokener.next()=" b +"ntokener.next(10)=" c +"ntokener.nextValue())=" array.toString() +"ntokener.nextClean()=" d); } catch (JSONException e) { // TODO Auto-generated catch block e.printStackTrace(); }
运行结果:
以上示例代码的tv_json.setText()是上文提到的TextView对象,但tv_json.setText()输出里面的字符串连接符(加号+),有些浏览器没显示出来,忽略它。
- Android用GSon处理Json数据
- Android用GSon处理Json数据
- Android用GSon处理Json数据
- Android用GSon处理Json数据
- Android用GSon处理Json数据
- Android用GSon处理Json数据
- Android只json数据的处理-Gson
- 使用Gson处理Json数据
- android 用gson解析遍历json数据
- Android 使用google-gson处理json格式数据
- Android Json处理之Gson
- Android解析json数据(Gson)
- Android Gson解析JSON数据
- android Gson解析json数据
- Gson对Json数据的处理
- 用Gson解析json数据
- Android中使用Gson解析JSON数据
- Android中使用Gson解析JSON数据
- 输入框js限制
- CString转char * ,string
- Single-Record Statistics
- HDU-bee-蜜蜂行走路线
- 黑马程序员_JAVA语言基础组成_判断结构
- Android用GSon处理Json数据
- 6174问题
- 大数据架构:Hadoop和Storm的介绍
- javaFX8初探(登录表单)
- C++对象模型
- GetWindowRect和GetClientRect的区别详解
- 用editText自定义日记本形式
- 深入探究宽字节注入漏洞与修补原理
- Java枚举的应用