1. 程式人生 > >Android訪問網路系列之--服務端返回XML或JSON格式資料,Android 進行解析並顯示

Android訪問網路系列之--服務端返回XML或JSON格式資料,Android 進行解析並顯示

例子說明:使用者通過訪問web資源的最新電影資訊,伺服器端生成XML或JSON格式資料,返回Android客戶端進行顯示。

此案例開發需要兩個方面 WEB開發和android開發.

一.web開發相對比較簡單,只是模擬一下

相關程式碼如下:

1.實體Bean

複製程式碼
package ygc.yxb.domain;

/**
 * 電影資訊實體Bean
 * @author YXB
 *
 */
public class News {
    private Integer id;              //id
    private String title;        //電影名稱
    private
Integer timelenght; //時長 public News() { } public News(Integer id, String title, Integer timelenght) { this.id = id; this.title = title; this.timelenght = timelenght; } public Integer getId() { return id; } public
void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public Integer getTimelenght() { return timelenght; } public void setTimelenght(Integer timelenght) {
this.timelenght = timelenght; } }
複製程式碼

2.業務邏輯

複製程式碼
package ygc.yxb.service.impl;

import java.util.ArrayList;
import java.util.List;

import ygc.yxb.domain.News;
import ygc.yxb.service.VideoNewsService;

public class VideoNewsServiceImpl implements VideoNewsService {
    
    
    /**
     * 獲取電影資訊的業務方法
     */
    public List<News> getLastNews(){
        
        
        List<News> newses = new ArrayList<News>();
        newses.add(new News(32, "大話西遊", 90));
        newses.add(new News(12, "軒轅劍", 40));
        newses.add(new News(56, "愛情公寓", 30));
        return newses;
        
    }

}
複製程式碼

3.Servlet

複製程式碼
package ygc.yxb.servlet;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import ygc.yxb.domain.News;
import ygc.yxb.service.VideoNewsService;
import ygc.yxb.service.impl.VideoNewsServiceImpl;

/**
 * 用最原始的web開發servlet請求伺服器,並返回客戶端資料
 */
public class ListServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    private VideoNewsService service = new VideoNewsServiceImpl();
   
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
        List<News> videos = service.getLastNews();
        String format=request.getParameter("format");
        //如果使用者請求的是這個路徑,則返回JSON格式的資料.http://192.168.1.113:8080/videonews/ListServlet?format=json
        
        if("json".equals(format)){
            //[{id:56,title:"xxxx",timelength:90}]
            //組拼一個JSON格式的物件
            StringBuilder builder = new StringBuilder();
            builder.append('[');
                for (News news : videos) {
                    builder.append('{');
                        builder.append("id:").append(news.getId()).append(',');
                        builder.append("title:\"").append(news.getTitle()).append("\",");
                        builder.append("timelength:").append(news.getTimelenght());
                    builder.append("},");
                }
                builder.deleteCharAt(builder.length()-1);
            builder.append(']');
            
            request.setAttribute("json", builder.toString());
            request.getRequestDispatcher("/WEB-INF/page/jsonvideonews.jsp").forward(request, response);
            
            
        //如果使用者請求的是這個路徑,則返回XML格式的資料.http://192.168.1.113:8080/videonews/ListServlet
        }else{
            request.setAttribute("videos", videos);
            request.getRequestDispatcher("/WEB-INF/page/videonews.jsp").forward(request, response);
        }
    }

}
複製程式碼

4.jsp頁面

4.1.jsonvideonews.jsp

<%@ page language="java" contentType="text/plain; charset=UTF-8" pageEncoding="UTF-8"%>${json}

4.2.videonews.jsp XML資料

複製程式碼
<%@ page language="java" contentType="text/xml; charset=UTF-8" pageEncoding="UTF-8"%><%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %><?xml version="1.0" encoding="UTF-8"?>
<videonews>
    <c:forEach items="${videos}" var="video">
        <news id ="${video.id }">
            <title>${video.title }</title>
            <timelength>${video.timelenght}</timelength>
        </news>
    </c:forEach>
</videonews>
複製程式碼

到此為止web開發完畢,現在Android開發相關程式碼

1.實體Bean

複製程式碼
package ygc.yxb.domain;

public class News {
    private Integer id;
    private String title;
    private Integer timelenght;
    
    
    public News() {
        
    }
    
    
    public News(Integer id, String title, Integer timelenght) {
        this.id = id;
        this.title = title;
        this.timelenght = timelenght;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public Integer getTimelenght() {
        return timelenght;
    }
    public void setTimelenght(Integer timelenght) {
        this.timelenght = timelenght;
    }
    
    

}
複製程式碼

2.業務邏輯

複製程式碼
package ygc.yxb.service;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONObject;
import org.xmlpull.v1.XmlPullParser;

import android.util.Xml;

import ygc.yxb.domain.News;
import ygc.yxb.utils.StreamTool;

public class VideoNewsService {
    
