一,服务器端

  服务器端使用的是Servlet,封装json对象使用的 'json-lib-2.2.2-jdk15.jar,ezmorph-1.0.4.jar,commons-logging-1.1.jar,commons-lang-2.4.jar,commons-collections-3.2.jar,commons-beanutils-1.7.0.jar' 6个jar包.可在 json封装的jar包中下载,我也不懂最近什么情况,使用Firefox总是很难下载csdn资源,可以使用ie.

1.首先是使用一个Person进行原始数据的封装:

package spt.src;

public class Person {
private String name;
private int age;
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
}

2.然后是两个服务类PersonService和JsonService,分别提供Person对象和将Person对象转换为json格式的字符串的服务类.

package spt.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import spt.src.Person; /**
* 该类用于产生Person对象的服务类.
*
* @author Administrator 2015-1-29
*/
public class PersonService {
public Person getAPerson() {
return new Person("莉莉", 21);
} public List<Person> getListPersons() {
List<Person> persons = new ArrayList<Person>();
persons.add(new Person("李静", 23));
persons.add(new Person("lucy", 20));
persons.add(new Person("小气", 22));
return persons;
} /**获取 id-Person对应的Map列表.
* @return
*/
public List<Map<String, Person>> getListMaps() {
List<Map<String, Person>> maps = new ArrayList<Map<String,Person>>(); Map<String, Person> map01 = new HashMap<String, Person>();
map01.put("a01", new Person("王静", 19));
map01.put("a02", new Person("json", 26)); Map<String, Person> map02 = new HashMap<String, Person>();
map01.put("b01", new Person("okay", 19));
map01.put("b02", new Person("小琴", 24)); maps.add(map01);
maps.add(map02); return maps;
}
}
package spt.service;

import net.sf.json.JSONObject;

/**将对象映射为json格式数据的服务类.
* @author Administrator
*2015-1-29
*/
public class JsonService {
public String getJsonStr(String key, Object value) {
JSONObject jsonObject = new JSONObject();
jsonObject.put(key, value);
return jsonObject.toString();
}
}

3.HttpServlet的子类JsonServlet,用于响应客户端的Servlet的核心处理类.

package spt.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import spt.service.JsonService;
import spt.service.PersonService; @WebServlet("/JsonAction")
public class JsonServlet extends HttpServlet{
/**
*
*/
private static final long serialVersionUID = 1L; @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //get person data.
PersonService personService = new PersonService(); //change person as json.
JsonService jsonService = new JsonService(); String action = req.getParameter("action");
String json = null;
if("p".equalsIgnoreCase(action))
json = jsonService.getJsonStr("p", personService.getAPerson());
else if("plst".equalsIgnoreCase(action))
json = jsonService.getJsonStr("plst", personService.getListPersons());
else if("plstMap".equalsIgnoreCase(action))
json = jsonService.getJsonStr("plstMap", personService.getListMaps()); System.out.println(json);
} @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp); //Get的处理方式和POST的处理方式一样.
}
}

4.另外的一个类是处理不同响应的编码的统一类:

package spt.servlet.filter;

