在项目中遇到要将Android设备拍摄的照片上传的服务器,将文件保存在服务器本地的文件夹中,数据库中保存的是图片文件名。整个上传是将图片生成二进制流通过HTTP请求上传到服务端,服务端是基于.NET环境的,采用ashx一般处理程序处理服务返回结果。

  下面直接贴上代码,先是上传文件HTTP请求的静态方法:

 /**
* 通过上传文件流形式上传文件
* @param picPaths
* @param requestURL
* @return
*/
public static String uploadFile(String[] picPaths, String requestURL) {
String boundary = UUID.randomUUID().toString();
String prefix = "--", end = "\r\n";
String content_type = "multipart/form-data"; // 内容类型
String CHARSET = "utf-8"; // 设置编码
int TIME_OUT = 10 * 10000000; // 超时时间
try {
URL url = new URL(requestURL);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(TIME_OUT);
conn.setConnectTimeout(TIME_OUT);
conn.setDoInput(true); // 允许输入流
conn.setDoOutput(true); // 允许输出流
conn.setUseCaches(false); // 不允许使用缓存
conn.setRequestMethod("POST"); // 请求方式
conn.setRequestProperty("Charset", "utf-8"); // 设置编码
conn.setRequestProperty("connection", "keep-alive");
conn.setRequestProperty("Content-Type", content_type + ";boundary=" + boundary);
//当文件不为空,把文件包装并且上传
OutputStream outputSteam = conn.getOutputStream();
DataOutputStream dos = new DataOutputStream(outputSteam); StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(prefix);
stringBuffer.append(boundary);
stringBuffer.append(end);
dos.write(stringBuffer.toString().getBytes()); dos.writeBytes("Content-Disposition: form-data; name=\"" + author + "\"" + end);
dos.writeBytes(end);
dos.writeBytes("klose");
dos.writeBytes(end); for(int i = 0; i < picPaths.length; i++){
File file = new File(picPaths[i]);
StringBuffer sb = new StringBuffer();
sb.append(prefix);
sb.append(boundary);
sb.append(end);
sb.append("Content-Disposition: form-data; name=\"" + i + "\"; filename=\"" + file.getName() + end);
sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + end);
sb.append(end);
dos.write(sb.toString().getBytes()); InputStream is = new FileInputStream(file);
byte[] bytes = new byte[8192];//8k
int len = 0;
while ((len = is.read(bytes)) != -1) {
dos.write(bytes, 0, len);
}
is.close();
dos.write(end.getBytes());//一个文件结束标志
}
byte[] end_data = (prefix + boundary + prefix + end).getBytes();//结束 http 流
dos.write(end_data);
dos.flush(); //获取响应状态
int responseCode = conn.getResponseCode(); if (HttpURLConnection.HTTP_OK == responseCode) { //连接成功
//当正确响应时处理数据
StringBuffer buffer = new StringBuffer();
String readLine;
BufferedReader responseReader;
//处理响应流
responseReader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((readLine = responseReader.readLine()) != null) {
buffer.append(readLine).append("\n");
}
responseReader.close();
Log.d("HttpPOST", buffer.toString());
return "保存成功!";//成功
}
}catch (Exception e) {
e.printStackTrace();
}
return "保存失败!";
}

  二进制流报文格式如下所示:

 --b8690cde-dc7b-48cb-868a-f328b6355a3c
Content-Disposition: form-data; name="author" xxx
--b8690cde-dc7b-48cb-868a-f328b6355a3c
Content-Disposition: form-data; name=""; filename="xxxx.jpg"
Content-Type: application/octet-stream; charset=utf- (这里是二进制数据)
--b8690cde-dc7b-48cb-868a-f328b6355a3c--

  在.NET服务端接受二进制流的ashx程序代码如下所示:

 /// <summary>
/// Handler1 的摘要说明
/// </summary>
public class Handler1 : IHttpHandler
{
string rootPath = ConfigurationManager.AppSettings["FileDirectory"];
private IRepository _repository = new RepositoryImpl(); public void ProcessRequest(HttpContext context)
{ var request = context.Request;
returnUploadResult(request); } public string returnUploadResult(HttpRequest request)
{
var files = request.Files;
var formUpload = request.Files.Count > ; string resultStr = ""; if (formUpload)
{ for (int i = ; i < request.Files.Count; i++)
{
var formFilename = formUpload ? request.Files[i].FileName : null;
var upload = new FineUpload
{
Filename = formFilename,
InputStream = formUpload ? request.Files[i].InputStream : request.InputStream
};
string fileName = upload.Filename;
string fullFileName = Path.Combine(rootPath, fileName); if (System.IO.File.Exists(fullFileName))
{
XSBPHOTOURL template = new XSBPHOTOURL();
template.NAME = fileName.ToString();
template.IMGGUID = Guid.NewGuid().ToString();
_repository.Save<XSBPHOTOURL>(template);
resultStr += (fullFileName + "已存在。 ");
}
else
{
XSBPHOTOURL template = new XSBPHOTOURL();
template.NAME = fileName.ToString();
template.IMGGUID = Guid.NewGuid().ToString();
_repository.Save<XSBPHOTOURL>(template);
upload.SaveAs(fullFileName);
resultStr += (fullFileName + "保存成功。 ");
}
}
}
return resultStr; } public bool IsReusable
{
get
{
return false;
}
}
}

  服务端文件保存路径写在WebConfig中,在appSettings中添加一行代码就可以了,示例如下:

<appSettings>
<add key="FileDirectory" value="D:/UploadFiles"/>
</appSettings>

  这样就从Android客户端完成了文件上传功能,欢迎各位批评指正!

