一、前言

  作为一名移动端开发人员,具备一定的服务端开发能力也是非常必要的,本篇博客讲述如何在Android和服务器之间实现JSON数据通信交互,博客内容基于另外一篇博客:【Web】Eclipse + Maven + Struts搭建服务器

二、服务器端改造

  在博客【Web】Eclipse + Maven + Struts搭建服务器中,我们实现了服务器的搭建,现在要做的事情就是让它返回的数据是一个JSON格式的,这样在获得请求的时候,我们才可以得到JSON数据,其配置改变如下。

  首先我们新建一个com.android.display.bean包,新建一个User类,如下:

 package conm.android.sdisplay.bean;

 public class User {
String id;
String name;
String password;
String say;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSay() {
return say;
}
public void setSay(String say) {
this.say = say;
}
}

  修改HelloAction代码如下:

 package com.android.displaymain;

 import java.util.HashMap;
import java.util.Map; import com.opensymphony.xwork2.ActionSupport; import conm.android.sdisplay.bean.User; public class HelloAction extends ActionSupport{
//将会被Struts2序列化为JSON字符串的对象
private Map<String, Object> dataMap; @Override
public String execute() throws Exception {
// dataMap中的数据将会被Struts2转换成JSON字符串,所以这里要先清空其中的数据
dataMap = new HashMap<String, Object>();
User user = new User();
user.setId("123");
user.setName("Android");
user.setPassword("abcdefg");
user.setSay("Hello world !");
dataMap.put("user", user);
// 放入一个是否操作成功的标识
dataMap.put("success", true);
// 返回结果
return SUCCESS;
} public Map<String, Object> getDataMap() {
return dataMap;
} public void setDataMap(Map<String, Object> dataMap) {
this.dataMap = dataMap;
}
}

  我们的目标是将dataMap以JSON格式返回。现在Action已经完成了,但是还需要配置一下,修改struts.xml文件如下:

 <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd"> <struts>
<package name="com.android.server" namespace="/" extends="json-default" >
<default-action-ref name="index"/> <action name="index">
<result>/index.jsp</result> <!-- index.htm为项目根目录的默认页面 -->
</action> <action name="HelloAction" class="com.android.displaymain.HelloAction" method="execute">
<result type="json"> <!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
<param name="root">dataMap</param>
</result>
</action>
</package>
</struts>

  注意两处改动,一是package的extends属性,二是HelloAction的结果返回类型,已经变为json,并且我们声明了一个叫做root的param,其值就是我们要JSON化的属性,至于为什么要声明,待会儿可以测试一下。

  修改完之后,我们因为使用JSON,需要Struts做一定的工作,我们就需要引入新的jar包,将pom文件改为:

 <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.android.network</groupId>
<artifactId>network_server</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>network_server Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>2.3.16</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-json-plugin</artifactId>
<version>2.3.4</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
</dependency>
</dependencies>
<build>
<finalName>network_server</finalName>
</build>
</project>

  这里增添了两个jar包,最重要的一个是struts2-json-plugin。

  配置完成,我们再运行一下工程,运行起来以后,我们在浏览器(注:非IE,否则会要求你下载文件)中输入网址:http://localhost:8080/display/HelloAction就可以看到浏览器返回的数据:

{"success":true,"user":{"id":"123","name":"Android","password":"abcdefg","say":"Hello world !"}}

  很明显,服务器端已经正确返回我们需要的JSON数据了!读者可以去掉struts.xml配置中的关于root的配置,看看结果就明白这段配置的含义了。接下来就看Android端的了。