import java.io.IOException;
import java.io.UnsupportedEncodingException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; //filter all servlets.
@WebFilter("/*")
public class EncodingFilter implements Filter { public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpReq = (HttpServletRequest) servletRequest;
//由于HttpServletRequest.setCharacterEncoding()对get方式不起作用,所以要单独编码.
if ("GET".equals(httpReq.getMethod()))
filterChain.doFilter(new HttpServletRequestEncodingWrapper(httpReq), servletResponse);
else {
//use utf encoding for none-get request.
httpReq.setCharacterEncoding("utf-8");
filterChain.doFilter(httpReq, servletResponse);
}
} public void init(FilterConfig filterConfig) throws ServletException { } /**inner class dealing for 'GET' method.
* @author Administrator
*2015-1-27
*/
private class HttpServletRequestEncodingWrapper extends HttpServletRequestWrapper { public HttpServletRequestEncodingWrapper(HttpServletRequest request) {
super(request);
} @Override
public String getParameter(String name) {
//encode with 'iso', and than decode with 'utf'.
String val = super.getRequest().getParameter(name);
if (null != val) {
try {
return new String(val.getBytes("iso8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return super.getParameter(name);
}
} public void destroy() { } }

到此,服务器端已经基本完成,启动服务器后,可在浏览器中输入不同请求参数的url获取不同的json字符串,例如

http://192.168.1.101:8080/ReceiveAndroid/JsonAction?action=Plst

可获得

{"plst":[{"age":23,"name":"李静"},{"age":20,"name":"lucy"},{"age":22,"name":"小气"}]}

接触json数据不是很多,不过很奇怪的是,为什么获得Map列表的时候,我在调试的时候,获得的Map的size()是2,但是在使用url为:

http://192.168.1.101:8080/ReceiveAndroid/JsonAction?action=plstMap

的时候,获取的json字符串为:

{"plstMap":[{"b01":{"age":19,"name":"okay"},"a01":{"age":19,"name":"王静"},"a02":{"age":26,"name":"json"},"b02":{"age":24,"name":"小琴"}},{}]}

末尾有一个成员为空的'{}'.

二,接下来写Android客户端

  1.首先,记得加 Internet permission.

  2.Activity代码:

package spt.http.activity;

import java.lang.ref.WeakReference;

import spt.http.get.activity.R;
import spt.http.post.PostSender;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; public class MainActivity extends Activity {
//view.
private EditText edt_param = null;
private Button btn_ok = null; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
} /**
* 初始化View.
*/
private void initView() {
edt_param = (EditText)findViewById(R.id.edt_para);
btn_ok = (Button)findViewById(R.id.btn_ok); //test:
edt_param.setText("plstMap");
} /**使用静态内部类,解决'This Handler class should be static or leaks might occur',以免造成内存泄露.
* @author Administrator
*
*/
private static class StatusHandler extends Handler {
WeakReference<MainActivity> iMainActivity = null; public StatusHandler(MainActivity mainActivity) {
iMainActivity = new WeakReference<MainActivity>(mainActivity);
} @Override
public void handleMessage(Message msg) {
switch (msg.what) {
case PostSender.SEND_SUCCESS:
//有iMainActivity.get()和iMainActivity.getClass().
Toast.makeText(iMainActivity.get(), "发送成功", Toast.LENGTH_SHORT).show();
break;
case PostSender.SEND_FAIL:
Toast.makeText(iMainActivity.get(), "发送失败", Toast.LENGTH_SHORT).show();
break;
default:
throw new RuntimeException("未知的发送结果!");
}
}
} /**
* 处理发送是否成功的状态的Handler.
*/
private final Handler handler = new StatusHandler(this); /**
* 初始化监听器.
*/
private void initListener() {
//点击按钮,往服务器端发送数据.
btn_ok.setOnClickListener(new Button.OnClickListener() { @Override
public void onClick(View v) {
String name = edt_param.getText().toString();
if(name.isEmpty()) {
Toast.makeText(MainActivity.this, "参数不能为空", Toast.LENGTH_SHORT).show();
return;
}
new PostSender(handler).send(name);
}
});
}
}

  3.使用Apache提供的HTTPClient进行POST请求的业务逻辑层类:

package spt.http.post;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import org.apache.http.HttpResponse;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException; import spt.json.JsonParser;
import spt.src.Person;
import android.os.Handler;
import android.util.Log; /**
* 用户向服务器端发送数据的类(使用post)方法.
*
* @author Administrator
*
*/
public class PostSender {
// 连接服务器的url.
private static final String URL = "http://192.168.1.101:8080/ReceiveAndroid/JsonAction";
// 标识是否连接到服务器成功.
public static final int SEND_SUCCESS = 1;
public static final int SEND_FAIL = 0; private Handler handler = null; //新线程关联的Handler,用于将是否发送成功的标识Message放到消息队列中. public PostSender(Handler handler) {
this.handler = handler;
} /**
* 往服务器发送数据.
*
* @param param
* @param pwd
*/
public void send(String param) {
// 这里params要传递到另外一个方法,加final为了防止被修改.
final Map<String, String> params = new HashMap<String, String>();
params.put("action", param); // 启动新的线程连接服务器.
new Thread(new Runnable() { @Override
public void run() {
// 请求连接.
try {
if (postSend(params, URL, "utf-8"))
handler.sendEmptyMessage(SEND_SUCCESS);
else
handler.sendEmptyMessage(SEND_FAIL);
} catch (MalformedURLException e) {
Log.d("sysout", "run:MalformedURLException" + e.getMessage());
} catch (IOException e) {
Log.d("sysout", "run:IOException" + e.getMessage());
}
}
}).start();
} /**
* 发送post请求的方法.
*
* @param params
* 请求参数的键-值对.
* @param url
* @param encoding
* 使用指定编码对参数值进行编码.
* @return
* @throws MalformedURLException
* @throws IOException
*/
private boolean postSend(Map<String, String> params, String url,
String encoding) throws MalformedURLException, IOException {
// 封装请求参数的键值对.
List<BasicNameValuePair> pairs = new ArrayList<BasicNameValuePair>();
for (Entry<String, String> param : params.entrySet()) {
pairs.add(new BasicNameValuePair(param.getKey(), param.getValue()));
}
//封装请求参数的实体.
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs, encoding);
//使用post请求.
HttpPost post = new HttpPost(url);
post.setEntity(entity);
//使用DefaultHttpClient指定请求,以获取响应信息.
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(post);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "utf-8"));
String ln = null;
while((ln = reader.readLine()) != null) {
// Log.d("sysout", ln);
try {
List<Map<String, Person>> maps = JsonParser.getListPersonMap("plstMap", ln);
for (Map<String, Person> map : maps) {
for (Entry<String, Person> en : map.entrySet()) {
Person p = en.getValue();
Log.d("sysout", "k:" + en.getKey() + "->" + p.getName() + "," + p.getAge());
}
}
} catch (JSONException e) {
Log.d("sysout", "postSend::readLine:JSONException" + e.getMessage());
e.printStackTrace();
}
}
return response.getStatusLine().getStatusCode() == 200; // 等于200表示发送成功.
}
}

  4.在客户端定义一个对象类,与服务器端的一致,用来封装json数据.

