在项目中遇到要将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. 关于Calendar中设置月份比实际小1的问题

    有如下程序,转化两个字符串数字为date类型,并判断是历史上的星期几,是否同为星期一 代码如下: public static void main(String[] args) throws Parse ...

  2. HashMap源码浅析(jdk1.8)

    HashMap是以key-value键值对的形式进行存储数据的,数据结构是以数组+链表或红黑树实现. 数据结构图如下: 一.关键属性 HashMap初始化和方法使用的属性. /** * 默认初始容量1 ...

  3. 关于Lumen / Laravel .env 文件中的环境变量是如何生效的

    .env 文件包含默认环境变量,我们还可自定义其他任何有效的变量,并可通过  调用 env() 或 $_SERVER 或 $_ENV  来获取该变量.那么env()是如何加载到这些变量的呢?在Lume ...

  4. EventBus 事件总线之我的理解

    用例:假设公司发布了一个公告 需要通过短信 和 邮件分别2种方式 通知员工 1:首先我们建立领域模型 /// <summary> /// 领域核心基类 /// </summary&g ...

  5. CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu?

    CJOJ 2485 UVa 11991 生日礼物 / UVa 11991 Easy Problem from Rujia Liu? Description (原题来自刘汝佳<训练指南>Pa ...

  6. STL—list

    前面我们分析了vector,这篇介绍STL中另一个重要的容器list list的设计 list由三部分构成:list节点.list迭代器.list本身 list节点 list是一个双向链表,所以其li ...

  7. (转)sql通配符

    背景:一次搞清sql查询中的通配符问题. 1 sql通配符 通配符主要以下几种:%._.[].[^] . 在搜索数据库中的数据时,SQL 通配符可以替代一个或多个字符.SQL 通配符必须与 LIKE ...

  8. 【HTML】html5新属性-datalist

    摘要: 为实现输入域自动填充的效果 方法一: jquery-ui的autocomplete方法, 不是jquery 自带的方法. 方法二: 采用html5新特性,datalist,例子如下:坏处很明显 ...

  9. iOS项目冗余资源扫描脚本

    iOS项目冗余资源扫描脚本 随着iOS项目的版本不断迭代,app中冗余文件会越来越多,app size也持续增加,是时候需要对app冗余资源进行检测,对app进行瘦身. 使用方法: 1. 运行环境为m ...

  10. 权限管理学习 一、ASP.NET Forms身份认证

    说明:本文示例使用的VS2017和MVC5. 系统无论大小.牛逼或屌丝,一般都离不开注册.登录.那么接下来我们就来分析下用户身份认证. 简单实现登录.注销 以前在学习.net的时候不知道什么Forms ...