Android通过HTTP协议上传图片(multipart/form-data格式)

关于multipart/form-data请求

       根据RFC的文档,并没有multipart/form-data请求这么一种请求方式,它并不是一种跟常用的get、post等独立的请求方式。multipart/form-data是HTTP协议中实现文件上传的规范,是RFC1867 (http://www.ietf.org/rfc/rfc1867.txt) 添加的新规范。

multipart/form-data有以下特点:

1、multipart/form-data的基础方法是post方法。

2、multipart/form-data与post方法的不同之处:请求头,请求体。

3、multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容。

创建HttpURLConnection并设置属性

URL url = new URL(requestURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setConnectTimeout(30 * 1000); //30秒连接超时
connection.setReadTimeout(30 * 1000);   //30秒读取超时
connection.setDoInput(true);  //允许文件输入流
connection.setDoOutput(true); //允许文件输出流
connection.setUseCaches(false);  //不允许使用缓存
connection.setRequestMethod("POST");  //请求方式为POST
connection.setRequestProperty("Charset", utf-8);  //设置编码为utf-8
connection.setRequestProperty("connection", "keep-alive"); //保持连接
connection.setRequestProperty("Cookie", "sid=" + firstCookie + ";" + "cgi_ck=" +secondCookie);//设置cookie,多个cookie用;分开
connection.setRequestProperty("Content-Type", multipart/form-data + ";boundary=" + BOUNDARY); //Content-Type必须为multipart/form-data
需要注意以下几点:

1、请求方式需要设置为POST

2、Content-Type必须为multipart/form-data

3、必要的话设置Cookie,多个用;分开

读取图片并压缩后转为InputStream

ByteArrayOutputStream baos = new ByteArrayOutputStream();
Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
bitmap.compress(CompressFormat.JPEG, 50, baos); //0-100 100为不压缩
InputStream is = new ByteArrayInputStream(baos.toByteArray());

如果不需要压缩,可以之间调用以下一行代码完成

InputStream is = new FileInputStream(file);
包装图片文件并上传

OutputStream outputSteam = connection.getOutputStream();
DataOutputStream dos = new DataOutputStream(outputSteam);
StringBuffer sb = new StringBuffer();
sb.append(PREFIX);
sb.append(BOUNDARY);
sb.append(LINE_END);

sb.append("Content-Disposition: form-data; name=\"upload!\"; filename=\""+file.getName()+"\""+LINE_END); 
sb.append("Content-Type: application/octet-stream; charset="+CHARSET+LINE_END);
sb.append(LINE_END);
dos.write(sb.toString().getBytes());

byte[] bytes = new byte[1024];
int len = 0;
while((len=is.read(bytes))!=-1)
{
	dos.write(bytes, 0, len);
}
is.close();
dos.write(LINE_END.getBytes());
byte[] end_data = (PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes();
dos.write(end_data);
dos.flush();
这里需要特别注意:

name是服务器端需要key;filename是文件的名字(包括后缀)

获取返回码并做相应处理

int res = conn.getResponseCode();
if(conn.getResponseCode() == 200)
{
	BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));
	StringBuilder result = new StringBuilder();
	String line;
	while((line = input.readLine()) != null)
	{
		result.append(line).append("\n");
	}
 return result.toString();
}

最后,整一个图片上传的函数如下:

public String uploadFile(File file,String requestURL,String firstCookie, String secondCookie, String fileField)
{
	String TAG = "uploadFile";
	String PREFIX = "--";
	String LINE_END = "\r\n";
	String BOUNDARY =  UUID.randomUUID().toString();  //随机生成边界
	
	try {
		URL url = new URL(requestURL);
		HttpURLConnection connection = (HttpURLConnection) url.openConnection();
		connection.setConnectTimeout(30 * 1000); //30秒连接超时
		connection.setReadTimeout(30 * 1000);   //30秒读取超时
		connection.setDoInput(true);  //允许文件输入流
		connection.setDoOutput(true); //允许文件输出流
		connection.setUseCaches(false);  //不允许使用缓存
		connection.setRequestMethod("POST");  //请求方式为POST
		connection.setRequestProperty("Charset", utf-8);  //设置编码为utf-8
		connection.setRequestProperty("connection", "keep-alive"); //保持连接
		connection.setRequestProperty("Cookie", "sid=" + firstCookie + ";" + "cgi_ck=" +secondCookie);//设置cookie,多个cookie用;分开
		connection.setRequestProperty("Content-Type", multipart/form-data + ";boundary=" + BOUNDARY); //特别注意:Content-Type必须为multipart/form-data
		
		//如果传入的文件路径不为空的话,则读取文件并上传
		if(file!=null)
		{
			//读取图片进行压缩
			//如果不需要压缩的话直接读取文件则可 InputStream is = new FileInputStream(file);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Bitmap bitmap = BitmapFactory.decodeFile(file.toString());
			bitmap.compress(CompressFormat.JPEG, 50, baos); //0-100 100为不压缩
			InputStream is = new ByteArrayInputStream(baos.toByteArray());

			OutputStream outputSteam = connection.getOutputStream();
			DataOutputStream dos = new DataOutputStream(outputSteam);
			StringBuffer sb = new StringBuffer();
			sb.append(PREFIX);
			sb.append(BOUNDARY);
			sb.append(LINE_END);

			//特别注意
			//name是服务器端需要key;filename是文件的名字(包括后缀)
			sb.append("Content-Disposition: form-data; name=\"upload!\"; filename=\""+file.getName()+"\""+LINE_END); 
			sb.append("Content-Type: application/octet-stream; charset="+CHARSET+LINE_END);
			sb.append(LINE_END);
			dos.write(sb.toString().getBytes());
			
			byte[] bytes = new byte[1024];
			int len = 0;
			while((len=is.read(bytes))!=-1)
			{
				dos.write(bytes, 0, len);
			}
			is.close();
			dos.write(LINE_END.getBytes());
			byte[] end_data = (PREFIX+BOUNDARY+PREFIX+LINE_END).getBytes();
			dos.write(end_data);
			dos.flush();

			//获取返回码,根据返回码做相应处理
			int res = conn.getResponseCode();
			Log.d(TAG, "response code:"+res);
			if(conn.getResponseCode() == 200)
			{
				BufferedReader input = new BufferedReader(new InputStreamReader(conn.getInputStream()));
				StringBuilder result = new StringBuilder();
				String line;
				while((line = input.readLine()) != null)
				{
					result.append(line).append("\n");
				}
				Log.i(TAG, result.toString());
		     return result.toString();
			}
		}
		
	} catch (MalformedURLException e) {
		e.printStackTrace();
	} catch (IOException e) {
		e.printStackTrace();
	}
	return null;
}



你可能感兴趣的:(Android)