利用HTTP协议实现Android文件上传至WEB服务器,采用PHP接收文件(参考网上自己实现)
2015-01-08 16:17
1031 查看
最近在做Android手机端的上传和下载功能。 上传文件的时候遇到了很大的麻烦,因为开始对网络编程这块十分不熟悉,加上对WEB服务器端也是一点不懂,搞了快一个星期才勉强实现,下面记录一下自己的过程:其中参考了网络编程的书籍,我本来是要对一个受保护的服务器进行上传文件,即需要输入帐号密码才可以成功上传文件,基于基础差,先做一个不用账户密码的,接下来再去实现可以访问受保护的服务器的功能。
1、首先搭建服务器端,朋友推荐我用了一款phpstudy集成的服务器环境搭建工具,确实非常好用。不用懂太多的PHP端,首先在phpstudy目录下的WWW目录下创建一个HTML文件,简单的写一个可以实现上传功能的界面,即一个选择文件框,还有一个上传的文件按钮,具体代码如下:
添加的代码就是图上标记为红色的部分,在<body>里边添加。说明一下,这个<form>标签用于为用户输入创建HTML表单。
<input type = "file"/>标签在被浏览器解析后会产生一个文本框和一个“浏览”按钮。单击浏览会弹出系统的文件选择框:如下图:
HTML中的form标签属性如下图:
图片来源与书上。
代码中的action=“upload_file.php”表示文件提交的时候会执行upload_file.php中的代码,这个文件主要实现对上传文件进行检查、复制等处理,代码如下:
创建一个PHP文件,也放在WWW目录下:
echo "Strore in:"."upload/".$_FILES["file1"]["name"]; //}}}else {echo "Invalid file1"; //文件超过20000字节则提示出错。}?></body></html>
还是红色代码为写的PHP代码。这个代码主要采用$_FILES这个全局变量,这个 全局变量会获取上传文件的消息,并用此变量来进行操作,例如检查文件大小、位置、是否存在等。具体解释见以上代码。
至此我们的服务端的环境搭好了就,我们可以运行一下(首先在WWW目录下建立一个upload文件夹 这个也是跟上边的PHP里边的upload路径对应)。http://localhost/up.html 这个时候就会弹出选择文件上传的提示框,然后选文件上传就之后提示成功,就可以在WWW下的upload里查看上传文件,因为在php.ini配置文件中对上传文件大小做了控制,想要上传大文件的话可以在php.ini里边设置2个属性的大小:post_max_size upload_max_filesize
把这两个属性设置好就可以了。
接下来就是安卓端代码的编写,这个代码也困扰了我好久,因为是看书上的例子,总也不能上传成功,后来发现是书上的列子传递参数好像传递错了,我改了一下就可以了。
代码如下:
首先是负责上传的工具类 httppost.java
代码具体解释看下注释吧,我出错的地方就是在 传递这句代码的时候出错的:sb1.append("Content-Disposition: form-data;name=\"file1\"; filename=" + FileName + LINEND);基于HTTP协议发送这个HTTP头,要有正确的格式,注意一下就好,要能够给filename一个正确的名字。这个filename是服务器端需要的参数,服务端通过这个参数值获得文件的名字。
接下来是Activity代码:
这个代码比较简单就是定义了一个按钮点击上传即可。
1、首先搭建服务器端,朋友推荐我用了一款phpstudy集成的服务器环境搭建工具,确实非常好用。不用懂太多的PHP端,首先在phpstudy目录下的WWW目录下创建一个HTML文件,简单的写一个可以实现上传功能的界面,即一个选择文件框,还有一个上传的文件按钮,具体代码如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>无标题文档</title> </head> <body> <span style="color:#ff0000;"><form action="upload_file.php" method="post" enctype="multipart/form-data"> <label for="file">文件名:</label> <input type="file" name="file1" id="file" /> <br/> <input type="submit" name="submit" value="提交" /> </form></span> </body> </html>
添加的代码就是图上标记为红色的部分,在<body>里边添加。说明一下,这个<form>标签用于为用户输入创建HTML表单。
<input type = "file"/>标签在被浏览器解析后会产生一个文本框和一个“浏览”按钮。单击浏览会弹出系统的文件选择框:如下图:
HTML中的form标签属性如下图:
图片来源与书上。
代码中的action=“upload_file.php”表示文件提交的时候会执行upload_file.php中的代码,这个文件主要实现对上传文件进行检查、复制等处理,代码如下:
创建一个PHP文件,也放在WWW目录下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>无标题文档</title> </head> <body> <span style="color:#ff0000;"><?php if($_FILES["file1"]["size"]<20000) //文件大小控制在20000字节内,超出则不接受,这个可以自己改。 { if($_FILES["file1"]["error"]>0) //上传文件的错误代码,如果返回了错位代码可以对照错误信息进行修正 { echo "Return Code:".$_FILES["file1"]["error"]."<br />"; } else { echo "Upload: ".$_FILES["file1"]["name"]."<br />"; //显示文件的名字,类型,大小,临时存放文件的路径 echo "Type: ".$_FILES["file1"]["type"]."<br />"; echo "Size: ".($_FILES["file1"]["size"]/1024)."kb<br />"; echo "Temp file1:".$_FILES["file1"]["tmp_name"]."<br />"; if(file_exists("./upload/".$_FILES["file1"]["name"])) //检测文件是否存在于upload目录下(这个目录是用来存放上传文件的目录,也是建立<span style="white-space:pre"> </span>在WWW目录下的),如果存在则返回提示。 { echo $_FILES["file1"]["name"]."already existst!"; } else {</span>
<span style="color:#ff0000;"></span><pre name="code" class="php" style="color: rgb(255, 0, 0); ">//调用了一个PHP函数move_uploaded_file,把临时文件存放到我们制定的目录,并且改成我们上传时候的文件的名字。move_uploaded_file($_FILES["file1"]["tmp_name"],"upload/".$_FILES["file1"]["name"]);
echo "Strore in:"."upload/".$_FILES["file1"]["name"]; //}}}else {echo "Invalid file1"; //文件超过20000字节则提示出错。}?></body></html>
还是红色代码为写的PHP代码。这个代码主要采用$_FILES这个全局变量,这个 全局变量会获取上传文件的消息,并用此变量来进行操作,例如检查文件大小、位置、是否存在等。具体解释见以上代码。
至此我们的服务端的环境搭好了就,我们可以运行一下(首先在WWW目录下建立一个upload文件夹 这个也是跟上边的PHP里边的upload路径对应)。http://localhost/up.html 这个时候就会弹出选择文件上传的提示框,然后选文件上传就之后提示成功,就可以在WWW下的upload里查看上传文件,因为在php.ini配置文件中对上传文件大小做了控制,想要上传大文件的话可以在php.ini里边设置2个属性的大小:post_max_size upload_max_filesize
把这两个属性设置好就可以了。
接下来就是安卓端代码的编写,这个代码也困扰了我好久,因为是看书上的例子,总也不能上传成功,后来发现是书上的列子传递参数好像传递错了,我改了一下就可以了。
代码如下:
首先是负责上传的工具类 httppost.java
package com.example.uploadfile; import java.io.DataOutputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import android.util.Log; public class httppost { public static String post(String actionurl,String FileName) throws IOException // 静态方法,直接在另外的类里可以调用 { String BOUNDARY = java.util.UUID.randomUUID().toString(); //调用一个函数随机生成一个字符串作为分割线 String PREFIX = "--",LINEND = "\r\n"; String MULTIPART_FORM_DATA = "multipart/form-data"; //表单数据常量化 String CHARSET = "UTF-8"; <span style="white-space:pre"> </span>//字符编码 URL url = new URL(actionurl); HttpURLConnection conn = (HttpURLConnection)url.openConnection();//建立HTTP连接 conn.setReadTimeout(5*1000); <span style="white-space:pre"> </span>//设置从主机读取数据超时时间 单位:毫秒 conn.setDoInput(true);<span style="white-space:pre"> </span>//设置允许输入 conn.setDoOutput(true);<span style="white-space:pre"> </span>//设置允许输出 conn.setUseCaches(false);<span style="white-space:pre"> </span>//设置不使用缓存 conn.setRequestMethod("POST"); // 设置为POST发送方法 conn.setRequestProperty("Connection", "Keep-Alive");//设置维持长连接 conn.setRequestProperty("Charsert", "UTF-8");//设置文件字符集为UTF-8 conn.setRequestProperty("Content-Type", MULTIPART_FORM_DATA //设置文件类型 + ";boundary=" + BOUNDARY);
<span style="white-space:pre"> </span>//创建一个新的数据输出流,将数据写入指定的基础输出流 DataOutputStream outstream = new DataOutputStream(conn.getOutputStream()); if(FileName!="") //发送文件数据 {
<span style="white-space:pre"> </span>//定义StringBuilder对象构建发送字符串数据 StringBuilder sb1 = new StringBuilder(); sb1.append(PREFIX); sb1.append(BOUNDARY); sb1.append(LINEND); sb1.append("Content-Disposition: form-data;name=\"file1\"; filename=" + FileName + LINEND); sb1.append("Content-Type: application/octet-stream; charset="+ CHARSET + LINEND); sb1.append(LINEND); //写入输出流中 outstream.write(sb1.toString().getBytes()); //将文件读到输入流中 InputStream is = new FileInputStream(FileName); byte[] buffer = new byte[1024]; int len = 0;
<span style="white-space:pre"> </span>//写入输出流中<span style="white-space:pre"> </span> while((len=is.read(buffer))!=-1) { System.out.println(len); Log.v("len","keb"); outstream.write(buffer,0,len); } is.close();//关闭输入流
<span style="white-space:pre"> </span>//添加换行标志 outstream.write(LINEND.getBytes()); } //请求结束标志 byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINEND).getBytes();
outstream.write(end_data);
<span style="white-space:pre"> </span>//刷新,发送数据 outstream.flush();
<span style="white-space:pre"> </span>//得到响应码 int res = conn.getResponseCode(); InputStream in = null;
<span style="white-space:pre"> </span>//上传成功返回相应码200 if(res == 200) { Log.v("res","200"); in = conn.getInputStream(); int ch; StringBuilder sb2 = new StringBuilder(); while((ch=in.read())!=-1) { sb2.append((char)ch); } } return in==null?null:in.toString(); } }
代码具体解释看下注释吧,我出错的地方就是在 传递这句代码的时候出错的:sb1.append("Content-Disposition: form-data;name=\"file1\"; filename=" + FileName + LINEND);基于HTTP协议发送这个HTTP头,要有正确的格式,注意一下就好,要能够给filename一个正确的名字。这个filename是服务器端需要的参数,服务端通过这个参数值获得文件的名字。
接下来是Activity代码:
package com.example.uploadfile; import java.io.IOException; import java.util.HashMap; import java.util.Map; import com.example.filechooser.CallbackBundle; import com.example.filechooser.OpenFileDialog; import com.example.uploadfile.R; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.app.Dialog; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity { public String url = "http://172.20.150.23/upload_file.php"; public static Dialog dialog; public String uploadfilepath; public String uploadfilename; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn =(Button)findViewById(R.id.btn1); btn.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub new Thread(runnable).start(); } }); } Runnable runnable = new Runnable() { public void run() { String filename = uploadfilepath;//uploadfilepath是自己指定的上传文件的路径和名字 try { Log.v("path",filename); String res=httppost.post(url,filename); Log.v("httres",res); } catch (IOException e) { // TODO Auto-generated catch block Log.v("tag","error!"); e.printStackTrace(); } } }; } }
这个代码比较简单就是定义了一个按钮点击上传即可。
相关文章推荐
- android上传文件和参数到web服务器,php接收并保存
- Android上传文件到Web服务器,PHP接收文件
- Android上传文件到Web服务器,PHP接收文件(一)
- [置顶] Android上传文件到Web服务器,PHP接收文件(二)
- 服务器基于PHP CodeIgniter,Android基于Volley实现多文件/图片上传(含服务器,web版和android客户端完整代码)
- [置顶] Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(2)
- Android上传文件到Web服务器 PHP接收文件
- Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(二)
- Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件
- Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(二)
- [置顶] Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(一)
- Android上传文件到Web服务器,PHP接收文件(二)
- Android上传文件到Web服务器,PHP接收文件
- android原生POST、httpClient4.X实现向PHP服务器上传文件
- Android端通过Okhttp与PHP服务器进行交互并实现文件上传下载(一)