注意事项Android网络通信中数据传输的JSON格式使用
什么是JSON格式
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。 JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等)。这些特性使JSON成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率)。
JSON格式语法
JSON 值可以是:
数字(整数或浮点数)
字符串(在双引号中)
逻辑值(true 或 false)
数组(在方括号中)
对象(在花括号中)
null
//创建单个人的对象
{
"姓名":"大憨",
"年龄":24
}
//创建学生数组,给数组赋值。
{
"学生": [
{"姓名":"小明","年龄":23},
{"姓名":"大憨","年龄":24}
]
}
//在JavaScript中创建people数组
var people = {
"programmers": [{
"firstName": "Brett",
"lastName": "McLaughlin",
"email": "aaaa"
}, {
"firstName": "Jason",
"lastName": "Hunter",
"email": "bbbb"
}, {
"firstName": "Elliotte",
"lastName": "Harold",
"email": "cccc"
}],
"authors": [{
"firstName": "Isaac",
"lastName": "Asimov",
"genre": "sciencefiction"
}, {
"firstName": "Tad",
"lastName": "Williams",
"genre": "fantasy"
}, {
"firstName": "Frank",
"lastName": "Peretti",
"genre": "christianfiction"
}],
"musicians": [{
"firstName": "Eric",
"lastName": "Clapton",
"instrument": "guitar"
}, {
"firstName": "Sergei",
"lastName": "Rachmaninoff",
"instrument": "piano"
}]
};
/*数组的下标从0开始*/
people.authors[1].genre // Value is "fantasy"
people.musicians[3].lastName // Undefined. This refers to the fourth entry, and there isn't one
people.programmers[2].firstName // Value is "Elliotte"
步骤简介
1、因为要使用gson的第三方架包,所以要导包,build path。
2、根据我们要传递的json内容在Eclipse for JavaEE中新建类,包括Person、Result、SchoolInfo等三个类。
这就是我们要处理的Json信息。
{
//result是一个结果值,当我们的客户端从服务器接受的Json串中的result为1的时,说明接收数据正确。
"result": 1,
"personDate": [
{
"name": "Nate",
"age": 12,
"school_info": "清华",
"url": "http://image.dili360.com/eweekly/ezhoukan/026/36_312525427_20110727180330.jpg"
},
{
"name": "Jack",
"age": 24,
"school_info": "北大",
"url": "http://cache.house.sina.com.cn/citylifehouse/citylife/b7/7b/20090611_29015_1.jpg"
}
]
}
3、新建TestJson.java来调用各种类赋初值。使用Gson就可以将我们生成的各种类直接转化成Json格式字符串。
4、新建JsonServeServlet来将服务器端创建的Json数组传递给客户端。
5、在客户端新建item.xml和json.xml完成相关的客户端布局。item.xml是单个数据,json.xml是填充的item的ListView。
6、将我们在服务器端也就是Eclipse for JavaEE中写好的各种类,包括Person、Result、SchoolInfo等三个类。复制到Android工程中。
7、创建HttpJson.java来继承Thread,完成相关网络操作,从服务器获取信息,发送请求,获取服务器返回的Json字符串。交给JsonAdapter.java解析,同时也要完成UI界面的更新,就是用Adapter填充ListView。
8、创建HttpImage.java来继承Thread,完成item.xml中图片的填充。
9、创建一个JsonAdapter.java来获取服务器返回的信息填充item.xml布局文件。设置界面信息。调用HttpImage.java来完成item.xml里面的图片部分。
10、创建JsonActivity.java来关联json.xml。HttpJson
源码分析
Person.java
package com.example.http_01;
import java.util.List;
//使用Gjon之后,只要我们生成数据对象,Gjon就会自动帮我们生成json代码
public class Person {
private String name;
private int age;
private String school_info;
private String url;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getSchool_info() {
return school_info;
}
public void setSchool_info(String school_info) {
this.school_info = school_info;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
Result.java
package com.example.http_01;
import java.util.List;
public class Result {
private int result;
private List<Person> personDate;
public int getResult() {
return result;
}
public void setResult(int result) {
this.result = result;
}
public List<Person> getPersonDate() {
return personDate;
}
public void setPersonDate(List<Person> personDate) {
this.personDate = personDate;
}
}
SchoolInfo.java
package com.example.http_01;
public class SchoolInfo {
private String school_name;
public String getSchool_name() {
return school_name;
}
public void setSchool_name(String school_name) {
this.school_name = school_name;
}
}
item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/ImageView"
android:layout_width="150dp"
android:layout_height="100dp"
android:layout_alignParentLeft="true"
/>
<RelativeLayout
android:padding="10dp"
android:layout_toRightOf="@+id/ImageView"
android:layout_width="fill_parent"
android:layout_height="100dp"
>
<TextView
android:id="@+id/name"
android:textSize="15sp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Name" />
<TextView
android:id="@+id/age"
android:textSize="15sp"
android:layout_below="@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Age" />
<TextView
android:id="@+id/school_info"
android:textSize="15sp"
android:layout_below="@+id/age"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="School" />
</RelativeLayout>
</RelativeLayout>
json.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<ListView
android:id="@+id/listView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
</ListView>
</RelativeLayout>
HttpImage.java
package com.example.http_01;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.widget.ImageView;
public class HttpImage extends Thread {
private ImageView imageview;
private String url;
private Handler handler;
public HttpImage(String url,ImageView imageview,Handler handler){
this.url=url;
this.handler=handler;
this.imageview=imageview;
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
URL httpUrl=new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
InputStream in = conn.getInputStream();
final Bitmap bitmap = BitmapFactory.decodeStream(in);
handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
imageview.setImageBitmap(bitmap);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
JsonAdapter
package com.example.http_01;
import java.util.List;
import android.content.Context;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class JsonAdapter extends BaseAdapter {
private List<Person> list;
private Context context;
private Handler handler=new Handler();
//LayoutInflater的作用类似于findViewById()。不同点是LayoutInflater是用来找res/layout/下的xml布局文件,实例化;
//而findViewById()是找xml布局文件下的具体widget控件
//1、对于一个没有被载入或者想要动态载入的界面,都需要使用LayoutInflater.inflate()来载入;
//2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。
private LayoutInflater inflater;
public JsonAdapter(Context context,List<Person> list){
this.list=list;
this.context=context;
inflater = LayoutInflater.from(context);
}
public JsonAdapter(Context context){
this.context=context;
inflater = LayoutInflater.from(context);
}
public void setData(List<Person>data){
this.list=data;
}
//getCount() 返回list所包含的item总个数
@Override
public int getCount() {
// TODO Auto-generated method stub
return list.size();
}
//返回当前Item显示的数据,方便在Activity中的onItemClick方法中调用
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return list.get(position);
}
//getItemId返回的是多少就是当前是第几列,从0开始。
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
Holder holder = null;
if(convertView==null){
//当convertView不为空的时候,inflater充满item布局
convertView=inflater.inflate(R.layout.item, null);
holder = new Holder(convertView);
convertView.setTag(holder);
}else{
holder = (Holder) convertView.getTag();
}
Person person = list.get(position);
holder.name.setText(person.getName());
holder.age.setText(""+person.getAge());
holder.school_info.setText(person.getSchool_info());
new HttpImage(person.getUrl(), holder.imageview, handler).start();
return convertView;
}
class Holder{
private TextView name;
private TextView age;
private TextView school_info;
private ImageView imageview;
public Holder(View view){
name=(TextView) view.findViewById(R.id.name);
age=(TextView) view.findViewById(R.id.age);
school_info=(TextView) view.findViewById(R.id.school_info);
imageview=(ImageView) view.findViewById(R.id.ImageView);
}
}
}
HttpJson.java
package com.example.http_01;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.os.Handler;
import android.widget.ListView;
import android.widget.Toast;
public class HttpJson extends Thread {
private String url;
private Context context;
private ListView listView;
private JsonAdapter adapter;
private Handler handler;
public HttpJson(String url,ListView listView,JsonAdapter adapter,Handler handler){
this.listView=listView;
this.adapter=adapter;
this.url=url;
this.handler=handler;
}
@Override
public void run() {
URL httpUrl;
try {
httpUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection) httpUrl.openConnection();
conn.setRequestMethod("GET");
conn.setReadTimeout(5000);
BufferedReader read = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuffer sb = new StringBuffer();
String str;
//循环读取服务器返回的数据。
while((str=read.readLine())!=null){
sb.append(str);
}
//把解析的对象传进去sb
final List<Person> data = parseJson(sb.toString());
//因为是子线程,需要向主线程发送信息的。
handler.post(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
adapter.setData(data);
//设置listview填充adapter
listView.setAdapter(adapter);
}
});
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private List<Person> parseJson(String json){
try {
JSONObject object=new JSONObject(json);
int result=object.getInt("result");
//将解析的json转化成实体的数据,创建一个ArrayList对象。
List<Person> persons=new ArrayList<Person>();
if(result==1){
JSONArray personData=object.getJSONArray("personDate");
//先创建数组,再遍历。
for(int i=0;i<personData.length();i++){
Person personObject=new Person();
persons.add(personObject);
//取出数组中所对应的每一个object。
JSONObject person=personData.getJSONObject(i);
String name=person.getString("name");
int age=person.getInt("age");
String url=person.getString("url");
String school_info=person.getString("school_info");
personObject.setName(name);
personObject.setAge(age);
personObject.setUrl(url);
personObject.setSchool_info(school_info);
}
return persons;
}else{
Toast.makeText(context,"error1",1).show();
}
} catch (JSONException e) {
//TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
JsonActivity.java
package com.example.http_01;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ListView;
public class JsonActivity extends Activity {
private ListView listView;
private JsonAdapter adapter;
private Handler handler=new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
//关联json.xml
setContentView(R.layout.json);
listView=(ListView) findViewById(R.id.listView);
adapter = new JsonAdapter(this);
String url="http://192.168.1.106:8080/web/JsonServeServlet";
new HttpJson(url,listView,adapter,handler).start();
}
}
最终运行效果
注意事项
1)、要解析json就要使用Google提供的一个名为gson的第三方架包。新建文件Gson的时候,在ADT或者Android Studio里面要建一个libs文件夹,把Gson-2.2.2.jar导入到里面,再在工程里Build Path。
2)、在JavaEE里面,Gson-2.2.2.jar必须导入到WEB-INF下面的lib文件夹里面。
3)、在JaveEE写好了的Person,Result,SchoolInfo类,同样要导入Eclipse(Android Studio)。