package spt.src;

/**用于将json数据转换的目标对象的类.
* @author Administrator
*
*/
public class Person {
private String name;
private int age;
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 Person(String name, int age) {
this.name = name;
this.age = age;
}
}

  5.解析json数据为目标类对象的辅助类:

package spt.json;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import spt.src.Person; /**
* 解析从服务器端获取的json数据,并封装为对象.
*
* @author Administrator
*
*/
public class JsonParser {
public static Person getPerson(String key, String jsonStr)
throws JSONException {
JSONObject jObj = new JSONObject(jsonStr);
JSONObject personObj = jObj.getJSONObject(key);
return new Person(personObj.getString("name"), personObj.getInt("age"));
} /**
* 根据json数据,返回对象列表.
*
* @param key
* @param jsonStr
* @return
* @throws JSONException
*/
public static List<Person> getPersonList(String key, String jsonStr)
throws JSONException {
JSONObject jsonObject = new JSONObject(jsonStr);
JSONArray jArr = jsonObject.getJSONArray(key); List<Person> persons = new ArrayList<Person>(); // 存储返回对象.
JSONObject jObj = null;
for (int j = 0; j < jArr.length(); j++) {
jObj = jArr.getJSONObject(j);
persons.add(new Person(jObj.getString("name"), jObj.getInt("age")));
}
return persons;
} /**
* 根据json数据,返回对象构成的键值对的列表.
*
* @param key
* @param jsonStr
* @return
* @throws JSONException
*/
public static List<Map<String, Person>> getListPersonMap(String key,
String jsonStr) throws JSONException {
JSONObject jsonObject = new JSONObject(jsonStr);
List<Map<String, Person>> personMaps = new ArrayList<Map<String, Person>>(); // 存储返回对象构成的键值对.
//Map<String, Person>构成的数组.
JSONArray jArr = jsonObject.getJSONArray(key);
JSONObject jObj = null;
for (int j = 0; j < jArr.length(); j++) {
jObj = jArr.getJSONObject(j);
//迭代每一个Map<String, Person>.
Map<String, Person> personMap = new HashMap<String, Person>();
@SuppressWarnings("unchecked")
Iterator<String> ks = jObj.keys();
JSONObject jPersonObj = null; //一个Person对象对应的json.
String k = null; //Person对象对应的键.
while(ks.hasNext()) {
k = ks.next();
jPersonObj = (JSONObject)jObj.get(k);
//将Person对象封装到Map中.
personMap.put(k, new Person(jPersonObj.getString("name"), jPersonObj.getInt("age")));
}
//将Map<String, Person>封装成数组.
personMaps.add(personMap);
}
return personMaps;
}
}

客户端可以运行,在这里偷懒一下,对于不同解析,如何遍历List<Person> 和显示Person单独对象,相对简单,所以就省略了.

json api: http://json-lib.sourceforge.net/apidocs/jdk15/

  

