Android:解析伺服器響應的XML和JSON(包括伺服器SSM搭建)
阿新 • • 發佈:2019-01-08
安卓APP要實現很多功能(比如登入註冊、發表評論等)時都必須要使用到網路資料互動。所以在學習了這部分內容後,就將其以拿一個物件為例整理出來。伺服器用的是SSM(SpringMVC、Spring、MyBatis)集合框架,返回響應資料格式為兩種xml、json,下面會兩種格式都舉例
準備環境
- java IDE:Eclipse(伺服器)
- 資料庫:Mysql
- 構建工具:Maven
- jdk:1.7以上
- android IDE:AndroidStudio(客戶端)
開發流程如下:
- 準備開發環境
- 利用SSM搭建伺服器
- 伺服器生成XML或者JSON
- 客戶端獲得連結讀取資料
- 開始解析 XML:(DOM、SAX、PUll)、Json:(原生態JSONObject,Gson,Fast.json)
- 通過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()+