开始之前,先在自己的电脑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中的代码,如下所示:
- packagecom.jack.networktest;
- importjava.io.BufferedReader;
- importjava.io.IOException;
- importjava.io.InputStream;
- importjava.io.InputStreamReader;
- importjava.io.StringReader;
- importjava.net.HttpURLConnection;
- importjava.net.MalformedURLException;
- importjava.net.URL;
- importjavax.xml.parsers.SAXParserFactory;
- importorg.apache.http.HttpEntity;
- importorg.apache.http.HttpHost;
- importorg.apache.http.HttpRequest;
- importorg.apache.http.HttpResponse;
- importorg.apache.http.client.ClientProtocolException;
- importorg.apache.http.client.HttpClient;
- importorg.apache.http.client.ResponseHandler;
- importorg.apache.http.client.methods.HttpGet;
- importorg.apache.http.client.methods.HttpUriRequest;
- importorg.apache.http.conn.ClientConnectionManager;
- importorg.apache.http.impl.client.DefaultHttpClient;
- importorg.apache.http.params.HttpParams;
- importorg.apache.http.protocol.HttpContext;
- importorg.apache.http.util.EntityUtils;
- importorg.json.JSONArray;
- importorg.json.JSONObject;
- importorg.xml.sax.InputSource;
- importorg.xml.sax.XMLReader;
- importorg.xmlpull.v1.XmlPullParser;
- importorg.xmlpull.v1.XmlPullParserFactory;
- importandroid.annotation.SuppressLint;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- importandroid.view.Menu;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- importandroid.widget.TextView;
- publicclassMainActivityextendsActivityimplementsOnClickListener{
- publicstaticfinalintSHOW_RESPONSE=0;
- privateButtonsendRequest=null;
- privateTextViewresponseText=null;
- privateHandlerhandler=newHandler(){
- @Override
- publicvoidhandleMessage(Messagemsg){
- //TODOAuto-generatedmethodstub
- super.handleMessage(msg);
- switch(msg.what){
- caseSHOW_RESPONSE:
- Stringresponse=(String)msg.obj;
- //在这里进行UI操作,将结果显示到界面上
- responseText.setText(response);
- break;
- default:
- break;
- }
- }
- };
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- 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
- publicbooleanonCreateOptionsMenu(Menumenu){
- //Inflatethemenu;thisaddsitemstotheactionbarifitispresent.
- getMenuInflater().inflate(R.menu.main,menu);
- returntrue;
- }
- @Override
- publicvoidonClick(Viewv){
- //TODOAuto-generatedmethodstub
- if(v.getId()==R.id.send_request){
- //sendRequestWithHttpURLConnection();
- sendRequestWithHttpClient();
- }
- }
- privatevoidsendRequestWithHttpURLConnection(){
- //开启线程来发起网络请求
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- //TODOAuto-generatedmethodstub
- HttpURLConnectionconnection=null;
- try{
- URLurl=newURL("http://www.baidu.com");
- connection=(HttpURLConnection)url.openConnection();
- connection.setRequestMethod("GET");
- connection.setConnectTimeout(8000);
- connection.setReadTimeout(8000);
- InputStreamin=connection.getInputStream();
- //下面对获取到的输入流进行读取
- BufferedReaderreader=newBufferedReader(newInputStreamReader(in));
- StringBuilderresponse=newStringBuilder();
- Stringline;
- while((line=reader.readLine())!=null){
- response.append(line);
- }
- Messagemessage=newMessage();
- message.what=SHOW_RESPONSE;
- //将服务器返回的结果存放到Message中
- message.obj=response.toString();
- handler.sendMessage(message);
- }catch(MalformedURLExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }catch(Exceptione){
- e.printStackTrace();
- }finally{
- if(connection!=null){
- connection.disconnect();
- }
- }
- }
- }).start();
- }
- privatevoidsendRequestWithHttpClient(){
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- //TODOAuto-generatedmethodstub
- try{
- HttpClienthttpClient=newDefaultHttpClient();
- //HttpGethttpGet=newHttpGet("http://www.baidu.com");
- //指定访问的服务器地址是电脑本机,10.0.2.2对模拟器来说就是电脑本机的ip地址
- //8080为端口号
- //HttpGethttpGet=newHttpGet("http://10.0.2.2:8080/get_data.xml");
- HttpGethttpGet=newHttpGet("http://10.0.2.2:8080/get_data.json");
- HttpResponsehttpResponse=httpClient.execute(httpGet);
- if(httpResponse.getStatusLine().getStatusCode()==200){
- //请求和响应都成功了
- HttpEntityentity=httpResponse.getEntity();
- Stringresponse=EntityUtils.toString(entity,"utf-8");
- //调用parseXMLWithPull方法解析服务器返回的数据
- //parseXMLWithPull(response);
- //调用parseXMLWithSAX方法解析服务器返回的数据
- parseXMLWithSAX(response);
- //调用parseJSONWithJSONObject方法解析服务器返回的数据
- parseJSONWithJSONObject(response);
- Messagemessage=newMessage();
- message.what=SHOW_RESPONSE;
- //将服务器返回的结果存放到Message中
- message.obj=response.toString();
- handler.sendMessage(message);
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- }).start();
- }
- //使用Pull解析xml
- privatevoidparseXMLWithPull(StringxmlData){
- //Log.d("MainActivity","parseXMLWithPull(StringxmlData)");
- try{
- //获取到XmlPullParserFactory的实例,并借助这个实例得到XmlPullParser对象
- XmlPullParserFactoryfactory=XmlPullParserFactory.newInstance();
- XmlPullParserxmlPullParser=factory.newPullParser();
- //调用XmlPullParser的setInput方法将服务器返回的xml数据设置进去开始解析
- xmlPullParser.setInput(newStringReader(xmlData));
- //通过getEventType()方法得到当前解析事件
- inteventType=xmlPullParser.getEventType();
- Stringid="";
- Stringname="";
- Stringversion="";
- while(eventType!=XmlPullParser.END_DOCUMENT){
- //通过getName()方法得到当前节点的名字,如果发现节点名等于id、name、或version
- //就调用nextText()方法来获取结点具体的内容,每当解析完一个app结点就将获取到的内容打印出来
- StringnodeName=xmlPullParser.getName();
- //Log.d("MainActivity",""+eventType+"nodeName="+nodeName);
- switch(eventType){
- //开始解析某个节点
- caseXmlPullParser.START_TAG:{
- if("id".equals(nodeName)){
- id=xmlPullParser.nextText();
- }elseif("name".equals(nodeName)){
- name=xmlPullParser.nextText();
- }elseif("version".equals(nodeName)){
- version=xmlPullParser.nextText();
- }
- break;
- }
- caseXmlPullParser.END_TAG:{
- if("app".equals(nodeName)){
- Log.d("MainActivity","idis"+id);
- Log.d("MainActivity","nameis"+name);
- Log.d("MainActivity","versionis"+version);
- }
- break;
- }
- default:
- break;
- }
- //调用next()方法获取到下一个解析事件
- eventType=xmlPullParser.next();
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- //进行SAX解析的函数
- privatevoidparseXMLWithSAX(StringxmlData){
- /*
- *parseXMLWithSAX方法中先创建一个SAXParserFactory的对象,然后再获取到
- *XMLReader对象,接着将我们编写的ContentHandler的实例设置到XMLReader中,
- *最后调用parse()方法开始执行解析。
- **/
- try{
- SAXParserFactoryfactory=SAXParserFactory.newInstance();
- XMLReaderxmlReader=factory.newSAXParser().getXMLReader();
- ContentHandlerhandler=newContentHandler();
- //将ContentHandler的实例设置到XMLReader中
- xmlReader.setContentHandler(handler);
- //开始执行解析
- xmlReader.parse(newInputSource(newStringReader(xmlData)));
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- //使用JSONObject解析json格式的数据
- privatevoidparseJSONWithJSONObject(StringjsonData){
- /*
- *首先把http请求的地址改成http://localhost:8080/get_data.json,然后在得到服务器返回
- *的数据后调用parseJSONWithJSONObject()方法来解析数据。由于我们在服务器中定义的是一个json数组,
- *因此解析的时候首先是将服务器返回的数据传入到一个JSONArray对象中。然后循环遍历这个JSONArray,从
- *中取出的每一个元素都是一个JSONObject对象,每个JSONObject对象中又包含了id,name和version这些
- *数据。接下来只需要调用getString()方法将这些数据取出,并打印出来即可。
- **/
- try{
- JSONArrayjsonArray=newJSONArray(jsonData);
- for(inti=0;i<jsonArray.length();i++){
- JSONObjectjsonObject=jsonArray.getJSONObject(i);
- Stringid=jsonObject.getString("id");
- Stringname=jsonObject.getString("name");
- Stringversion=jsonObject.getString("version");
- Log.d("MainActivity","idis"+id);
- Log.d("MainActivity","nameis"+name);
- Log.d("MainActivity","versionis"+version);
- }
- }catch(Exceptione){
- 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这三个字段,如下所示:
- packagecom.jack.networktest;
- publicclassApp{
- privateStringid;
- privateStringname;
- privateStringversion;
- publicStringgetId(){
- returnid;
- }
- publicvoidsetId(Stringid){
- this.id=id;
- }
- publicStringgetName(){
- returnname;
- }
- publicvoidsetName(Stringname){
- this.name=name;
- }
- publicStringgetVersion(){
- returnversion;
- }
- publicvoidsetVersion(Stringversion){
- this.version=version;
- }
- }
然后修改MainActivity中的代码,如下所示:
- packagecom.jack.networktest;
- importjava.io.BufferedReader;
- importjava.io.IOException;
- importjava.io.InputStream;
- importjava.io.InputStreamReader;
- importjava.io.StringReader;
- importjava.net.HttpURLConnection;
- importjava.net.MalformedURLException;
- importjava.net.URL;
- importjava.util.List;
- importjavax.xml.parsers.SAXParserFactory;
- importorg.apache.http.HttpEntity;
- importorg.apache.http.HttpHost;
- importorg.apache.http.HttpRequest;
- importorg.apache.http.HttpResponse;
- importorg.apache.http.client.ClientProtocolException;
- importorg.apache.http.client.HttpClient;
- importorg.apache.http.client.ResponseHandler;
- importorg.apache.http.client.methods.HttpGet;
- importorg.apache.http.client.methods.HttpUriRequest;
- importorg.apache.http.conn.ClientConnectionManager;
- importorg.apache.http.impl.client.DefaultHttpClient;
- importorg.apache.http.params.HttpParams;
- importorg.apache.http.protocol.HttpContext;
- importorg.apache.http.util.EntityUtils;
- importorg.json.JSONArray;
- importorg.json.JSONObject;
- importorg.xml.sax.InputSource;
- importorg.xml.sax.XMLReader;
- importorg.xmlpull.v1.XmlPullParser;
- importorg.xmlpull.v1.XmlPullParserFactory;
- importcom.google.gson.Gson;
- importcom.google.gson.reflect.TypeToken;
- importandroid.annotation.SuppressLint;
- importandroid.app.Activity;
- importandroid.os.Bundle;
- importandroid.os.Handler;
- importandroid.os.Message;
- importandroid.util.Log;
- importandroid.view.Menu;
- importandroid.view.View;
- importandroid.view.View.OnClickListener;
- importandroid.widget.Button;
- importandroid.widget.TextView;
- publicclassMainActivityextendsActivityimplementsOnClickListener{
- publicstaticfinalintSHOW_RESPONSE=0;
- privateButtonsendRequest=null;
- privateTextViewresponseText=null;
- privateHandlerhandler=newHandler(){
- @Override
- publicvoidhandleMessage(Messagemsg){
- //TODOAuto-generatedmethodstub
- super.handleMessage(msg);
- switch(msg.what){
- caseSHOW_RESPONSE:
- Stringresponse=(String)msg.obj;
- //在这里进行UI操作,将结果显示到界面上
- responseText.setText(response);
- break;
- default:
- break;
- }
- }
- };
- @Override
- protectedvoidonCreate(BundlesavedInstanceState){
- 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
- publicbooleanonCreateOptionsMenu(Menumenu){
- //Inflatethemenu;thisaddsitemstotheactionbarifitispresent.
- getMenuInflater().inflate(R.menu.main,menu);
- returntrue;
- }
- @Override
- publicvoidonClick(Viewv){
- //TODOAuto-generatedmethodstub
- if(v.getId()==R.id.send_request){
- //sendRequestWithHttpURLConnection();
- sendRequestWithHttpClient();
- }
- }
- privatevoidsendRequestWithHttpURLConnection(){
- //开启线程来发起网络请求
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- //TODOAuto-generatedmethodstub
- HttpURLConnectionconnection=null;
- try{
- URLurl=newURL("http://www.baidu.com");
- connection=(HttpURLConnection)url.openConnection();
- connection.setRequestMethod("GET");
- connection.setConnectTimeout(8000);
- connection.setReadTimeout(8000);
- InputStreamin=connection.getInputStream();
- //下面对获取到的输入流进行读取
- BufferedReaderreader=newBufferedReader(newInputStreamReader(in));
- StringBuilderresponse=newStringBuilder();
- Stringline;
- while((line=reader.readLine())!=null){
- response.append(line);
- }
- Messagemessage=newMessage();
- message.what=SHOW_RESPONSE;
- //将服务器返回的结果存放到Message中
- message.obj=response.toString();
- handler.sendMessage(message);
- }catch(MalformedURLExceptione){
- //TODOAuto-generatedcatchblock
- e.printStackTrace();
- }catch(Exceptione){
- e.printStackTrace();
- }finally{
- if(connection!=null){
- connection.disconnect();
- }
- }
- }
- }).start();
- }
- privatevoidsendRequestWithHttpClient(){
- newThread(newRunnable(){
- @Override
- publicvoidrun(){
- //TODOAuto-generatedmethodstub
- try{
- HttpClienthttpClient=newDefaultHttpClient();
- //HttpGethttpGet=newHttpGet("http://www.baidu.com");
- //指定访问的服务器地址是电脑本机,10.0.2.2对模拟器来说就是电脑本机的ip地址
- //8080为端口号
- //HttpGethttpGet=newHttpGet("http://10.0.2.2:8080/get_data.xml");
- HttpGethttpGet=newHttpGet("http://10.0.2.2:8080/get_data.json");
- HttpResponsehttpResponse=httpClient.execute(httpGet);
- if(httpResponse.getStatusLine().getStatusCode()==200){
- //请求和响应都成功了
- HttpEntityentity=httpResponse.getEntity();
- Stringresponse=EntityUtils.toString(entity,"utf-8");
- //调用parseXMLWithPull方法解析服务器返回的数据
- //parseXMLWithPull(response);
- //调用parseXMLWithSAX方法解析服务器返回的数据
- //parseXMLWithSAX(response);
- //调用parseJSONWithJSONObject方法解析服务器返回的数据
- //parseJSONWithJSONObject(response);
- //调用parseJSONWithGSON方法解析服务器返回的数据
- parseJSONWithGSON(response);
- Messagemessage=newMessage();
- message.what=SHOW_RESPONSE;
- //将服务器返回的结果存放到Message中
- message.obj=response.toString();
- handler.sendMessage(message);
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- }).start();
- }
- //使用Pull解析xml
- privatevoidparseXMLWithPull(StringxmlData){
- //Log.d("MainActivity","parseXMLWithPull(StringxmlData)");
- try{
- //获取到XmlPullParserFactory的实例,并借助这个实例得到XmlPullParser对象
- XmlPullParserFactoryfactory=XmlPullParserFactory.newInstance();
- XmlPullParserxmlPullParser=factory.newPullParser();
- //调用XmlPullParser的setInput方法将服务器返回的xml数据设置进去开始解析
- xmlPullParser.setInput(newStringReader(xmlData));
- //通过getEventType()方法得到当前解析事件
- inteventType=xmlPullParser.getEventType();
- Stringid="";
- Stringname="";
- Stringversion="";
- while(eventType!=XmlPullParser.END_DOCUMENT){
- //通过getName()方法得到当前节点的名字,如果发现节点名等于id、name、或version
- //就调用nextText()方法来获取结点具体的内容,每当解析完一个app结点就将获取到的内容打印出来
- StringnodeName=xmlPullParser.getName();
- //Log.d("MainActivity",""+eventType+"nodeName="+nodeName);
- switch(eventType){
- //开始解析某个节点
- caseXmlPullParser.START_TAG:{
- if("id".equals(nodeName)){
- id=xmlPullParser.nextText();
- }elseif("name".equals(nodeName)){
- name=xmlPullParser.nextText();
- }elseif("version".equals(nodeName)){
- version=xmlPullParser.nextText();
- }
- break;
- }
- caseXmlPullParser.END_TAG:{
- if("app".equals(nodeName)){
- Log.d("MainActivity","idis"+id);
- Log.d("MainActivity","nameis"+name);
- Log.d("MainActivity","versionis"+version);
- }
- break;
- }
- default:
- break;
- }
- //调用next()方法获取到下一个解析事件
- eventType=xmlPullParser.next();
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- //进行SAX解析的函数
- privatevoidparseXMLWithSAX(StringxmlData){
- /*
- *parseXMLWithSAX方法中先创建一个SAXParserFactory的对象,然后再获取到
- *XMLReader对象,接着将我们编写的ContentHandler的实例设置到XMLReader中,
- *最后调用parse()方法开始执行解析。
- **/
- try{
- SAXParserFactoryfactory=SAXParserFactory.newInstance();
- XMLReaderxmlReader=factory.newSAXParser().getXMLReader();
- ContentHandlerhandler=newContentHandler();
- //将ContentHandler的实例设置到XMLReader中
- xmlReader.setContentHandler(handler);
- //开始执行解析
- xmlReader.parse(newInputSource(newStringReader(xmlData)));
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- //使用JSONObject解析json格式的数据
- privatevoidparseJSONWithJSONObject(StringjsonData){
- /*
- *首先把http请求的地址改成http://localhost:8080/get_data.json,然后在得到服务器返回
- *的数据后调用parseJSONWithJSONObject()方法来解析数据。由于我们在服务器中定义的是一个json数组,
- *因此解析的时候首先是将服务器返回的数据传入到一个JSONArray对象中。然后循环遍历这个JSONArray,从
- *中取出的每一个元素都是一个JSONObject对象,每个JSONObject对象中又包含了id,name和version这些
- *数据。接下来只需要调用getString()方法将这些数据取出,并打印出来即可。
- **/
- try{
- JSONArrayjsonArray=newJSONArray(jsonData);
- for(inti=0;i<jsonArray.length();i++){
- JSONObjectjsonObject=jsonArray.getJSONObject(i);
- Stringid=jsonObject.getString("id");
- Stringname=jsonObject.getString("name");
- Stringversion=jsonObject.getString("version");
- Log.d("MainActivity","idis"+id);
- Log.d("MainActivity","nameis"+name);
- Log.d("MainActivity","versionis"+version);
- }
- }catch(Exceptione){
- e.printStackTrace();
- }
- }
- //使用JSONWithGSON(StringjsonData)方法解析json格式的数据
- privatevoidparseJSONWithGSON(StringjsonData){
- Gsongson=newGson();
- List<App>appList=gson.fromJson(jsonData,new
- TypeToken<List<App>>(){}.getType());
- for(Appapp:appList){
- Log.d("MainActivity","idis"+app.getId());
- Log.d("MainActivity","nameis"+app.getName());
- Log.d("MainActivity","versionis"+app.getVersion());
- }
- }
- }
运行程序,结果如下所示:
经过上面两种方法对json格式的数据进行解析,相信对json格式的数据应该不再陌生了。