node.js+android(使用HttpURLConnection和HttpClient)实现文件上传
来源:互联网 发布:魔兽争霸3画面优化 编辑:程序博客网 时间:2024/04/28 00:05
上一篇node.js 第三方模块如何安装(使用npm)及介绍 了formidable的安装,这一篇结合android写一个文件上传的例子。
先上服务端node.js 的代码,保存为upload.js
var http = require('http');var fs = require('fs');var formidable = require('formidable');var firstPage = function(res){res.writeHead(200, {'Content-Type': 'text/html'});var html = fs.readFileSync(__dirname + '/public/form.html');res.end(html);}var resultPage = function(res,data,files){ res.setHeader('Content-Type', 'text/html'); res.write('<p>thanks ' + data.name + '</p>'); res.write('<ul>');console.log(data);console.log(files); if (Array.isArray(files.images)) { files.images.forEach(function(image){ var kb = image.size / 1024 | 0; res.write('<li>uploaded ' + image.name + ' ' + kb + 'kb</li>'); }); } else { var image = files.images; var kb = image.size / 1024 | 0; res.write('<li>uploaded ' + image.name + ' ' + kb + 'kb</li>'); } res.end('</ul>');}var server = http.createServer(function(req, res) {if (req.method == 'GET'){return firstPage(res);}var form = new formidable.IncomingForm; var data = {}; var files = {}; form.uploadDir = __dirname +'/file';form.keepExtensions = true;function ondata(name, val, data){if (Array.isArray(data[name])) {//数组data[name].push(val);} else if (data[name]) {//同keydata[name] = [data[name], val];} else {//第一次data[name] = val;}}form.on('field', function(name, val){ondata(name, val, data);});form.on('file', function(name, val){ondata(name, val, files);}); form.on('end', function() {resultPage(res,data,files);}); form.parse(req);});server.listen(8080);console.log('listening on http://localhost:8080');__dirname + '/public/form.html,在js当前目录下建立public文件夹,文件夹下建立form.html文件,文件内容如下
<html><body><form action="/" method="post" enctype="multipart/form-data"> <input type="text" name="name" placeholder="Name:" /> <input type="file" name="images" multiple="multiple" /> <input type="submit" value="Upload" /></form></body></html>
代码比较简单,formidable部分可以上官网https://github.com/felixge/node-formidable看API。
运行以下看看
在浏览器中打开http://localhost:8080
选择文件,输入文件name
点击upload
后台截图
文件上传成功
再看android代码,布局文件main.xml如下
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/RelativeLayout1" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/textViewInfo" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true"/> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_below="@+id/textViewInfo" android:layout_marginLeft="40dp" android:layout_marginTop="20dp" android:text="文件路径" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textViewFile" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView1" android:layout_below="@+id/textView1"/> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textViewFile" android:layout_below="@+id/textViewFile" android:layout_marginTop="10dp" android:text="上传网址" android:textAppearance="?android:attr/textAppearanceMedium" /> <TextView android:id="@+id/textViewUrl" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@+id/textView3" android:layout_below="@+id/textView3"/><WebView android:id="@+id/webViewResult" android:layout_width="fill_parent" android:layout_height="100dp" android:layout_below="@+id/textViewUrl" android:layout_marginTop="30dp"/> <Button android:id="@+id/buttonJava" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_marginLeft="60dp" android:text="Java上传" /> <Button android:id="@+id/buttonApache" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignBottom="@+id/buttonJava" android:layout_toRightOf="@+id/buttonJava" android:text="Apache上传" /></RelativeLayout>主程序代码如下
package com.zhang.test08_11;import java.io.BufferedInputStream;import java.io.BufferedOutputStream;import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.UnsupportedEncodingException;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.ProtocolException;import java.net.URL;import java.nio.charset.Charset;import java.util.Random;import org.apache.http.HttpResponse;import org.apache.http.ParseException;import org.apache.http.client.ClientProtocolException;import org.apache.http.client.HttpClient;import org.apache.http.client.methods.HttpPost;import org.apache.http.client.methods.HttpUriRequest;import org.apache.http.entity.mime.HttpMultipartMode;import org.apache.http.entity.mime.MultipartEntity;import org.apache.http.entity.mime.content.FileBody;import org.apache.http.entity.mime.content.StringBody;import org.apache.http.impl.client.DefaultHttpClient;import org.apache.http.protocol.HTTP;import org.apache.http.util.EntityUtils;import android.app.Activity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.webkit.WebView;import android.widget.Button;import android.widget.TextView;public class Test08_11Activity extends Activity {private TextView textViewInfo;private TextView textViewFile;private TextView textViewUrl;private WebView webViewResult;private Button buttonJava;private Button buttonApache;private static final String UPLOAD_FILE = "/sdcard/test.jpg";private static final String UPLOAD_URL = "http://192.168.9.194:8080/";private static final int BUFFER_SIZE = 1024;//rfc1867协议private static final String FIELD_SEP = ": ";private static final String CR_LF = "\r\n";private static final String TWO_DASHES = "--";private static final String BOUNDARY; /** * The pool of ASCII chars to be used for generating a multipart boundary. */ private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); static { StringBuilder buffer = new StringBuilder(); Random rand = new Random(); int count = rand.nextInt(11) + 30; // a random size from 30 to 40 for (int i = 0; i < count; i++) { buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]); } BOUNDARY = buffer.toString(); Log.i("info", BOUNDARY);} @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textViewInfo = (TextView)findViewById(R.id.textViewInfo); textViewFile = (TextView)findViewById(R.id.textViewFile); textViewUrl = (TextView)findViewById(R.id.textViewUrl); webViewResult = (WebView)findViewById(R.id.webViewResult); buttonJava = (Button)findViewById(R.id.buttonJava); buttonApache = (Button)findViewById(R.id.buttonApache); textViewFile.setText(UPLOAD_FILE); textViewUrl.setText(UPLOAD_URL); buttonJava.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {javaUpload();}}); buttonApache.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {apacheUpload();}}); } private void javaUpload(){ URL url = null; try {url = new URL(UPLOAD_URL);} catch (MalformedURLException e) {}HttpURLConnection urlConnection = null; try { urlConnection = (HttpURLConnection) url.openConnection();} catch (IOException e) {textViewInfo.setText(e.getMessage());return;}try {urlConnection.setRequestMethod("POST");} catch (ProtocolException e) {}urlConnection.setDoOutput(true);urlConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary="+ BOUNDARY + "; charset=UTF-8");OutputStream out = null;try {out = new BufferedOutputStream(urlConnection.getOutputStream());//请求} catch (IOException e) {urlConnection.disconnect();textViewInfo.setText(e.getMessage());return;}FileInputStream fStream = null;StringBuilder form = new StringBuilder();form.append(TWO_DASHES + BOUNDARY + CR_LF);form.append("Content-Disposition" + FIELD_SEP + "form-data; name=\"name\"" + CR_LF);form.append("Content-Type" + FIELD_SEP + "text/plain; charset=UTF-8"+ CR_LF);form.append("Content-Transfer-Encoding" + FIELD_SEP + "8bit"+ CR_LF);form.append(CR_LF);form.append("testImage抓哇");form.append(CR_LF);form.append(TWO_DASHES + BOUNDARY + CR_LF);form.append("Content-Disposition" + FIELD_SEP + "form-data; name=\"images\";filename=\"test抓哇.jpg\"" + CR_LF);form.append("Content-Type" + FIELD_SEP + "image/jpeg; charset=UTF-8"+ CR_LF);form.append("Content-Transfer-Encoding" + FIELD_SEP + "binary"+ CR_LF);form.append(CR_LF);try {out.write(form.toString().getBytes("UTF-8"));fStream = new FileInputStream(UPLOAD_FILE);byte[] buffer = new byte[BUFFER_SIZE];int length = -1;while ((length = fStream.read(buffer)) != -1) {out.write(buffer,0,length);}out.write(CR_LF.getBytes("UTF_8"));out.write((TWO_DASHES + BOUNDARY + TWO_DASHES + CR_LF).getBytes("UTF-8"));out.flush();} catch (IOException e) {try {out.close();} catch (IOException e1) {}urlConnection.disconnect();textViewInfo.setText(e.getMessage());return;} finally {try {if (fStream != null) {fStream.close();}} catch (IOException e) {}}getResponseJava(urlConnection); } private void apacheUpload(){ HttpPost request = new HttpPost(UPLOAD_URL); FileBody bin = new FileBody(new File(UPLOAD_FILE),"test阿帕奇.jpg","image/jpeg",HTTP.UTF_8); StringBody comment = null;try {comment = new StringBody("testImage阿帕奇", Charset.forName(HTTP.UTF_8));} catch (UnsupportedEncodingException e) {} MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, Charset.forName(HTTP.UTF_8)); entity.addPart("images", bin); entity.addPart("name", comment); request.setEntity(entity); getResponseApache(request); } private void getResponseJava(HttpURLConnection urlConnection) {InputStream in = null;try {in = new BufferedInputStream(urlConnection.getInputStream());//响应} catch (IOException e) {urlConnection.disconnect();textViewInfo.setText(e.getMessage());return;}BufferedReader reader = null;try {reader = new BufferedReader(new InputStreamReader(in,"UTF-8"));} catch (UnsupportedEncodingException e1) {}StringBuilder result = new StringBuilder();String tmp = null;try {while((tmp = reader.readLine()) != null){result.append(tmp);}} catch (IOException e) {textViewInfo.setText(e.getMessage());return;} finally {try {reader.close();urlConnection.disconnect();} catch (IOException e) {}}webViewResult.loadDataWithBaseURL(null, result.toString(), "text/html", "UTF-8", null);} private void getResponseApache(HttpUriRequest request) {HttpClient client = new DefaultHttpClient(); HttpResponse response = null; try {response = client.execute(request);} catch (ClientProtocolException e) {textViewInfo.setText(e.getMessage());} catch (IOException e) {textViewInfo.setText(e.getMessage());}if (response == null) {return;}String result = null;if (response.getStatusLine().getStatusCode() == 200) {try {result = EntityUtils.toString(response.getEntity(),HTTP.UTF_8);} catch (ParseException e) {result = e.getMessage();} catch (IOException e) {result = e.getMessage();}} else {result = "error response" + response.getStatusLine().toString();}//Log.i("info", result); //不乱码//webViewResult.loadData(result, "text/html", "UTF-8"); //乱码webViewResult.loadDataWithBaseURL(null, result, "text/html", "UTF-8", null);//不乱码}}别忘了加权限
<uses-permission android:name="android.permission.INTERNET"/>
先看看运行效果
点击java上传
后台输出
文件上传成功
点击Apache上传
后台输出
文件保存成功
运行一切OK。
解释一下代码:
private static final String UPLOAD_FILE = "/sdcard/test.jpg";private static final String UPLOAD_URL = "http://192.168.9.194:8080/";
在sd卡根目录上放上test.jpg文件,node.js+android http请求响应 讲过,不要使用localhost。
代码其它部分主要是要了解http文件上传的协议 RFC1867,http://www.ietf.org/rfc/rfc1867.txt IETF官方介绍,它提供的例子不错
6. Examples Suppose the server supplies the following HTML: <FORM ACTION="http://server.dom/cgi/handle" ENCTYPE="multipart/form-data" METHOD=POST> What is your name? <INPUT TYPE=TEXT NAME=submitter> What files are you sending? <INPUT TYPE=FILE NAME=pics> </FORM> and the user types "Joe Blow" in the name field, and selects a text file "file1.txt" for the answer to 'What files are you sending?' The client might send back the following data: Content-type: multipart/form-data, boundary=AaB03x --AaB03x content-disposition: form-data; name="field1" Joe Blow --AaB03x content-disposition: form-data; name="pics"; filename="file1.txt" Content-Type: text/plain ... contents of file1.txt ... --AaB03x-- If the user also indicated an image file "file2.gif" for the answer to 'What files are you sending?', the client might client might send back the following data: Content-type: multipart/form-data, boundary=AaB03x --AaB03x content-disposition: form-data; name="field1" Joe Blow --AaB03x content-disposition: form-data; name="pics" Content-type: multipart/mixed, boundary=BbC04y --BbC04y Content-disposition: attachment; filename="file1.txt"
如果看不太懂的话,可以在搜索引擎里找 rfc1867实现。
- node.js+android(使用HttpURLConnection和HttpClient)实现文件上传
- android使用HttpURLConnection/HttpClient实现带参数文件上传
- android 用httpClient和HttpUrlConnection上传文件
- Android HttpClient HttpUrlConnection上传文件
- 利用node.js android 实现文件上传
- Android使用HttpURLConnection上传文件
- Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传
- Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传
- Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传
- Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传带进度条
- Android 使用HttpClient和第三方MIME文件上传类库,实现文件上传
- Android 使用HttpClient和第三方MiME文件上传类库,实现文件上传
- android 登录Javaeye(使用HttpURLConnection和HttpClient)
- android 登录Javaeye(使用HttpURLConnection和HttpClient)
- android HttpURLConnection和HttpClient的使用
- Android:HttpUrlConnection和HttpClient的使用
- Golang+Android(使用HttpURLConnection)实现文件上传
- android使用HttpURLConnection实现带参数文件上传
- 降龙十八掌搞定rt3070 USB WIFI模块在android2.3平台上上网[基于x210开发板]
- 想做视频监控的朋友看过来
- 官方解读BroadcastReceiver
- 从零开始学ArcGIS Server(一)--ArcGIS Server平台
- Air Dictate:用Siri解放你在Mac上打字的双手
- node.js+android(使用HttpURLConnection和HttpClient)实现文件上传
- VS2010 Silverlight学习——启动xaml方式
- Oracle 修改日志大小及增加日志成员
- SD 交货出口
- 从零开始学ArcGIS Server(二)--系统结构
- C语言volatile类型浅析
- 海量数据存储-bit map思想
- Java中数值计算的精度问题
- 国内知名产品和他们的开发语言v0.0.1