在项目中遇到要将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. Python学习笔记——import模块

    OS模块 直接输出系统命令到屏幕,该方法获取的命令返回值不可被赋值给变量,输出结果受编码影响会乱码: import os os.system("ipconfig") 将执行获取的系 ...

  2. MongoDB数据库文档操作

    前面的话 本文将详细介绍MongoDB数据库关于文档的增删改查 数据类型 在介绍文档操作之前,首先要了解MongoDB的数据类型 MongoDB支持许多数据类型,包括 1.字符串 - 这是用于存储数据 ...

  3. JVM学习(1)——通过实例总结Java虚拟机的运行机制-转载http://www.cnblogs.com/kubixuesheng/p/5199200.html

    JVM系类的文章全部转载自:http://www.cnblogs.com/kubixuesheng/p/5199200.html 特别在此声明.那位博主写的真的很好 ,感谢!! 俗话说,自己写的代码, ...

  4. IDEA的热部署插件jrebel6.4.3离线安装版配置与破解

    JRebel 介绍 IDEA上原生是不支持热部署的,一般更新了 Java 文件后要手动重启 Tomcat 服务器,才能生效,浪费不少生命啊.目前对于idea热部署最好的解决方案就是安装JRebel插件 ...

  5. Python怎么样入门?Python基础入门教程

    给大家整理的这套python学习路线图,按照此教程一步步的学习来,肯定会对python有更深刻的认识.或许可以喜欢上python这个易学,精简,开源的语言.此套教程,不但有视频教程,还有源码分享,让大 ...

  6. JavaScript 值类型和引用类型的初次研究

    今天遇到一个坑,具体的不多说,直接上代码 var a = [ [],[],[1,2,3] ] var b = ['颜色','大小','尺寸'] var arr = [] for(let i = 0; ...

  7. BestCoder Round #92 (hdu_6015 6016)

    比赛链接 A题主要是map的使用,比赛的时候问了下队友,下次要记住了 #include<bits/stdc++.h> using namespace std; typedef long l ...

  8. static关键字,引发的spring普通类获取spring的bean的思考

    在c++和java中static关键字用于修饰静态成员变量和成员函数 举例一个普通的javabean class AA { int a; static int b; geta/seta;//此处省略g ...

  9. ARM开发(2)基于STM32的蜂鸣器

    基于STM32的蜂鸣器 一 蜂鸣器原理:  1.1 本实验实现1个蜂鸣器间隔1S鸣叫.  1.2 实验思路:根据电路图原理,给蜂鸣器相关引脚赋予高低电平,实现电路的导通,使蜂鸣器实现鸣叫或不鸣.  1 ...

  10. TensorFlow conv2d实现卷积

    tf.nn.conv2d是TensorFlow里面实现卷积的函数,参考文档对它的介绍并不是很详细,实际上这是搭建卷积神经网络比较核心的一个方法,非常重要 tf.nn.conv2d(input, fil ...