1. 程式人生 > >Android:解析伺服器響應的XML和JSON(包括伺服器SSM搭建)

Android:解析伺服器響應的XML和JSON(包括伺服器SSM搭建)

安卓APP要實現很多功能(比如登入註冊、發表評論等)時都必須要使用到網路資料互動。所以在學習了這部分內容後,就將其以拿一個物件為例整理出來。伺服器用的是SSM(SpringMVC、Spring、MyBatis)集合框架,返回響應資料格式為兩種xml、json,下面會兩種格式都舉例

準備環境
  • java IDE:Eclipse(伺服器)
  • 資料庫:Mysql
  • 構建工具:Maven
  • jdk:1.7以上
  • android IDE:AndroidStudio(客戶端)
開發流程如下:
  1. 準備開發環境
  2. 利用SSM搭建伺服器
  3. 伺服器生成XML或者JSON
  4. 客戶端獲得連結讀取資料
  5. 開始解析 XML:(DOM、SAX、PUll)、Json:(原生態JSONObject,Gson,Fast.json)
  6. 通過listview展示
讀取資料流程

我們先搭建伺服器

1、新建一個mavenProject :

這裡寫圖片描述

這邊我在知道需要哪些依賴架包時,一次性直接新增 (pom.xml):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion
>
4.0.0</modelVersion> <groupId>com.zking</groupId> <artifactId>XmlParser</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>XmlParser Maven Webapp</name> <url>http://maven.apache.org</url> <!--spring版本-->
<properties> <spring.version>4.3.3.RELEASE</spring.version> </properties> <dependencies> <!-- MyBatis依賴 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.2.5</version> </dependency> <!-- MySql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> <!-- Servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- Log4J --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- 整合Spring,包含SpringMVC --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-oxm</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- 引用c3p0 依賴 start--> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.2.1</version> </dependency> <!-- 引用c3p0 依賴 end--> <!-- 引用外掛依賴:MyBatis整合Spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!-- JSTL --> <dependency> <groupId>jstl</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- JACKSON Start--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.6.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.6.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.6.3</version> </dependency> <!-- JACKSON end--> </dependencies> <build> <finalName>XmlParser</finalName> </build> </project>

2、首先我們先把myBatis搭建成功 注(MyBatisconfig.xml可以省略)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">


  <configuration>
        <!-- 連線資料庫資訊 -->
    <!--  <environments default="development">
        <environment id="development">
          <transactionManager type="JDBC"/>
          <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/test"/>
            <property name="username" value="root"/>
            <property name="password" value="tiger"/>
          </dataSource>
        </environment>
      </environments>  -->    
      <!-- 關聯對映檔案 -->
     <!-- <mappers>
          <mapper resource="com/zking/entity/Person.xml" />
      </mappers>--> 

  </configuration>

person.java實體類

package com.zking.entity;

public class Person {


    private int pid;
    private String pname;
    private int page;
    public int getPid() {
        return pid;
    }
    public void setPid(int pid) {
        this.pid = pid;
    }
    public String getPname() {
        return pname;
    }
    public void setPname(String pname) {
        this.pname = pname;
    }


    public Person() {
        super();
        // TODO Auto-generated constructor stub
    }
    public int getPage() {
        return page;
    }
    public void setPage(int page) {
        this.page = page;
    }
    public Person(int pid, String pname, int page) {
        super();
        this.pid = pid;
        this.pname = pname;
        this.page = page;
    }
    public Person(String pname, int page) {
        super();
        this.pname = pname;
        this.page = page;
    }
    @Override
    public String toString() {
        return "Person [pid=" + pid + ", pname=" + pname + ", page=" + page + "]";
    }

}

PersonDao介面:

package com.zking.dao;

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

import com.zking.entity.Person;

public interface PersonDao {

    public void addPerson(Person person);

    public List<Person> getPersons();
}

