昨天,(在我的上一篇博客中)写了通过浏览器上传图片到服务器(php),今天将这个功能付诸实践.(还完善了服务端的代码)

不试不知道,原来通过android 向服务端发送图片还真是挺麻烦的一件事.

上传代码:

/* 上传文件至Server的方法 */
private void uploadFile()
{
String end = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
try
{
URL url = new URL(postUrl);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
/* Output to the connection. Default is false,
set to true because post method must write something to the connection */
con.setDoOutput(true);
/* Read from the connection. Default is true.*/
con.setDoInput(true);
/* Post cannot use caches */
con.setUseCaches(false);
/* Set the post method. Default is GET*/
con.setRequestMethod("POST");
/* 设置请求属性 */
con.setRequestProperty("Connection", "Keep-Alive");
con.setRequestProperty("Charset", "UTF-8");
con.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
/*设置StrictMode 否则HTTPURLConnection连接失败,因为这是在主进程中进行网络连接*/
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());
/* 设置DataOutputStream,getOutputStream中默认调用connect()*/
DataOutputStream ds = new DataOutputStream(con.getOutputStream()); //output to the connection
ds.writeBytes(twoHyphens + boundary + end);
ds.writeBytes("Content-Disposition: form-data; " +
"name=\"file\";filename=\"" +
fileName + "\"" + end);
ds.writeBytes(end);
/* 取得文件的FileInputStream */
FileInputStream fStream = new FileInputStream(uploadFile);
/* 设置每次写入8192bytes */
int bufferSize = 8192;
byte[] buffer = new byte[bufferSize]; //8k
int length = -1;
/* 从文件读取数据至缓冲区 */
while ((length = fStream.read(buffer)) != -1)
{
/* 将资料写入DataOutputStream中 */
ds.write(buffer, 0, length);
}
ds.writeBytes(end);
ds.writeBytes(twoHyphens + boundary + twoHyphens + end);
/* 关闭流,写入的东西自动生成Http正文*/
fStream.close();
/* 关闭DataOutputStream */
ds.close();
/* 从返回的输入流读取响应信息 */
InputStream is = con.getInputStream(); //input from the connection 正式建立HTTP连接
int ch;
StringBuffer b = new StringBuffer();
while ((ch = is.read()) != -1)
{
b.append((char) ch);
}
/* 显示网页响应内容 */
// Toast.makeText(MainActivity.this, b.toString().trim(), Toast.LENGTH_SHORT).show();//Post成功
System.out.println(b.toString());
} catch (Exception e)
{
/* 显示异常信息 */
// Toast.makeText(MainActivity.this, "Fail:" + e, Toast.LENGTH_SHORT).show();//Post失败
System.out.println(e);
}
}

上篇博文有说上传图片必须使用POST方法,这里当然使用的就是post方法.这里上传跟普通上传写法没啥变化.

不过我还是不习惯使用这个方法(我一直使用volley框架, 有兴趣可以百度一下.一个官方推出的很好用的框架,要不是需要用到传图我还不会研究这个写法)

使用原生POST方法的基本步骤:

  1.使用 HttpURLConnection 建立连接

  2.设置请求属性

  3.根据请求格式组装参数(很麻烦 , 可以通过浏览器发送POST请求,取出调试信息对比)

  4.建立输入流,并写入数据(FileInputStream 和下面循环写入哪里)

  5.获取返回流,并处理返回参数

  6.关闭所有流

该部分代码几乎完全借鉴大神的写法.里面注释也很多我也不多说了.

值得一提的是在4.0(android 版本)以后就已经不支持在主线程中执行上传,下载等耗时操作了.

这也很合理,假如你在上传文件的时候,突然你的网络不好,你就会一直在上传状态.体验很不好.

所以调用上面的方法需要新建一个线程:

 new Thread(new Runnable() {
@Override
public void run() {
uploadFile();
}
}).start();

这个调用方法是在上传方法与该方法同文件时可以这样写,如果上传方法在独立的class文件中需要先实例化然后通过

实例化对象名.uploadFile();

的方法调用.

服务器端

  上篇博文里面只是简单的实现了,接收并转存图片.这里对该服务端进行完善:

<?php
/**
* 接收上传的图片
*
* ------------
* 200 ok
* 401 Error method
* 500 Internal error
* ------------
*/
// ini_set("display_errors", "On");
// error_reporting(E_ALL | E_STRICT);
header('Access-Control-Allow-Origin: *'); // 解决前段javascript跨域请求 $fileInfo = $_FILES['file'];
$maxSize=2097152;//允许的最大值 $allowExt=array('jpeg','jpg','png','gif','wbmp');
$flag=true;//检测是否为真实图片类型 if($fileInfo['error']==0){
//判断上传文件的大小 if($fileInfo['size']>$maxSize){
$data = '上传文件过大'; return Response::show(201,'error1', $data); exit();
}
//$ext=strtolower(end(explode('.',$fileInfo['name'])));获取后缀 $ext=pathinfo($fileInfo['name'],PATHINFO_EXTENSION);
if(!in_array($ext,$allowExt)){ $data = '非法文件类型'; return Response::show(202 , 'error2' , $data); exit(); }
//判断文件是否是通过HTTP POST方式上传来的 if(!is_uploaded_file($fileInfo['tmp_name'])){ $data = '文件不是通过HTTP POST方式上传来的'; return Response::show(203 , 'error3' , $data); exit();
}
//检测是否为真实的图片类型 if($flag){
if(!getimagesize($fileInfo['tmp_name'])){ $data = '不是真正图片类型'; return Response::show(204 , 'error4' , $data); exit(); }
} //创建与id对应的文件夹 $id = $_GET['id'];
if(!file_exists($id)){
mkdir('../files/'.$id);
//chmod($id , 0777);
} if(@move_uploaded_file($fileInfo['tmp_name'],'../files/'.$id.'/'.$fileInfo['name'])){
$data = '文件上传成功'; return Response::show(200 , 'ok' , $data); }else{
$data = '文件上传失败'; return Response::show(404 , 'error5' , $data);
}
}else{
switch($fileinfo['error']){
case 1:
$data = '上传文件超过了PHP配置文件中upload_max_filesize选项的值'; return Response::show(401 , 'error5' , $data); break; case 2: $data = '超过了表单MAX_FILE_SIZE限制的大小'; return Response::show(402 , 'error5' , $data); break;
case 3: $data = '文件部分被上传'; return Response::show(403 , 'error5' , $data); break;
case 4: $data = '没有选择上传文件'; return Response::show(405 , 'error5' , $data); break;
case 6: $data = '没有找到临时目录'; return Response::show(405 , 'error5' , $data); break;
case 7:
case 8: $data = '系统错误'; return Response::show(405 , 'error5' , $data); break;
}
}

这里对图片进行了各种检测.比昨天的更可靠了是吧.还统一了返回的json格式方便客户端进行解析.(还有就是,上面的服务端的代码也是借鉴了慕课大神的写法,略作修改)