    /**
     * 獲取最新的視訊資訊接受伺服器端XML格式的資料
     * @return
     * @throws Exception
     */
    public static List<News> getLastNews() throws Exception{
        String path="http://192.168.1.113:8080/videonews/ListServlet";
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        if(conn.getResponseCode()==200){
            InputStream inStream=conn.getInputStream();
            return parseXML(inStream);
        }
        return null;
    }
    
    /**
     * 獲取最新的視訊資訊 接受伺服器端JSON格式的資料
     * @return
     * @throws Exception
     */
    public static List<News> getJSONLastNews() throws Exception{
        String path="http://192.168.1.113:8080/videonews/ListServlet?format=json";
        URL url = new URL(path);
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        conn.setConnectTimeout(5000);
        conn.setRequestMethod("GET");
        if(conn.getResponseCode()==200){
            InputStream inStream=conn.getInputStream();
            return parseJSON(inStream);
        }
        return null;
    }

    /**
     * 解析JSON資料
     * @param inStream
     * @return
     */
    private static List<News> parseJSON(InputStream inStream) throws Exception {
        List<News> newses = new ArrayList<News>();
        byte[] data =StreamTool.read(inStream);
        //將位元組陣列轉換成字串
        String json= new String(data);
        //將json物件轉換成json的陣列物件
        JSONArray array = new JSONArray(json);
        for (int i = 0; i < array.length(); i++) {
            JSONObject jsonObject=array.getJSONObject(i);
            News news=new News(jsonObject.getInt("id"),jsonObject.getString("title"),jsonObject.getInt("timelength"));
            newses.add(news);
        }
        
        return newses;
    }

    /**
     * 解析伺服器返回的XML資料
     * @param inStream
     * @return
     */
    private static List<News> parseXML(InputStream inStream) throws Exception{
        List<News> newses = new ArrayList<News>();
        News news = null;
        //用Pull解析器解析XML檔案
        XmlPullParser parser= Xml.newPullParser();
        parser.setInput(inStream, "UTF-8");
        
        //得到開始文件XML事件
        int event = parser.getEventType();
        
        //不等於結束事件,迴圈讀取XML檔案並封裝成物件
        while(event !=XmlPullParser.END_DOCUMENT){
            switch (event) {
            case XmlPullParser.START_TAG:
                if("news".equals(parser.getName())){
                    int id = new Integer(parser.getAttributeValue(0));
                    news = new News();
                    news.setId(id);
                    
                }else if("title".equals(parser.getName())){
                    
                    news.setTitle(parser.nextText());
                    
                }else if("timelength".equals(parser.getName())){
                    
                    news.setTimelenght(new Integer(parser.nextText()));
                }
                
                break;

            case XmlPullParser.END_TAG:
                if("news".equals(parser.getName())){
                    
                    newses.add(news);
                    news = null;
                }
                break;
            }
            
            event = parser.next();
        }
        
        return newses;
    }
    

}
複製程式碼

3.Activity

複製程式碼
package ygc.yxb.news;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import ygc.yxb.domain.News;
import ygc.yxb.service.VideoNewsService;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        ListView listView=(ListView)this.findViewById(R.id.listView);
        
        try {
            List<News> videos=VideoNewsService.getJSONLastNews();
            List<HashMap<String,Object>> data = new ArrayList<HashMap<String,Object>>();
            for (News news : videos) {
                HashMap<String, Object> item = new HashMap<String, Object>();
                item.put("id", news.getId());
                item.put("title", news.getTitle());
                item.put("timelength", getResources().getString(R.string.timelength)+
                        news.getTimelenght()+getResources().getString(R.string.min));
                data.add(item);
                
            }
            //用SimpleAdapter 繫結ListView控制元件
            SimpleAdapter adapter = new SimpleAdapter(this,data,
                    R.layout.item,new String[]{"title","timelength"},
                    new int[]{R.id.title,R.id.timelength});
            listView.setAdapter(adapter);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
複製程式碼

4讀取資料流工具類:

複製程式碼
package ygc.yxb.utils;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;

public class StreamTool {

    /**
     * 讀取流中的資料
     * @param inStream
     * @return
     * @throws Exception
     */
    public static byte[] read(InputStream inStream) throws Exception {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        //如果位元組流中的資料不等於-1,就說明一直有,然後迴圈讀出
        while( (len=inStream.read(buffer)) !=-1){
            //將讀出的資料放入記憶體中
            outputStream.write(buffer);
            
        }
        inStream.close();
        return outputStream.toByteArray();
    }

}
複製程式碼

這裡android 開發完畢,而顯示的控制元件是ListView 最後在清單檔案中,配置訪問網路的許可權即可。

執行效果如下: