使用HttpURLConnection的应用稍加修饰,对服务器来说它就是一个浏览器,接受HTTP请求和发送响应.当我们需要让程序能像使用浏览器一样上传文件到HTTP服务器,使用HttpURLConnection并设置一些参数即可.
使用HttpURLConnection上传文件非常简单,只要把要上传的数据组装成使用浏览器上传时一模一样的"格式",写到输出流就可以了.以下简单讨论一下使用浏览器上传一个文件时发送的数据的"格式"是怎样的.
假定我有一个文本文件 test.txt 内容为
content of test.txt
上传时浏览器发送的格式是
-----------------------------7d65d38307d2
Content-Disposition: form-data; name="myfile"; filename="E:\badboy\test.txt"
Content-Type: text/plain
content of test.txt
-----------------------------7d65d38307d2--
对于这次的文件上传,第1行和第6行是分隔符,他们之间是文件的信息和内容.第2和第3行是文件的一些基本信息,例如这里表单名是myfile文件是E:\badboy\test.txt内容类型为text/plain.第5行开始是文件的内容.
这里的分隔符浏览器是随机生成的,但我们可以给它指定一个,只要在请求的时候给服务器说明一下,然后我们将要发送的数据组装成上述的格式,简单地写进HttpURLConnection的输出流即可完成上传.
有关这部分的内容详见这个网页:http://www.web1357.cn/post/multipartform_data_boundary_post.html
以下是一个简单的演示程序
try
{
URL url = new URL("http://192.168.1.111:1108/testupload/upload.php"); //文件接收的CGI,不一定是JSP的
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符
StringBuffer sb = new StringBuffer();
sb.append("--");
sb.append(BOUNDARY);
sb.append("\r\n");
sb.append("Content-Disposition: form-data; name=\"myfile\"; filename=\"test.txt\"\r\n");
sb.append("Content-Type: application/octet-stream\r\n\r\n");
byte[] data = sb.toString().getBytes();
byte[] end_data = ("\r\n--" + BOUNDARY + "--\r\n").getBytes();
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary="+BOUNDARY); //设置表单类型和分隔符
conn.setRequestProperty("Content-Length", String.valueOf(data.length + buf.length + end_data.length)); //设置内容长度
os = conn.getOutputStream();
os.write(data);
FileInputStream fis = new FileInputStream(new File("E:/badboy/test.txt")); //要上传的文件
int rn2;
byte[] buf2 = new byte[1024];
while((rn2=fis.read(buf2, 0, 1024))>0)
{
os.write(buf2,0,rn2);
}
os.write(end_data);
os.flush();
os.close();
fis.close();
//得到返回的信息
InputStream is = conn.getInputStream();
byte[] inbuf = new byte[1024];
int rn;
while((rn=is.read(inbuf,0,1024))>0)
{
System.out.write(inbuf,0,rn);
}
is.close();
}
catch(Exception ee)
{
System.out.println("上传出错.");
}
如果要实现上传进度监视,暂时我只能使用sun.net.www.protocol.http.HttpURLConnection而不是java.net.URLConnection,因为前者可以分块上传,后者无论如何都是最后一次把数据上传完.相关资料请