通过android 客户端上传图片到服务器的更多相关文章

  1. Java乔晓松-android中上传图片到服务器Tomcat(Struts2)

    在做android开发的时候,有时你会用到图片的上传功能,在我的android项目中,我是选中图片,点击上传多张图片 android客户端上传图片部分的代码如下: package com.exampl ...

  2. Android 客户端 okhttp3 与服务器之间的双向验证

    [原文]https://blog.csdn.net/leng_wen_rou/article/details/58596142 本篇是Android 客户端基于okhttp3的网络框架 和后台服务器之 ...

  3. iphone客户端上传图片到服务器

    本文转载至 http://blog.sina.com.cn/s/blog_4c70701801012inq.html       如上采用asihttprequest类中的post方式上传就行.大致思 ...

  4. android 上传图片到服务器Tomcat(Struts2)

    在做android开发的时候,有时你会用到图片的上传功能,在我的android项目中,我是选中图片,点击上传多张图片 android客户端上传图片部分的代码如下: package com.exampl ...

  5. SSH服务器与Android通信(3)--Android客户端发送数据

    Android客户端向SSH服务器发送数据主要有三种情况:通过客户端删除数据.添加数据和修改数据. 1.删除数据 先看看jsp文件里面是怎样删除数据的: <td align="cent ...

  6. Android客户端OkHttp的使用以及tomcat服务器的解析客户端发过来的数据

    2020-02-15 21:25:42 ### android客户端客户向服务器发送json字符串或者以参数请求的方式发送数据 其中又分为post请求和get请求 1.activity.xml < ...

  7. Android客户端与Python服务器端通信之上传图片

    继上篇成功的与服务器端通信上之后,我现在需要将安卓本地的图片上传到服务端.服务端接收图片存下来. 参考:https://blog.csdn.net/qq_26906345/article/detail ...

  8. SSH服务器与Android通信(2)--Android客户端接收数据

    基本原理是Android客户端通过HttpClient向服务器发出请求,服务器向Android客户端返回JSON字符串,Android客户端解析JSON字符串获得数据. 1. 新建一个Android项 ...

  9. Android客户端与服务器

    就是普通的服务器端编程,还不用写界面,其实还比服务器编程简单一些.跟J2EE一样的服务器,你android这一方面只要用json或者gson直接拿数据,后台的话用tomcat接受请求操作数据,功能不复 ...

随机推荐

  1. C# RGB和HSB相互转换

    背景 最近做的项目中有这样一个场景,设置任意一种颜色,得到这种颜色偏深和偏浅的两种颜色.也就是说取该颜色同色系的深浅两种颜色.首先想到的是调节透明度,但效果不理想.后来尝试调节颜色亮度,发现这才是正解 ...

  2. UVa11549计算器谜题[floyd判圈]

    题意: 有个老式计算器,每次只能记住一个数字的前n位.现在输入一个整数k,然后反复平方,一直做下去,能得到的最大数是多少.例如,n=1,k=6,那么一次显示:6,3,9,1... 白书上的题 set, ...

  3. 升级Flash Builder 4.6中的Flash Player版本

    测试有效 本人按此方法升级到了flash player 15 Adobe自发布Flash Builder 4.6后,就暂停了Flash Builder新版本的发布.但AIR和FlashPlayer版本 ...

  4. css相关问题

    display:none和visibility:hidden的区别? 前几天遇到的这个问题,表格布局:::::display:none 隐藏对应的元素,在文档布局中不再给它分配空间,它各边的元素会合拢 ...

  5. Centos5.8 iptables管理

    使用第三方提供的Centos5.8 vmx安装的虚拟机实例, 在安装Tomcat时发现启动后8080端口无法访问, 先检查是否selinux作了限制 查看selinux状态: sestatus 查看s ...

  6. BZOJ 1191 【HNOI2006】 超级英雄Hero

    Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目,只有当选手正确回 ...

  7. POJ 3714 Raid

    Description After successive failures in the battles against the Union, the Empire retreated to its ...

  8. IIS中ASP.NET安全配置

    1.禁止web中的DELETE.OPTIONS.PUT.HEAD和TRACE HTTP方法 请求方法是请求一定的Web页面的程序或用于特定的URL.可选用下列几种:GET: 请求指定的页面信息,并返回 ...

  9. js 随笔

    setInterval:即使在方法中使用了stopInterval这个方法也要执行完才会停止自行重复执行,解决:使用return false来跳出方法. JS string和num:当一个是字符串数字 ...

  10. weblogic下部署应用时slf4j与logbak冲突的解决办法

    今天在weblogic上部署一个使用logback的应用时,报错如下: java.lang.IllegalArgumentException: Invalid 'logbackConfigLocati ...