person對映xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  <mapper namespace="com.zking.dao.PersonDao">
      <insert id="addPerson" parameterType="com.zking.entity.Person" >
          insert into person values(null,#{pname},#{page}); 
      </insert>
      <select id="getPersons" resultType="com.zking.entity.Person">
          select * from person
      </select>
  </mapper>

mybatis這邊就可以先測試一下搭建成功沒有,可以通過

SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(“MyBatisConfig.xml”));拿到Session工廠,具體程式碼就不貼了

新增一個日誌管理
log4j.properties

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

3、下面搭建spring框架:

這邊先來一個數據連線的配置檔案:

uname=root##使用者名稱
upass=tiger##密碼
driver_class=com.mysql.jdbc.Driver##mysql驅動類
url=jdbc:mysql://localhost:3306/test//連線url

initPoolSize=5//資料連線池初始最小5個
maxPoolSize=10//資料連線池最大10

applicationContext.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

    <!-- 1.載入properties檔案 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!--2.引用資料來源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <property name="user" value="${uname}"></property>
        <property name="password" value="${upass}"></property>
        <property name="jdbcUrl" value="${url}"></property>
        <property name="driverClass" value="${driver_class}"></property>

        <property name="initialPoolSize" value="${initPoolSize}"></property>
        <property name="maxPoolSize" value="${maxPoolSize}"></property>
    </bean>

    <!-- 03.配置SQLSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 3.1引用資料來源 -->
        <property name="dataSource" ref="dataSource" ></property>
        <!-- 3.2載入MyBatis配置檔案 -->
        <property name="configLocation" value="classpath:MyBatisConfig.xml"></property>
        <!-- 3.3關聯Mybatis對映檔案 -->
        <property name="mapperLocations" value="classpath:com/zking/entity/*.xml"></property>
    </bean>


    <!-- 配置所有的Dao所在的包 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zking.dao"></property>
    </bean>
</beans>

4、下面搭建SpringMVC

springMVC.xml 這裡記得把註解驅動放進去,如果不加,則會報406的錯

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">


    <!-- 配置掃描器 -->
    <context:component-scan base-package="com.zking"></context:component-scan>


    <!-- 註解驅動 -->
    <mvc:annotation-driven></mvc:annotation-driven>

    <!-- 檢視解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>    
</beans>

PersonContorller.java:

package com.zking.contorller;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.zking.dao.PersonDao;
import com.zking.entity.Person;
import com.zking.entity.Teacher;

//宣告為控制器類
@Controller
public class PersonContorller  {

    //拿到介面物件
    @Autowired
    PersonDao personDao;


    //XML
    @RequestMapping("/getPersons")
    public ModelAndView getPersons(){
        List<Person> mypersons= personDao.getPersons();
        ModelAndView andView=new ModelAndView();
        andView.addObject("mypersons",mypersons);
        andView.setViewName("success");
        return andView;
    }


    //Json格式
    @RequestMapping("/getPersonJson")
    @ResponseBody
    public Teacher getPersonsJson(){
       Teacher teacher= new Teacher();
       teacher.setSchool("天王蓋地虎");
       teacher.setNumber(20);
       List<Person> mypersons= personDao.getPersons();
       teacher.setPersons(mypersons);
        return teacher;
    }   
}

5、訪問資料

如果是XML格式的,我們需要生成xml檔案:
success.jsp:

<%@ page language="java" contentType="text/xml; charset=UTF-8"pageEncoding="UTF-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><%@page isELIgnored="false" %>
<persons>
        <c:forEach items="${mypersons}" var="hh">
          <person id="${hh.pid }" name="${hh.pname }">
            <age>${hh.page }</age>
          </person>
        </c:forEach>
</persons>

如果是Json格式的,就只需在Contorller方法上面加上註解@ResponseBody,返回你需要的物件就行了

最後在來一個頁面測試一下資料訪問

getperson.jsp:

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
        <a href="getPersons.action">獲取xml資料</a>
        <a href="getPersonJson.action">獲取Json資料</a>

</body>
</html>

最後web.xml配置如下:

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>



    <!-- needed for ContextLoaderListener -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!-- Bootstraps the root web application context before servlet initialization -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>



  <!-- The front controller of this Spring Web application, responsible for handling all application requests -->
    <servlet>
        <servlet-name>springDispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springMVC.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- Map all requests to the DispatcherServlet for handling -->
    <servlet-mapping>
        <servlet-name>springDispatcherServlet</servlet-name>
        <url-pattern>*.action</url-pattern>
    </servlet-mapping>
