关于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;
}