问题:
Android应用中,当遇到填写用户信息、发表评论等操作,不可避免会遇到“form表单操作”(类似web form操作)上传图片的功能。
在这种情况下,使用Android的HTTPConnection/ ApacheHTTP 通过POST 和GET的方式就实现不了。
解决方法:
其中
Android客户端通过模拟 HTTP multipart/form-data 请求协议信息实现图片上传。
/**
* 文件名称:UploadImage.java
*
* 版权信息:Apache License, Version 2.0
*
* 功能描述:实现图片文件上传。
*
* 创建日期:2011-5-10
*
* 作者:Bert Lee
*/
/package com.zjzcl;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class UploadImage {
String multipart_form_data = "multipart/form-data";
String twoHyphens = "--";
String boundary = "****************fD4fH3gL0hK7aI6"; // 数据分隔符
String lineEnd = System.getProperty("line.separator"); // The value is "\r\n" in Windows.
/*
* 上传图片内容,格式请参考HTTP 协议格式。
* 人人网Photos.upload中的”程序调用“http://wiki.dev.renren.com/wiki/Photos.upload#.E7.A8.8B.E5.BA.8F.E8.B0.83.E7.94.A8
* 对其格式解释的非常清晰。
* 格式如下所示:
* --****************fD4fH3hK7aI6
* Content-Disposition: form-data; name="upload_file"; filename="apple.jpg"
* Content-Type: image/jpeg
*
* 这儿是文件的内容,二进制流的形式
*/
private void addImageContent(byte[] image, DataOutputStream output) {
StringBuilder split = new StringBuilder();
split.append(twoHyphens + boundary + lineEnd);
split.append("Content-Disposition: form-data; name=\"signImage\"; filename=\"c:/signImage.jpg\"" + lineEnd);
split.append("Content-Type: image/jpeg" + lineEnd);
split.append(lineEnd);
try {
// 发送图片数据
output.writeBytes(split.toString());
output.write(image, 0, image.length);
output.writeBytes(lineEnd);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/*
* 构建表单字段内容,格式请参考HTTP 协议格式(用FireBug可以抓取到相关数据)。(以便上传表单相对应的参数值)
* 格式如下所示:
* --****************fD4fH3hK7aI6
* Content-Disposition: form-data; name="action"
* // 一空行,必须有
* upload
*/
private void addFormField(Set<Map.Entry<Object,Object>> params, DataOutputStream output) {
StringBuilder sb = new StringBuilder();
for(Map.Entry<Object, Object> param : params) {
sb.append(twoHyphens + boundary + lineEnd);
sb.append("Content-Disposition: form-data; name=\"" + param.getKey() + "\"" + lineEnd);
sb.append(lineEnd);
sb.append(param.getValue() + lineEnd);
}
try {
output.writeBytes(sb.toString());// 发送表单字段数据
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 直接通过 HTTP 协议提交数据到服务器,实现表单提交功能。
* @param actionUrl 上传路径
* @param params 请求参数key为参数名,value为参数值
* @param files 上传文件信息
* @return 返回请求结果
*/
public String post(String actionUrl, Set<Map.Entry<Object,Object>> params, byte[] files) {
HttpURLConnection conn = null;
DataOutputStream output = null;
BufferedReader input = null;
try {
URL url = new URL(actionUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(120000);
conn.setDoInput(true); // 允许输入
conn.setDoOutput(true); // 允许输出
conn.setUseCaches(false); // 不使用Cache
conn.setRequestMethod("POST");
conn.setRequestProperty("Connection", "keep-alive");
conn.setRequestProperty("Content-Type", multipart_form_data + "; boundary=" + boundary);
conn.connect();
output = new DataOutputStream(conn.getOutputStream());
addImageContent(files, output); // 添加图片内容
addFormField(params, output); // 添加表单字段内容
output.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);// 数据结束标志
output.flush();
int code = conn.getResponseCode();
if(code != 200) {
throw new RuntimeException("请求‘" + actionUrl +"’失败!");
}
input = new BufferedReader(new InputStreamReader(conn.getInputStream()));
StringBuilder response = new StringBuilder();
String oneLine;
while((oneLine = input.readLine()) != null) {
response.append(oneLine + lineEnd);
}
return response.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} finally {
// 统一释放资源
try {
if(output != null) {
output.close();
}
if(input != null) {
input.close();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
if(conn != null) {
conn.disconnect();
}
}
}
public static void main(String[] args) {
try {
String response = "";
BufferedReader in = new BufferedReader(new FileReader("config/actionUrl.properties"));
String actionUrl = in.readLine();
// 读取表单对应的字段名称及其值
Properties formDataParams = new Properties();
formDataParams.load(new FileInputStream(new File("config/formDataParams.properties")));
Set<Map.Entry<Object,Object>> params = formDataParams.entrySet();
byte[] files = null;
response = new UploadImage().post(actionUrl, params, files);
System.out.println("返回结果:" + response);
} catch (IOException e) {
e.printStackTrace();
}
}
}
分享到:
相关推荐
以下是一个简单的Android上传文件的示例代码片段: ```java public void uploadFile(String filePath) { HttpURLConnection connection = null; try { URL url = new URL("http://yourserver.com/upload"); ...
"android 文件上传含进度条"这个标题恰好揭示了我们要实现的功能:在Android应用中,既要能上传文件,又要能在上传过程中显示进度条,以提升用户体验。 首先,我们需要理解Android的文件操作机制。Android提供了...
以上就是Android设备上传文件到C# WebService的基本步骤和关键知识点。实际开发时,要根据项目需求进行相应的调整和优化。参考提供的链接(http://blog.sina.com.cn/s/blog_8d71d5140101fk8r.html),可以找到更具体...
在Android应用开发中,文件上传和文件选择器是常见的功能需求。用户可能需要从设备存储中选择一个或多个文件,例如图片、文档或音频文件,然后上传到服务器或进行其他操作。本文将深入探讨如何在Android平台上实现...
在Android平台上,文件上传是一项常见的任务,特别是在开发涉及用户数据交互的应用时,如社交媒体应用、云存储服务等。本教程将深入探讨如何在Android客户端实现文件及文件夹上传,并介绍服务器端的相关处理。附件中...
例如,使用Spring MVC的MultipartFile接口可以方便地处理上传文件。 在实际项目中,为了提高用户体验,我们通常会使用文件上传控件。这里提到的“android文件上传控件”可能是一个预封装好的UI组件,它提供了一套...
在标题"android大文件分段上传"中提到的方法,是通过使用Socket流将大文件分段进行上传,这是一种有效应对大文件传输问题的策略。下面我们将详细探讨这一技术。 首先,了解Socket的基本概念。Socket是网络编程中的...
在实际使用这个“Android端上传文件的jar包”时,开发者需要了解这些基本概念,并根据jar包提供的API文档或示例代码进行集成。这个预编译的库可能已经封装了上述复杂流程,让开发者只需简单调用几个方法即可完成文件...
Android上传文件工具类
在Android开发中,文件上传,特别是图片上传,是常见的需求之一。这涉及到用户选择本地文件,通常是图片,然后通过网络接口将这些文件发送到服务器。本文将深入探讨如何实现Android平台上的多文件和单文件上传,以及...
5. **文件上传**:使用FTPClient的storeFile方法上传文件。在上传过程中,可以监听数据传输进度,以便展示给用户。 ```java File selectedFile = new File("/sdcard/path/to/image.jpg"); FileInputStream fis = ...
- 对上传文件进行验证,限制可接受的文件类型和大小,防止恶意文件上传。 - 保护服务器免受DoS攻击,限制并发上传的数量。 - 为敏感数据加密,确保传输过程中数据的安全。 9. **性能优化**: - 使用断点续传或...
一般情况下,我们不能一次性加载整个大文件到内存,而是要采用流式处理(streaming)来分块读取和上传文件。 1. **分块上传**:大文件上传通常采用分块方式,即将大文件切分为多个小块,然后逐个上传。这样可以避免...
本文将详细讲解如何在Android中实现文件上传功能,主要围绕"android文件上传demo"这一主题,结合描述和标签,我们将讨论文件上传的基本原理、使用的技术以及示例代码。 首先,Android中的文件上传通常涉及网络操作...
2. 多线程上传:为了解决这个问题,开发者可以使用多线程同时上传文件的不同部分。这种方式可以显著缩短总体上传时间,特别是在网络环境不稳定或上传文件较大的情况下。 三、实现多线程上传 1. 使用AsyncTask:...
在Android开发中,断点上传是一项重要的功能,它允许用户在网络连接不稳定或者设备突然断电...以上就是关于“Android断点上传文件”的知识点介绍。通过理解这些概念和技术,开发者可以构建出高效、可靠的文件上传功能。
综上所述,Android上传大文件是一个涉及多步操作的过程,通过Socket实现高效传输,合理利用分块、编码、断点续传和进度显示等技术,可以确保大文件如200MB的`audioRecordTest`在3分钟内顺利上传到服务器。...
本篇将详细讲解如何在Android应用中使用Socket进行文件的上传和下载操作。 首先,理解Socket的基本概念:Socket是应用程序与网络协议之间的接口,它允许两个网络应用程序通过TCP/IP协议进行通信。在Android中,我们...
在Android平台上,将文件...以上就是Android上传文件到服务器的关键知识点,包括OkHttp的使用、Multipart上传、进度显示、错误处理、权限管理以及线程控制。实际开发中,还需要根据具体需求和服务器API进行调整和优化。
- 上传文件:调用`S3TransferUtility.upload()`方法,传入目标Bucket名称、对象键(Key)、本地文件路径。例如: ```java S3TransferUtility transferUtility = S3TransferUtility.create(this, s3Client); ...