昨天我们只对Android接收网络数据进行了简单介绍,今天我们完成了Android数据存储网络部分的所有内容。在此我将对这非常重要的内容进行总结。
本篇日志是对Android与WEB应用服务之间进行数据交互的总结,下篇日志是一个经典而又让人十分好奇的Android多线程断点下载应用的总结。下面我们开始Android与网络数据的交互。
一、创建WEB应用服务
使用eclipse3.5创建一个动态WEB应用,使用Struts1处理用户请求。我们此应用添加一个DispatchAction,并为它添加四个方法创建用于处理Android以各种方式提交的请求。
1.创建动态WEB工程
Project name:AndroidWebServer
Target runtime:Apache Tomcat v6.0
Dynamic web module version:2.5
Configuration:Default Configuration for Apache Tomcat v6.0
2.添加DispatchAction
package com.changcheng.web.struts.actions;
import java.io.File;
import java.io.FileOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import com.changcheng.web.struts.forms.DataForm;
public class AndroidWebServer extends DispatchAction {
// Andoird以Get方式发送的请求
public ActionForward sendDataByGet(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String name = request.getParameter("name");
request.setAttribute("message", "Hello " + name);
return mapping.findForward("success");
}
// Andoird以Post方式发送的请求
public ActionForward sendDataByPost(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String name = request.getParameter("name");
request.setAttribute("message", "Hello " + name);
return mapping.findForward("success");
}
// Andoird以表单方式发送的请求
public ActionForward sendDataByForm(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
DataForm formbean = (DataForm) form;
System.out.println("StrData:" + formbean.getStrData());
// 获取上传的文件
if (formbean.getFileData() != null
&& formbean.getFileData().getFileSize() > 0) {
// 设置保存目录
File dir = new File(request.getSession().getServletContext()
.getRealPath("/images"));
if (!dir.exists())
dir.mkdirs();
// 保存文件
FileOutputStream outStream = new FileOutputStream(new File(dir,
formbean.getFileData().getFileName()));
outStream.write(formbean.getFileData().getFileData());// 保存文件
outStream.close();
}
return null;
}
}
3.向web.xml添加Struts1的ActionServlet
struts
org.apache.struts.action.ActionServlet
config
/WEB-INF/struts-config.xml
struts
*.do
4.struts-config.xml
<!--l version=<-->"1.0" encoding="UTF-8"?>
<!--CTYPE struts-config PUBLIC</d-->
"-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
"http://struts.apache.org/dtds/struts-config_1_3.dtd">
"dataForm" type="com.changcheng.web.struts.forms.DataForm" />
"/server"
type="com.changcheng.web.struts.actions.AndroidWebServer" name="dataForm"
scope="request" parameter="method">
"success" path="/WEB-INF/pages/success.jsp"/>
二、创建Android应用
1.创建Android工程
Project name:AndroidWebClient
BuildTarget:Android2.1
Application name:AndroidWEB应用客户端
Package name:com.changcheng.web.client
Create Activity:AndroidWebClient
Min SDK Version:7
2.AndroidManifest.xml
<!--l version=<-->"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
package="com.changcheng.web.client" android:versionCode="1"
android:versionName="1.0">
"@drawable/icon" android:label="@string/app_name">
<!-- 单元测试 -->
"android.test.runner" />
".AndroidWebClient" android:label="@string/app_name">
"android.intent.action.MAIN" />
"android.intent.category.LAUNCHER" />
"7" />
<!-- 访问internet权限 -->
"android.permission.INTERNET" />
<!-- 在SDCard中创建与删除文件权限 -->
"android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<!-- 往SDCard写入数据权限 -->
"android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 单元测试 -->
"android.test.InstrumentationTestRunner"
android:targetPackage="com.changcheng.web.client" android:label="Tests for My App" />
Android应用要访问Internet需要添加权限。
3.ClientService类
package com.changcheng.web.client.service;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import android.os.Environment;
import android.util.Log;
public class ClientService {
private static final String TAG = "ClientService";
// 以get方式发送请求
public static void sendDataToServerByGet() throws Exception {
// 主机地址不可以设置为localhost或127.0.0.1,必须是本机或其他机器所在Internet网或局域网地址。
String path = "http://192.168.0.2:8080/AndroidWebServer/server.do?"
+ "method=sendDataByGet&name=changcheng";
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(6 * 1000);
// 请求成功
if (conn.getResponseCode() == 200) {
// 获取服务器返回的数据
byte[] data = readStream(conn.getInputStream());
Log.i(TAG, new String(data, "UTF-8"));
}
}
// 以Post方式发送请求,面向HTTP协议编程
public static void sendDataTOserverByPost() throws Exception {
String path = "http://192.168.0.2:8080/AndroidWebServer/server.do";
String params = "method=sendDataByPost&name=tingting";// 请求参数
byte[] data = params.getBytes();
URL url = new URL(path);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(6 * 1000);
conn.setDoOutput(true);// 发送POST请求必须设置允许输出
conn.setUseCaches(false);// 不使用Cache
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");// 维持长连接
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Length", String.valueOf(data.length));
conn.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
DataOutputStream outStream = new DataOutputStream(conn
.getOutputStream());
outStream.write(data);// 以内容实体方式发送请求参数
outStream.flush();
outStream.close();
// 请求成功
if (conn.getResponseCode() == 200) {
// 获取服务器返回的数据
byte[] html = readStream(conn.getInputStream());
Log.i(TAG, new String(html, "UTF-8"));
}
}
// 以表单方式发送请求
public static void sendDataToServerByForm() throws Exception {
Map params = new HashMap();
params.put("method", "sendDataByForm");
params.put("strData", "字符串数据");
// 获取SDCard中的good.jpg
File file = new File(Environment.getExternalStorageDirectory(),
"app_Goog_Android_w.png");
FormFile fileData = new FormFile("app_Goog_Android_w.png", new FileInputStream(file),
"fileData", "application/octet-stream");
HttpRequester.post(
"http://192.168.0.2:8080/AndroidWebServer/server.do", params,
fileData);
}
// 获取输入流数据
private static byte[] readStream(InputStream inStream) throws Exception {
byte[] buffer = new byte[1024];
int len = -1;
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
byte[] data = outStream.toByteArray();
outStream.close();
inStream.close();
return data;
}
}
其中使用到的FormFile类:
package com.changcheng.web.client.service;
import java.io.InputStream;
/**
* 上传文件
*/
public class FormFile {
/* 上传文件的数据 */
private byte[] data;
private InputStream inStream;
/* 文件名称 */
private String filname;
/* 表单字段名称*/
private String formname;
/* 内容类型 */
private String contentType = "application/octet-stream";
public FormFile(String filname, byte[] data, String formname, String contentType) {
this.data = data;
this.filname = filname;
this.formname = formname;
if(contentType!=null) this.contentType = contentType;
}
public FormFile(String filname, InputStream inStream, String formname, String contentType) {
this.filname = filname;
this.formname = formname;
this.inStream = inStream;
if(contentType!=null) this.contentType = contentType;
}
public InputStream getInStream() {
return inStream;
}
public void setInStream(InputStream inStream) {
this.inStream = inStream;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
public String getFilname() {
return filname;
}
public void setFilname(String filname) {
this.filname = filname;
}
public String getFormname() {
return formname;
}
public void setFormname(String formname) {
this.formname = formname;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
}
其中使用到的HttpRequester类:
package com.changcheng.web.client.service;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
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 android.util.Log;
/**
* http请求发送器
*/
public class HttpRequester {
/**
* 直接通过HTTP协议提交数据到服务器,实现如下面表单提交功能:
*
enctype="multipart/form-data">
* @param actionUrl 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static String post(String actionUrl, Map params, FormFile[] files) {
try {
String BOUNDARY = "---------7d 4a6d158c9"; //数据分隔线
String MULTIPART_FORM_DATA = "multipart/form-data";
URL url = new URL(actionUrl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(6* 1000);
conn.setDoInput(true);//允许输入
conn.setDoOutput(true);//允许输出
conn.setUseCaches(false);//不使用Cache
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Charset", "UTF-8");
conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
StringBuilder sb = new StringBuilder();
for (Map.Entry entry : params.entrySet()) {//构建表单字段内容
sb.append("--");
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data; name=\""+ entry.getKey() + "\"\r\n\r\n");
sb.append(entry.getValue());
sb.append("\r\n");
}
DataOutputStream outStream = new DataOutputStream(conn.getOutputStream());
outStream.write(sb.toString().getBytes());//发送表单字段数据
for(FormFile file : files){//发送文件数据
StringBuilder split = new StringBuilder();
split.append("--");
split.append(BOUNDARY);
split.append("\r\n");
split.append("Content-Disposition: form-data;name=\""+ file.getFormname()+"\";filename=\""+ file.getFilname() + "\"\r\n");
split.append("Content-Type: "+ file.getContentType()+"\r\n\r\n");
outStream.write(split.toString().getBytes());
if(file.getInStream()!=null){
byte[] buffer = new byte[1024];
int len = 0;
while((len = file.getInStream().read(buffer))!=-1){
outStream.write(buffer, 0, len);
}
file.getInStream().close();
}else{
outStream.write(file.getData(), 0, file.getData().length);
}
outStream.write("\r\n".getBytes());
}
byte[] end_data = ("--" + BOUNDARY + "--\r\n").getBytes();//数据结束标志
outStream.write(end_data);
outStream.flush();
int cah = conn.getResponseCode();
if (cah != 200) throw new RuntimeException("请求url失败");
InputStream is = conn.getInputStream();
int ch;
StringBuilder b = new StringBuilder();
while( (ch = is.read()) != -1 ){
b.append((char)ch);
}
Log.i("ItcastHttpPost", b.toString());
outStream.close();
conn.disconnect();
return b.toString();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 提交数据到服务器
* @param actionUrl 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static String post(String actionUrl, Map params, FormFile file) {
return post(actionUrl, params, new FormFile[]{file});
}
/**
* 提交数据到服务器
* @param actionUrl 上传路径(注:避免使用localhost或127.0.0.1这样的路径测试,因为它会指向手机模拟器,你可以使用http://www.itcast.cn或http://192.168.1.10:8080这样的路径测试)
* @param params 请求参数 key为参数名,value为参数值
*/
public static String post(String actionUrl, Map params) {
HttpPost httpPost = new HttpPost(actionUrl);
List list = new ArrayList();
for (Map.Entry entry : params.entrySet()) {//构建表单字段内容
list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(list, HTTP.UTF_8));
HttpResponse httpResponse = new DefaultHttpClient().execute(httpPost);
if(httpResponse.getStatusLine().getStatusCode() == 200){
return EntityUtils.toString(httpResponse.getEntity());
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return null;
}
}
我们最好对HTTP协议有深入的了解,这样在编写简单数据交互应用时直接面向HTTP协议编程可以提高运行速度并减少资源的占用。
我们在最后一个方法中使用到的HttpPost类,是Apache开源组织提供的httpcomponents-client-4.0.1包。httpcomponents-client-4.0.1可以实现浏览器的大部分功能,但如果我们能不使用它就尽量不使用它,因为这会造成对手机硬件资源的占用,从而减慢应用程序的运行速度。
4.测试类
package com.changcheng.web.client.test;
import com.changcheng.web.client.service.ClientService;
import android.test.AndroidTestCase;
public class TestAndroidClientService extends AndroidTestCase {
public void testSendDataToServerByGet() throws Throwable {
ClientService.sendDataToServerByGet();
}
public void testSendDataToServerByPost() throws Throwable {
ClientService.sendDataTOserverByPost();
}
public void testSendDataToServerByForm() throws Throwable {
ClientService.sendDataToServerByForm();
}
}
5.运行
首先启动AndroidWebService应用程序,然后运行测试方法,查看运行结果。
分享到:
相关推荐
android studio应用程序开发作业,实验数据存储和访问。1、制作启动界面如下图所示 2、选择“教师”,点击“登录”按钮,使用保存在SharedPreferences里的帐号信息验证用户名和密码。登录成功后跳转到如下界面。
第10章 数据存储 10.1 shared preferences 第11章 无线网络通信 11.1 初认识无线局域网 11.2 socket通信 11.3 android与javaschpt交互 第2章 goog-emap与gps 12.1 初认识google map api 12.2 申请...
3.实现了管理员登录,使用的是与Tomcat服务器进行数据交互验证信息的正确性,我使用的是myeclipse进行布置的服务器信息,此时使用的是SQLserver 2008 数据库存储的管理员的信息,读取完以后然后返回到管理界面 ...
一款使用安卓自带的realm数据库来储存数据的锻炼跑步app,Realm自带数据库加密,需要64位字节数据进行加密。指定数据库的密钥后,用户可以安全地存储自己的锻炼数据,而且可以通过注销的方式来自己清除本地的数据,...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
Js与Native交互函数封装,适配了Android与iOS系统,模仿微信公众号jssdk,前端可以通过CDN方式引用Js文件 软件开发设计:PHP、QT、应用软件开发、系统软件开发、移动应用开发、网站开发C++、Java、python、web、C#等...
本书大致可以分成两个部分,第一部分为基础篇,主要介绍Android操作系统概况、Android生命周期与组件通信、Android用户界面设计、Android数据存储与交互、Android后台服务与事件广播、媒介与网络、AndroidNDK,...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
阐述了基于Android平台的个人理财软件的设计与实现过程,系统基于Android平台,采用Java语言开发,通过XML文档进行界面编程,并通过相应的Activity与后台Service实现指定功能,且实现了对数据的图形处理,数据存储与...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
利用 VMware+Ubuntu 制作简易网关,利用串口通信协议采集底层温湿度数据, 以 MQTT、TCP 为通信协议与 Android 端实现数据交互 以Vmware虚拟机和Linux操作系统为核心构建一个简易的物联网网关, 以Proteus仿真为...
8.1 Android数据存储概述 8.2 轻轻地我保护——SharedPreferences存储 8.3 谁的文件,谁主宰——文件存储 8.4 打造自己的数据库存储——SQLite存储方式 8.4.1 Android中对数据库操作 8.4.2 完整地操作数据库——日记...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...
它消除了编写单独的类来管理数据库-对象交互的需要,并允许开发人员使用简单的方法来存储、查询、更新和删除对象。 该库能够存储类的所有对象,这些类的实例变量要么是原始数据类型,要么本身就是另一个可存储类的...
6. 数据存储:Android 提供了多种数据存储方式,包括 SQLite 数据库、文件存储、SharedPreferences 等。 7. 网络通信:Android 支持多种网络通信方式,包括 HTTP、TCP、UDP 等。 8. 社交媒体集成:Android 提供了...