android学习二十三(解析json格式数据)
前面我们已经掌握了xml格式数据的解析方式,那么接下来我们学习下如何解析json格式的数据。比起xml,json的主要优势在于它体积更小,在网络上传输的时候可以更省流量。但缺点在于,它的语义性差,看起来不如xml直观。
开始之前,先在自己的电脑apache-tomcat-6.0.39\webapps\ROOT路径目录下新建一个get_data.json的文件,然后编辑这个文件,并加入如下json格式的内容:
[{"id":"5","version":"5.5","name":"angelababy"},
{"id":"6","version":"7.0","name":"clash of clans"},
{"id":"7","version":"3.5","name":"hey day"}]
这时候在浏览器访问的结果如下:
这样就把json格式的数据准备好了,下面我们在android程序中解析这些数据吧。
使用JSONObject解析json格式的数据
解析json格式的数据有很多种方式,可以使用官方提供的JSONObject,也可以用谷歌的开源库GSON。
还有一些第三方的开源库,比如Jackson,FastSON等。目前只讲解JSONObject和GSON。
修改MainActivity中的代码,如下所示:
package com.jack.networktest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import javax.xml.parsers.SAXParserFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONObject; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener{ public static final int SHOW_RESPONSE=0; private Button sendRequest=null; private TextView responseText=null; private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch(msg.what){ case SHOW_RESPONSE: String response=(String) msg.obj; //在这里进行UI操作,将结果显示到界面上 responseText.setText(response); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendRequest=(Button) findViewById(R.id.send_request); responseText=(TextView) findViewById(R.id.response_text); sendRequest.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v.getId()==R.id.send_request){ //sendRequestWithHttpURLConnection(); sendRequestWithHttpClient(); } } private void sendRequestWithHttpURLConnection(){ //开启线程来发起网络请求 new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub HttpURLConnection connection=null; try { URL url=new URL("http://www.baidu.com"); connection =(HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in=connection.getInputStream(); //下面对获取到的输入流进行读取 BufferedReader reader=new BufferedReader(new InputStreamReader(in)); StringBuilder response=new StringBuilder(); String line; while((line=reader.readLine())!=null){ response.append(line); } Message message=new Message(); message.what=SHOW_RESPONSE; //将服务器返回的结果存放到Message中 message.obj=response.toString(); handler.sendMessage(message); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch(Exception e){ e.printStackTrace(); }finally{ if(connection!=null){ connection.disconnect(); } } } }).start(); } private void sendRequestWithHttpClient(){ new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub try{ HttpClient httpClient=new DefaultHttpClient() ; //HttpGet httpGet=new HttpGet("http://www.baidu.com"); //指定访问的服务器地址是电脑本机,10.0.2.2对模拟器来说就是电脑本机的ip地址 //8080为端口号 //HttpGet httpGet=new HttpGet("http://10.0.2.2:8080/get_data.xml"); HttpGet httpGet=new HttpGet("http://10.0.2.2:8080/get_data.json"); HttpResponse httpResponse=httpClient.execute(httpGet); if(httpResponse.getStatusLine().getStatusCode()==200){ //请求和响应都成功了 HttpEntity entity=httpResponse.getEntity(); String response=EntityUtils.toString(entity,"utf-8"); //调用parseXMLWithPull方法解析服务器返回的数据 //parseXMLWithPull(response); //调用parseXMLWithSAX方法解析服务器返回的数据 parseXMLWithSAX(response); //调用parseJSONWithJSONObject方法解析服务器返回的数据 parseJSONWithJSONObject(response); Message message=new Message(); message.what=SHOW_RESPONSE; //将服务器返回的结果存放到Message中 message.obj=response.toString(); handler.sendMessage(message); } }catch(Exception e){ e.printStackTrace(); } } }).start(); } //使用Pull解析xml private void parseXMLWithPull(String xmlData){ //Log.d("MainActivity", "parseXMLWithPull(String xmlData)"); try{ //获取到XmlPullParserFactory的实例,并借助这个实例得到XmlPullParser对象 XmlPullParserFactory factory=XmlPullParserFactory.newInstance(); XmlPullParser xmlPullParser=factory.newPullParser(); //调用XmlPullParser的setInput方法将服务器返回的xml数据设置进去开始解析 xmlPullParser.setInput(new StringReader(xmlData)); //通过getEventType()方法得到当前解析事件 int eventType=xmlPullParser.getEventType(); String id=""; String name=""; String version=""; while(eventType!=XmlPullParser.END_DOCUMENT){ //通过getName()方法得到当前节点的名字,如果发现节点名等于id、name、或version //就调用nextText()方法来获取结点具体的内容,每当解析完一个app结点就将获取到的内容打印出来 String nodeName=xmlPullParser.getName(); //Log.d("MainActivity",""+eventType+ " nodeName= "+nodeName); switch(eventType){ //开始解析某个节点 case XmlPullParser.START_TAG:{ if("id".equals(nodeName)){ id=xmlPullParser.nextText(); }else if("name".equals(nodeName)){ name=xmlPullParser.nextText(); }else if("version".equals(nodeName)){ version=xmlPullParser.nextText(); } break; } case XmlPullParser.END_TAG:{ if("app".equals(nodeName)){ Log.d("MainActivity", "id is "+id); Log.d("MainActivity", "name is "+name); Log.d("MainActivity", "version is "+version); } break; } default: break; } //调用next()方法获取到下一个解析事件 eventType=xmlPullParser.next(); } }catch(Exception e){ e.printStackTrace(); } } //进行SAX解析的函数 private void parseXMLWithSAX(String xmlData){ /* * parseXMLWithSAX方法中先创建一个SAXParserFactory的对象,然后再获取到 * XMLReader对象,接着将我们编写的ContentHandler的实例设置到XMLReader中, * 最后调用parse()方法开始执行解析。 * */ try{ SAXParserFactory factory=SAXParserFactory.newInstance(); XMLReader xmlReader=factory.newSAXParser().getXMLReader(); ContentHandler handler=new ContentHandler(); //将ContentHandler的实例设置到XMLReader中 xmlReader.setContentHandler(handler); //开始执行解析 xmlReader.parse(new InputSource(new StringReader(xmlData))); }catch(Exception e){ e.printStackTrace(); } } //使用JSONObject解析json格式的数据 private void parseJSONWithJSONObject(String jsonData){ /* * 首先把http请求的地址改成http://localhost:8080/get_data.json,然后在得到服务器返回 * 的数据后调用parseJSONWithJSONObject()方法来解析数据。由于我们在服务器中定义的是一个json数组, * 因此解析的时候首先是将服务器返回的数据传入到一个JSONArray对象中。然后循环遍历这个JSONArray,从 * 中取出的每一个元素都是一个JSONObject对象,每个JSONObject对象中又包含了id,name和version这些 * 数据。接下来只需要调用getString()方法将这些数据取出,并打印出来即可。 * */ try{ JSONArray jsonArray=new JSONArray(jsonData); for(int i=0;i<jsonArray.length();i++){ JSONObject jsonObject=jsonArray.getJSONObject(i); String id=jsonObject.getString("id"); String name=jsonObject.getString("name"); String version=jsonObject.getString("version"); Log.d("MainActivity", "id is "+id); Log.d("MainActivity", "name is "+name); Log.d("MainActivity", "version is "+version); } }catch(Exception e){ e.printStackTrace(); } } }
现在重新运行下程序,点击send request按钮,结果如下所示:
使用GSON
谷歌提供的GSON开源库可以让解析JSON数据的工作简单到不敢想象的地步。要使用GSON必须要在项目中添加一个 GSON的jar包。首先需要将GSON的资源压缩包下载下来,下载地址是:htt://code.google.com/p/google-gson/downloads/list
然后把下载下来的gson-x.x.x.jar包拷贝到NetworkTest项目的libs目录下,GSON库就自动添加到项目了。
GSON的强大之处,在于可以将一段json格式的字符串自动映射成一个对象,从而不需要我们再动手去编写代码进行解析了。比如说一段json格式的数据如下所示:
{"name":"tom","age":"20"}
那么我们就可以定义一个Person类,并加入name和age这两个字段,然后只需简单地调用如下代码就可以将json数据自动解析成一个Person对象了:
Gson gson=new Gson();
Person person=gson.fromJson(jsonData,Person.class);
如果需要解析的是一段json数组会稍微麻烦点,我们需要借助TypeToken将期望解析的数据类型传入到fromJson()方法,如下所示:
List<Person> people=gson.fromJson(jsonData,new TypeToken<List<Person>>(){}.getType());
好了,基本的用法就是这样了,下面我们来试试,首先新增一个App类,并加入id,name和version这三个字段,如下所示:
package com.jack.networktest; public class App { private String id; private String name; private String version; public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getVersion() { return version; } public void setVersion(String version) { this.version = version; } }
然后修改MainActivity中的代码,如下所示:
package com.jack.networktest; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.List; import javax.xml.parsers.SAXParserFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.ResponseHandler; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.HttpParams; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; import org.json.JSONArray; import org.json.JSONObject; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import android.annotation.SuppressLint; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener{ public static final int SHOW_RESPONSE=0; private Button sendRequest=null; private TextView responseText=null; private Handler handler=new Handler(){ @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); switch(msg.what){ case SHOW_RESPONSE: String response=(String) msg.obj; //在这里进行UI操作,将结果显示到界面上 responseText.setText(response); break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sendRequest=(Button) findViewById(R.id.send_request); responseText=(TextView) findViewById(R.id.response_text); sendRequest.setOnClickListener(this); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public void onClick(View v) { // TODO Auto-generated method stub if(v.getId()==R.id.send_request){ //sendRequestWithHttpURLConnection(); sendRequestWithHttpClient(); } } private void sendRequestWithHttpURLConnection(){ //开启线程来发起网络请求 new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub HttpURLConnection connection=null; try { URL url=new URL("http://www.baidu.com"); connection =(HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); InputStream in=connection.getInputStream(); //下面对获取到的输入流进行读取 BufferedReader reader=new BufferedReader(new InputStreamReader(in)); StringBuilder response=new StringBuilder(); String line; while((line=reader.readLine())!=null){ response.append(line); } Message message=new Message(); message.what=SHOW_RESPONSE; //将服务器返回的结果存放到Message中 message.obj=response.toString(); handler.sendMessage(message); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); }catch(Exception e){ e.printStackTrace(); }finally{ if(connection!=null){ connection.disconnect(); } } } }).start(); } private void sendRequestWithHttpClient(){ new Thread(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub try{ HttpClient httpClient=new DefaultHttpClient() ; //HttpGet httpGet=new HttpGet("http://www.baidu.com"); //指定访问的服务器地址是电脑本机,10.0.2.2对模拟器来说就是电脑本机的ip地址 //8080为端口号 //HttpGet httpGet=new HttpGet("http://10.0.2.2:8080/get_data.xml"); HttpGet httpGet=new HttpGet("http://10.0.2.2:8080/get_data.json"); HttpResponse httpResponse=httpClient.execute(httpGet); if(httpResponse.getStatusLine().getStatusCode()==200){ //请求和响应都成功了 HttpEntity entity=httpResponse.getEntity(); String response=EntityUtils.toString(entity,"utf-8"); //调用parseXMLWithPull方法解析服务器返回的数据 //parseXMLWithPull(response); //调用parseXMLWithSAX方法解析服务器返回的数据 //parseXMLWithSAX(response); //调用parseJSONWithJSONObject方法解析服务器返回的数据 //parseJSONWithJSONObject(response); //调用parseJSONWithGSON方法解析服务器返回的数据 parseJSONWithGSON(response); Message message=new Message(); message.what=SHOW_RESPONSE; //将服务器返回的结果存放到Message中 message.obj=response.toString(); handler.sendMessage(message); } }catch(Exception e){ e.printStackTrace(); } } }).start(); } //使用Pull解析xml private void parseXMLWithPull(String xmlData){ //Log.d("MainActivity", "parseXMLWithPull(String xmlData)"); try{ //获取到XmlPullParserFactory的实例,并借助这个实例得到XmlPullParser对象 XmlPullParserFactory factory=XmlPullParserFactory.newInstance(); XmlPullParser xmlPullParser=factory.newPullParser(); //调用XmlPullParser的setInput方法将服务器返回的xml数据设置进去开始解析 xmlPullParser.setInput(new StringReader(xmlData)); //通过getEventType()方法得到当前解析事件 int eventType=xmlPullParser.getEventType(); String id=""; String name=""; String version=""; while(eventType!=XmlPullParser.END_DOCUMENT){ //通过getName()方法得到当前节点的名字,如果发现节点名等于id、name、或version //就调用nextText()方法来获取结点具体的内容,每当解析完一个app结点就将获取到的内容打印出来 String nodeName=xmlPullParser.getName(); //Log.d("MainActivity",""+eventType+ " nodeName= "+nodeName); switch(eventType){ //开始解析某个节点 case XmlPullParser.START_TAG:{ if("id".equals(nodeName)){ id=xmlPullParser.nextText(); }else if("name".equals(nodeName)){ name=xmlPullParser.nextText(); }else if("version".equals(nodeName)){ version=xmlPullParser.nextText(); } break; } case XmlPullParser.END_TAG:{ if("app".equals(nodeName)){ Log.d("MainActivity", "id is "+id); Log.d("MainActivity", "name is "+name); Log.d("MainActivity", "version is "+version); } break; } default: break; } //调用next()方法获取到下一个解析事件 eventType=xmlPullParser.next(); } }catch(Exception e){ e.printStackTrace(); } } //进行SAX解析的函数 private void parseXMLWithSAX(String xmlData){ /* * parseXMLWithSAX方法中先创建一个SAXParserFactory的对象,然后再获取到 * XMLReader对象,接着将我们编写的ContentHandler的实例设置到XMLReader中, * 最后调用parse()方法开始执行解析。 * */ try{ SAXParserFactory factory=SAXParserFactory.newInstance(); XMLReader xmlReader=factory.newSAXParser().getXMLReader(); ContentHandler handler=new ContentHandler(); //将ContentHandler的实例设置到XMLReader中 xmlReader.setContentHandler(handler); //开始执行解析 xmlReader.parse(new InputSource(new StringReader(xmlData))); }catch(Exception e){ e.printStackTrace(); } } //使用JSONObject解析json格式的数据 private void parseJSONWithJSONObject(String jsonData){ /* * 首先把http请求的地址改成http://localhost:8080/get_data.json,然后在得到服务器返回 * 的数据后调用parseJSONWithJSONObject()方法来解析数据。由于我们在服务器中定义的是一个json数组, * 因此解析的时候首先是将服务器返回的数据传入到一个JSONArray对象中。然后循环遍历这个JSONArray,从 * 中取出的每一个元素都是一个JSONObject对象,每个JSONObject对象中又包含了id,name和version这些 * 数据。接下来只需要调用getString()方法将这些数据取出,并打印出来即可。 * */ try{ JSONArray jsonArray=new JSONArray(jsonData); for(int i=0;i<jsonArray.length();i++){ JSONObject jsonObject=jsonArray.getJSONObject(i); String id=jsonObject.getString("id"); String name=jsonObject.getString("name"); String version=jsonObject.getString("version"); Log.d("MainActivity", "id is "+id); Log.d("MainActivity", "name is "+name); Log.d("MainActivity", "version is "+version); } }catch(Exception e){ e.printStackTrace(); } } //使用JSONWithGSON(String jsonData)方法解析json格式的数据 private void parseJSONWithGSON(String jsonData){ Gson gson=new Gson(); List<App> appList=gson.fromJson(jsonData, new TypeToken<List<App>>() {}.getType()); for(App app: appList){ Log.d("MainActivity", "id is "+app.getId()); Log.d("MainActivity", "name is "+app.getName()); Log.d("MainActivity", "version is "+app.getVersion()); } } }
运行程序,结果如下所示:
经过上面两种方法对json格式的数据进行解析,相信对json格式的数据应该不再陌生了。
http://blog.csdn.net/j903829182/article/details/42503583
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。