</web-app>

6、到這裡,伺服器的框架搭完,我們只需要在客戶端(應用程式)中去拿資料就可以了

下面在Android app中分為兩種方式去拿資料,一種是解析json,一種是解析XML
(6.1)、首先我們先解析json:

package com.example.android30_jsonparser;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.example.android30_jsonparser.entity.Person;
import com.example.android30_jsonparser.entity.Teacher;
import com.example.android30_jsonparser.uitl.ItemTag;
import com.google.gson.Gson;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;

import static android.os.Build.VERSION_CODES.M;
import static com.alibaba.fastjson.JSON.parseObject;

public class MainActivity extends AppCompatActivity {

    private Teacher teacher;
    private View vHead;//頭部
    private ListView lv_json;
    private MyAdpter myAdpter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv_json = (ListView) findViewById(R.id.lv_json);


    }



    public void getJson(View view){
        new MyAsyncTask().execute();
    }

    class MyAdpter extends BaseAdapter{


        @Override
        public int getCount() {
            return teacher.getPersons().size();
        }

        @Override
        public Object getItem(int i) {
            return teacher.getPersons().get(i);
        }

        @Override
        public long getItemId(int i) {
            return i;
        }

        @Override
        public View getView(int i, View view, ViewGroup viewGroup) {
            if(view==null){//優化物件的重用
                view= LayoutInflater.from(MainActivity.this).inflate(R.layout.item_listview,null);
                ItemTag itemTag=new ItemTag();
                itemTag.tv_pid= (TextView) view.findViewById(R.id.tv_item_listview_pid);
                itemTag.tv_pname= (TextView) view.findViewById(R.id.tv_item_listview_pname);
                itemTag.tv_page= (TextView) view.findViewById(R.id.tv_item_listview_page);
                view.setTag(itemTag);
            }
            ItemTag itemTag= (ItemTag) view.getTag();
            itemTag.tv_pid.setText(""+teacher.getPersons().get(i).getPid());
            itemTag.tv_pname.setText(teacher.getPersons().get(i).getPname());
            itemTag.tv_page.setText(""+teacher.getPersons().get(i).getPage());
            return view;
        }
    }



    class MyAsyncTask extends AsyncTask{
        @Override
        protected Object doInBackground(Object[] objects) {//耗時操作
            String path="http://193.168.2.212:8080/XmlParser/getPersonJson.action";
            try {
                //獲取路徑
                URL url=new URL(path);
                HttpURLConnection  huc= (HttpURLConnection) url.openConnection();
                huc.setRequestMethod("GET");
                huc.setConnectTimeout(5000);
                if(huc.getResponseCode()==200){
                    InputStream is= huc.getInputStream();
                    BufferedReader br=new BufferedReader(new InputStreamReader(is));
                    StringBuffer sb=new StringBuffer();
                    String str=null;
                    while ((str=br.readLine())!=null){
                        sb.append(str);
                    }
                    br.close();
                    is.close();
                    //原生態解析(JSONSObject,JSONArray)
//                    JSONObject jb=new JSONObject(sb.toString());
//                    String school=jb.getString("school");
//                    int number=jb.getInt("number");
//                    Log.i("test",school+"   "+number);
//                    JSONArray ja= jb.getJSONArray("persons");
//                    for (int i=0;i<ja.length();i++){
//                       JSONObject jbPerson=  ja.getJSONObject(i);
//                        int pid= jbPerson.getInt("pid");
//                        String pname= jbPerson.getString("pname");
//                        int page= jbPerson.getInt("page");
//                        Log.i("test",pid+"  "+pname+"  "+page);
//                    }

                    //阿里巴巴json解析(匯入架包以及引用架包)
                    teacher= JSON.parseObject(sb.toString(), Teacher.class);
//                    Log.i("test","alibaba:"+teacher.getSchool()+