Android - 服务器json数据交互.的更多相关文章

  1. android json解析及简单例子+Android与服务器端数据交互+Android精彩案例【申明:来源于网络】

    android json解析及简单例子+Android与服务器端数据交互+Android精彩案例[申明:来源于网络] android json解析及简单例子:http://www.open-open. ...

  2. android基础---->JSON数据的解析

    上篇博客,我们谈到了XML两种常用的解析技术,详细可以参见我的博客(android基础---->XMl数据的解析).网络传输另外一种数据格式JSON就是我们今天要讲的,它是比XML体积更小的数据 ...

  3. 分享两个模拟get和post方法的工具类,让应用能够与服务器进行数据交互

    很久没有码字了,今天跟大家分享一个模拟get和post方法的工具类,在安卓应用中很多都需要跟服务器进行数据交互,这需要两方面的配合,首先服务器端会给应用提供一些数据交互的接口,可是怎样在应用中去调用呢 ...

  4. json数据交互

    springmvc 的json数据交互 - 哎幽的成长 - CSDN博客--和老师讲课相同http://blog.csdn.net/u012373815/article/details/4720818 ...

  5. springmvc的json数据交互

    准备 @RequestBody 作用: @RequestBody注解用于读取http请求的内容(字符串),通过springmvc提供的HttpMessageConverter接口将读到的内容(json ...

  6. 1.4(Spring MVC学习笔记)JSON数据交互与RESTful支持

    一.JSON数据交互 1.1JSON简介 JSON(JavaScript Object Notation)是一种数据交换格式. 1.2JSON对象结构 {}代表一个对象,{}中写入数据信息,通常为ke ...

  7. Vue.js 学习笔记之三:与服务器的数据交互

    显而易见的,之前的02_toDoList存在着一个很致命的缺陷.那就是它的数据只存在于浏览器端,一但用户关闭或重新载入页面,他之前加入到程序中的数据就会全部丢失,一切又恢复到程序的初始状态.要想解决这 ...

  8. spring-boot json数据交互

    SpringBoot学习之Json数据交互 最近在弄监控主机项目,对javaweb又再努力学习.实际的项目场景中,前后分离几乎是所以项目的标配,全栈的时代的逐渐远去,后端负责业务逻辑处理,前端负责数据 ...

  9. SpringMVC JSON数据交互

    本节内容: @RequestBody @ResponseBody 请求json,响应json实现 前端可以有很多语言来写,但是基本上后台都是java开发的,除了c++(开发周期长),PHP和#Net( ...

随机推荐

  1. 三招搞挂Mysql(转)

    一.产生大量的undo日志 众所周知,InnoDB是一个支持MVCC的存储引擎,为了支持MVCC,InnoDB需要保存undo日志,以便对用户提供记录的历史版本.如果我们开启一个事务,反复地更新一条记 ...

  2. 【UE】

    1.链接颜色.评论颜色.时间颜色 区分 2.昵称 - 评论 - 时间 用户视线很自然

  3. poj 2586 Y2K Accounting Bug

    http://poj.org/problem?id=2586 大意是一个公司在12个月中,或固定盈余s,或固定亏损d. 但记不得哪些月盈余,哪些月亏损,只能记得连续5个月的代数和总是亏损(<0为 ...

  4. C#面向对象的三大特征

    一,封装:我们可以把世界上任何一个东西都看作为一个对象,那么我们这里以人为例,一个人就肯定是一个对象了.那么封装是什么呢?封装就是这个人要完成一件事情,他所需要的任何工具都带在了自己的身上,所需要的技 ...

  5. Android应用开发学习之表格视图

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 本文我们来学习一个使用表格视图的程序,下图是该程序的运行效果: 该程序主Activity文件内容如下: packag ...

  6. CSS 最核心的几个概念

    CSS 中最核心的几个概念,包括:盒模型.position.float等. 这些是 CSS 的基础,也是最常用的几个属性,它们之间看似独立却又相辅相成. 元素类型 HTML 的元素可以分为两种: 块级 ...

  7. php 燕十八 观察者模式代码例子

    <?php class user implements SplSubject { public $lognum; public $hobby; protected $observers=null ...

  8. jquery获取节点的时候获取包含自己在内的HTML标签

    jquery获取某个标签的html()方法的时候总是只能获取内部的 如果获取包含自身的HTML代码呢? 用.prop("outerHTML")方法获取 <div id=&qu ...

  9. jetty之嵌入式运行jetty

    在文章什么是jetty中,提到jetty容器真正出名的地方是可以作为一个嵌入到java代码的servlet容器,即可以在java代码中实例化servlet对象并操作该对象.下面我们就先来学习 下如何把 ...

  10. git与svn的区别-小结一下

    1)Git是分布式的,SVN不是: 这 是GIT和其它非分布式的版本控制系 统,例如SVN,CVS等,最核心的区别.好处是跟其他同事不会有太多的冲突,自己写的代码放在自己电脑上,一段时间后再提交.合并 ...