安卓使用HttpClient进行Http Post文件上传

项目有个需求就是需要上传文件,由于传文件要用到multipart/data-form这种content-type。

里面内容全是2进制,各个field需要自己去拼。今天上午用java的HttpUrlConnection那个类自己去做,结果一上午都没做出来,服务器一直报错,拿浏览器提交就一点问题也没有。对比浏览器的报文,眼睛都看花了也没觉得哪里不一样。于是下午就开始尝试HttpClient。

在Apache上下了个最新的用JAVA玩没什么问题,放到jar包安卓上就开始各种类找不到…

       经过长时间网上搜索,发现android是自带apache httpclient的,但是它自带的那个不全,无法发文件。如果要发文件要用到 apache-mime4j-0.6.jar  httpmime-4.0.1.jar 这两个jar包,缺一不可!把这两个加到build path里面就ok了。

      

       安卓端文件上传源码如下:


package com.example.uploadtest;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
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.util.EntityUtils;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Button button = new Button(this);
	
		setContentView(button);
		button.setText("send data and write file");
		button.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				new Thread(new NetWorUpload(getAssets())).start();
				
			}
		});

	}

	class NetWorUpload implements Runnable {
		AssetManager assetManager;
	
		public NetWorUpload(AssetManager assetManager) {
			this.assetManager = assetManager;
		}

		@Override
		public void run() {
			HttpClient client = new DefaultHttpClient();
			HttpPost postMethod = new HttpPost("http://192.168.1.101:8080/upload");

			File file =  Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) ;
			String picturePath= file.getAbsolutePath();
			try {
				byte[] buffer=new byte[1024*10];
				InputStream is=assetManager.open("one.jpg");
				File output=new File(picturePath+"/one.jpg");
				Log.d("MSG", output.getAbsolutePath());
				FileOutputStream fos=new FileOutputStream(output);
				int readCount=0;
				Log.d("MSG",is.available()+"");
				while((readCount=is.read(buffer))!=-1 ){
					fos.write(buffer,0,readCount);
					Log.i("MSG", readCount+"");
				}
				fos.close();
				MultipartEntity entity = new MultipartEntity();
				FileBody contentFile = new FileBody(output);
				entity.addPart("uploadFile",contentFile);
				
				StringBody username = new StringBody("Longyubo");
				entity.addPart("username",username);
				
				StringBody password=new StringBody("passsss");
				entity.addPart("password", password);
				
				postMethod.setEntity(entity);
				HttpResponse response = client.execute(postMethod);
				HttpEntity httpEntity = response.getEntity();
				String state = EntityUtils.toString(httpEntity);
				Log.i("MSG", state);
				
				
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
	}

}

需要自己放个one.jpg到asset里面

 

Go服务器端源码如下:

那个login是用来测试一个post表单中,多个value匹配一个name的情况。。。可以不用管哈

 

// FileUploadServer project main.go
package main

import (
	"fmt"
	"html/template"
	"io"
	"net/http"
	"os"
)

func printErr(e error) {
	if e != nil {
		fmt.Println(e)
	}
}

//测试多个值的时候情况
func login(w http.ResponseWriter, r *http.Request) {

	if r.Method == "GET" {

		hello, world := "hello", "world"
		t, err := template.ParseFiles("login.html")
		if err != nil {
			fmt.Println(err)
		}
		t.Execute(w, map[string]string{"hello": hello, "world": world})
	} else {
		r.ParseForm()
		for _, v := range r.Form["username"] {
			w.Write([]byte("username: " + v))
		}
		w.Write([]byte("\n"))
		for _, v := range r.Form["password"] {
			w.Write([]byte("password: " + v))
		}

	}

}

func upload(w http.ResponseWriter, r *http.Request) {
	fmt.Println("uplaod invoke")
	if r.Method == "GET" {
		tpl, err := template.ParseFiles("upload.html")
		if err != nil {
			fmt.Println(err)
		}
		tpl.Execute(w, nil)

	} else {
		fmt.Println(r.Header)
		reader, _ := r.MultipartReader()

		form, FormErr := reader.ReadForm(16 << 20)
		if FormErr != nil {
			fmt.Println("FormErr", FormErr)
		}
		
	values:=	form.Value
	for k,v:=range values{		
		w.Write([]byte("server recieve--name: "+k+" value: "+v[0]))
	}
		
		
		
		path := "E:/upload/goUpload/"
		_, statError := os.Stat(path)

		if statError != nil {
			os.MkdirAll(path, 0777)
		}
		fmt.Println("BEFORE UPLOAD LIST")
		fmt.Println("form", form.File["uploadFile"])
		fileheadList := form.File["uploadFile"]
		fmt.Println("AFTER UPLOAD LIST")
		for _, v := range fileheadList {
			fileName := v.Filename
			file, err := v.Open()
			printErr(err)
			defer file.Close()
			toFile, fileError := os.Create(path + fileName)
			if fileError != nil {
				printErr(fileError)
				break
			}

			defer toFile.Close()
			io.Copy(toFile, file)
			w.Write([]byte("server had write file : " + fileName + "\n"))
		}
		w.Write([]byte("server had recieve your data successfully"))

	}
}
func main() {

	http.HandleFunc("/login", login)
	http.HandleFunc("/upload", upload)
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		fmt.Println(err)
	}
}




整个工程android和服务器端都上传了csdn。下载地址  http://download.youkuaiyun.com/detail/longyubo007/7605259



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值