一、前言

  作为一名移动端开发人员,具备一定的服务端开发能力也是非常必要的,本篇博客讲述如何在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. Lingo 做线性规划 - Asset allocation and Portfolio models

    Reference: <An Introduction to Management Science Quantitative Approaches to Decision Making, Rev ...

  2. paip.提升性能3倍--使用栈跟VirtualAlloc代替堆的使用.

    paip.提升性能3倍--使用栈跟VirtualAlloc代替堆的使用. #----为什么要设计堆栈,它有什么独特的用途? 为了性能 ....  堆比栈的性能 也有的说法为了编程容易...这个是错误的 ...

  3. iOS之富文本

    之前做项目时遇到一个问题: 使用UITextView显示一段电影的简介,由于字数比较多,所以字体设置的很小,行间距和段间距也很小,一大段文字挤在一起看起来很别扭,想要把行间距调大,结果在XCode中查 ...

  4. css之属性部分

    这篇写的是今天的学习到的属性,一共20个. 属性再多,但也要会使用,会在使用时可以记起它,才能起到它为我们所需要的作用. 样式属性 1.border CSS边框属性允许你指定一个元素边框的样式和颜色. ...

  5. 解决android SwipeRefreshLayout recyclerview 不能下拉

    http://stackoverflow.com/questions/25178329/recyclerview-and-swiperefreshlayout 23down vote write th ...

  6. exam help

    http://forceprepare.com/ http://forcecertified.com/certifications/certified-developer/ http://blog.l ...

  7. mybatis热加载的实现

    最近在使用mybatis,由于是刚刚开始用,用的并不顺手,目前是感觉有2个地方非常的不好用: 1.mybatis调试不方便 由于dao层只有接口,实现只是一个map的xml文件,想加断点都没有地方加, ...

  8. 将redis作为windows系统的系统服务

    在windows系统,每次打开redis服务都是一个dos窗口一直开着,很不爽,这里我用winsw工具把redis作为系统服务启动 我把自动启动的所有内容都整理好了,请自行下载 下载地址:http:/ ...

  9. Linux--Ubuntu中文文件夹转英文

    前言 在安装Ubuntu的时候,如果选择的系统语言为汉语,安装完成后,Ubuntu系统的主文件夹下的几个文件目录就是中文的,这样才纯终端下,输入起来确实非常的不方便.当然,如果安装Ubuntu的时候, ...

  10. Android--ColorMatrix改变图片颜色

    前言 本篇博客讲解如何通过改变图片像素点RGB的值的方式,在Android中改变图片的颜色.在最后将以一个简单的Demo来作为演示. 本篇博客的主要内容: ColorMatrix 使用ColorMat ...