Android上传图片到服务器,服务端利用.NET WCFRest服务读取文件的解决方案的更多相关文章

  1. atitit.组件化事件化的编程模型--服务端控件(1)---------服务端控件与标签的关系

    atitit.组件化事件化的编程模型--服务端控件(1)---------服务端控件与标签的关系 1. 服务器控件是可被服务器理解的标签.有三种类型的服务器控件: 1 1.1. HTML 服务器控件  ...

  2. day112:MoFang:种植园使用websocket代替http&服务端基于flask-socketio提供服务&服务端响应信息&种植园页面显示初始化

    目录 1.种植园使用websocket代替http 2.服务端基于socket提供服务 3.服务端响应信息 4.种植园页面展示 1.种植园使用websocket代替http 我们需要完成的种植园,是一 ...

  3. 服务端使用Zookeeper注册服务地址,客户端从Zookeeper获取可用的服务地址。

    一个轻量级分布式RPC框架--NettyRpc - 阿凡卢 - 博客园 http://www.cnblogs.com/luxiaoxun/p/5272384.html 这个RPC框架使用的一些技术所解 ...

  4. Android 上传图片到服务器 okhttp一

    [目录] (一)上传图片到服务器一 ---------------------------------Android代码 (二)上传图片到服务器二--------------------------- ...

  5. Android 上传图片到服务器二--------调用相机7.0以上权限问题

    [目录] (一)上传图片到服务器一 ---------------------------------Android代码 (二)上传图片到服务器二--------------------------- ...

  6. mpush 服务端配置 for windows 服务自动运行

    mpush 服务端配置 以下安装部分是参照官方的步骤, 一.安装jdk1.8并配置环境变量 示例:  http://www.cnblogs.com/endv/p/6439860.html 二.Wind ...

  7. oracle服务端与客户端字符集不同导致中文乱码解决方案

    1.问题描述 用pl/sql登录时,会提示“数据库字符集(ZHS16GBK)和客户端字符集(2%)是不同的,字符集转化可能会造成不可预期的后果”,具体问题是中文乱码,如下图 2.问题分析 不管错误信息 ...

  8. MVC文件上传05-使用客户端jQuery-File-Upload插件和服务端Backload组件自定义上传文件夹

    在零配置情况下,文件的上传文件夹是根目录下的Files文件夹,如何自定义文件的上传文件夹呢? MVC文件上传相关兄弟篇: MVC文件上传01-使用jquery异步上传并客户端验证类型和大小  MVC文 ...

  9. java Socket Tcp示例三则(服务端处理数据、上传文件)

    示例一: package cn.itcast.net.p5.tcptest; import java.io.BufferedReader;import java.io.IOException;impo ...

随机推荐

  1. MySql单表最大8000W+ 之数据库遇瓶颈记

    前言 昨晚救火到两三点,早上七点多醒来,朦胧中醒来发现电脑还开着,赶紧爬起来看昨晚执行的SQL命令结果.由于昨晚升级了阿里云的RDS,等了将近两个小时 还在 升降级中,早上阿里云那边回复升级过程中出现 ...

  2. 3,Spring Boot热部署

    问题的提出: 在编写代码的时候,你会发现我们只是简单把打印信息改变了,就需要重新部署,如果是这样的编码方式,那么我们估计一天下来就真的是打几个Hello World就下班了.那么如何解决热部署的问题呢 ...

  3. 关于delete使用limit的一些注意事项

    在使用delete删除记录时,如果表里面存在多条相同的记录,但是此刻你只想删除一条记录,那么limit就派上了用场.但是使用limit的时候得注意: 如图,您如果想着删除第一个名字叫做张三的,如果你这 ...

  4. 线程池与Threadlocal

    线程池与Threadlocal 线程池: 线程池是为了使线程能够得到循环的利用,线程池里面养着一些线程,有任务需要使用线程的时候就往线程池里抓线程对象出来使用.线程池里的线程能够重复使用,所以在资源上 ...

  5. android6.0动态权限处理<一>

    android 6.0以上为了保护用户的隐私,和以往被人诟病的权限机制,确立了新的权限机制.从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授 ...

  6. Abp(.NetCore)开发与发布过程

    .NetCore 项目开发正当火热,ABP也推出了.NetCore的版本.趁此机会学习.NetCore的开发与发布过程.以下是本人的踩坑经验. 在ABP官网提供单页面应用开发框架(AngularJs) ...

  7. NOIP模拟:能源(二分答案)

    题目描述 小美为了拯救世界能源危机,她准备了 n 台蓄电池.一开始每台蓄电池有 ai 个单位的能量. 现在她想把 n 台蓄电池调整到能量相同.对于每台蓄电池可以给另一台蓄电池传递能量.但是会有能量损耗 ...

  8. python基础(9):文件处理

    很多软件都会有有对文件处理的功能.今天我们就来学习文件处理. 文件处理 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,可以将结果赋值给一个变量,这个变量我们称为句柄.这样我们就可以通过这个 ...

  9. 全面理解SSD和NAND Flash

    Flash Memory又叫做闪存,是一种非易失性存储器.非易失性是指断电之后数据不会丢失,这里就涉及到断电保护(后面详细讲解). 总体思路 1.NAND Flash的用途. 2.NAND Flash ...

  10. 决策树(C4.5)原理

    决策树c4.5算法是在决策树ID3上面演变而来. 在ID3中: 信息增益 按属性A划分数据集S的信息增益Gain(S,A)为样本集S的熵减去按属性A划分S后的样本子集的熵,即 在此基础上,C4.5计算 ...