三、Android客户端构建

  Android实现的目标是:向服务器发送请求,并且携带参数,展示返回的JSON数据。Android环境的搭建就不赘述啦~直接进入正题。

  发起请求的Activity如下:

 package com.example.androidjson;

 import java.io.IOException;

 import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity {
TextView textView;
Button dataButton;
Handler mainHandler; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.textView);
dataButton = (Button)findViewById(R.id.dataButton); mainHandler = new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
textView.setText(msg.obj.toString());
}
}; dataButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Thread thread = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
sendData();
}
}; thread.start();
}
});
} private void sendData(){
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://192.168.0.102:8080/display/HelloAction");
try {
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 取得返回的数据
Message msg = mainHandler.obtainMessage(0, EntityUtils.toString(httpResponse.getEntity()));
mainHandler.sendMessage(msg);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

  按下按钮后返回结果如下:

到这里,基本功能已经完成,我们可以发起请求,获取到正确的JSON格式数据了。接下来就是解析JSON数据格式了~

  修改一下服务器端的HelloAction代码如下:

 package com.android.displaymain;

 import java.util.HashMap;
import java.util.Map; import com.opensymphony.xwork2.ActionSupport; import conm.android.sdisplay.bean.User; public class HelloAction extends ActionSupport{
//将会被Struts2序列化为JSON字符串的对象
private Map<String, Object> dataMap; private String name; @Override
public String execute() throws Exception {
// dataMap中的数据将会被Struts2转换成JSON字符串,所以这里要先清空其中的数据
dataMap = new HashMap<String, Object>();
User user = new User();
user.setId("123");
user.setName(name);
user.setPassword("abcdefg");
user.setSay("Hello world !");
dataMap.put("user", user);
// 放入一个是否操作成功的标识
dataMap.put("success", true);
// 返回结果
return SUCCESS;
} public Map<String, Object> getDataMap() {
return dataMap;
} public void setDataMap(Map<String, Object> dataMap) {
this.dataMap = dataMap;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
}
}

  这里要求我们传入一个参数name,并且设置到返回值中去。现在,我们的目标是通过JSON向服务器端发送带参数请求,并正确解析返回的数据。修改Activity代码如下:

 package com.example.androidjson;

 import java.io.IOException;
import java.util.ArrayList; import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
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.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;
import org.json.JSONObject; import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends Activity {
TextView textView;
Button dataButton;
Handler mainHandler; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); textView = (TextView)findViewById(R.id.textView);
dataButton = (Button)findViewById(R.id.dataButton); mainHandler = new Handler(){ @Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
parseJSON(msg.obj.toString());
}
}; dataButton.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Thread thread = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
sendData();
}
}; thread.start();
}
});
} private void parseJSON(String result){
JSONObject jsonObj;
try {
jsonObj = new JSONObject(result);
boolean resResult = jsonObj.getBoolean("success");
JSONObject userObj = jsonObj.getJSONObject("user");
String id = userObj.getString("id");
String name = userObj.getString("name");
String say = userObj.getString("say");
textView.setText("ID: "+ id + "\n姓名: " + name + "\n性别: " + say);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} private void sendData(){
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://192.168.0.102:8080/display/HelloAction");
try {
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("name", "大脚印"));
HttpEntity en = new UrlEncodedFormEntity(list, HTTP.UTF_8);
httpPost.setEntity(en);
HttpResponse httpResponse = httpClient.execute(httpPost);
if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
// 取得返回的数据
Message msg = mainHandler.obtainMessage(0, EntityUtils.toString(httpResponse.getEntity()));
mainHandler.sendMessage(msg);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

  点击Send Data 按钮:

至此,我们已经可以完成从数据库返回JSON格式的数据,并且正确解析数据~

五、总结

  突发奇想,想要自己走一遍Android客户端到服务器之间的数据传递流程,所以花了点时间研究了一下~

  使用JSON传递数据非常简单,尤其是当服务器使用Struts2时可以使用插件支持该功能,更是非常方便~

客户端 & 服务器端示例代码下载

【Android】与服务器实现JSON数据通信的更多相关文章

  1. android跟服务器使用json传递数据

    最近在做项目,使用了json传递数据,把服务器对象转换成json字符串返回,android使用gson包解析json字符串变成对象. 1.服务器代码编写,我这边是在servlet里面 Peron pe ...

  2. 从高处理解android与服务器交互(看懂了做开发就会非常的容易)

    今天帮一个朋友改一个bug 他可以算是初学者吧 .我给他看了看代码,从代码和跟他聊天能明显的发现他对客户端与服务器交互 基本 不是很了解.所以我花了更多时间去给他讲客户端与服务器的关系.我觉得从这个高 ...

  3. Android学习笔记之JSON数据解析

    转载:Android学习笔记44:JSON数据解析 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种 ...

  4. android 与 服务器通信

    android 与 服务器通信 服务端代码: (1)control 层 /** * 用户登录 * @return */ @RequestMapping(value = "/login&quo ...

  5. 移动开发首页业界资讯移动应用平台技术专题 输入您要搜索的内容 基于Java Socket的自定义协议,实现Android与服务器的长连接(二)

    在阅读本文前需要对socket以及自定义协议有一个基本的了解,可以先查看上一篇文章<基于Java Socket的自定义协议,实现Android与服务器的长连接(一)>学习相关的基础知识点. ...

  6. 【代码笔记】iOS-向服务器传JSON数据的两种方式

    一,代码. - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. ...

  7. Android - 向服务器发送数据(POST) - HTTPClient.

    该篇文章主要说明使用Apache提供的HTTPClient,通过post方式,向服务器发送数据.由于有些东西在 Android - 向服务器发送数据(GET)中提到过,就不再重复. 一,Android ...

  8. Ajax与服务器(JSON)通信介绍

    本文主要介绍使用Ajax与服务器(JSON)通信方法,谈谈Ajax提供的两类服务器通信手段:同步通信和异步通信.有需要的可以了解一下.毕竟这个时代出了很多东西,自动化构建工具,mvvm框架等等.Jav ...

  9. 服务器返回JSON,IE出现下载问题

    我向来的观点,IE就是个奇葩. 服务器返回json,chrome处理得好地地,但IE却奇葩地向你请求是否要保存这个JSON文件? 之所以出现这种弱智现象,是因为IE无法识别一个所谓的响应头部:appl ...

随机推荐

  1. JAVA软件开发职责

    1.了解OO,AOP,SOA设计模式.J2EE的核心设计模式.应用架构模式和应用集成模式:2.熟练使用Spring.Hibernate/ibatis.Struts等通用性开源框架,并对其原理有深刻的理 ...

  2. NPM小结

    nodejs的出现,可以算是前端里程碑式的一个事件,它让前端攻城狮们摆脱了浏览器的束缚,踏上了一个更加宽广的舞台.前端的可能性,从此更加具有想象空间. 随着一系列基于nodes的应用/工具的出现,工作 ...

  3. netstat常见参数

    -a (all)显示所有选项,默认不显示LISTEN相关-t (tcp)仅显示tcp相关选项-u (udp)仅显示udp相关选项-n 拒绝显示别名,能显示数字的全部转化成数字.-l 仅列出有在 Lis ...

  4. Atitit.java eval功能的实现  Compiler API

    Atitit.java eval功能的实现  Compiler API 输出echo2 输出目录配置2 针对编译器,JDK 设计了两个接口,分别是 JavaCompiler 和JavaCompiler ...

  5. iOS开发-- 开发环境,证书和授权文件

    一.成员介绍 1.    Certification(证书)证书是对电脑开发资格的认证,每个开发者帐号有一套,分为两种:1)    Developer Certification(开发证书)安装在电脑 ...

  6. android定位GPS定位 代码实现

    package com.lx.util;   import android.content.Context; import android.content.SharedPreferences; imp ...

  7. 更改Linux默认栈空间的大小

    有时候在Linux写C++程序处理大量的数据,程序内部需要分配很大的数组来存放一些数据,但有时候分配的数组太大的话运行时会出现段错误.这种情况可能是分配的数组大小超过了Linux系统的默认栈空间的大小 ...

  8. [mongodb-10gen]ubuntu下安装方法

    由于自己老是不死心,所以还是继续在UBUNTU下开始我的GOLANG,今天发现服务源很快一下子就把GO的源代码从GoogleProject上给hg回来了,所以今天才查了一下在UBUNTU下安装Mong ...

  9. Asp.net WebAPI 单元测试

    现在Asp.net webapi 运用的越来越多,其单元而是也越来越重要.一般软件开发都是多层结构,上层调用下层的接口,而各层的实现人员不同,一般大家都只写自己对应单元测试.对下层的依赖我们通过IOC ...

  10. nodejs express 框架解密2-如何创建一个app

    本文是基于express 3.4.6 的 1.在我们的app.js 文件里面有这么几行 http.createServer(app).listen(app.get('port'), function( ...