J2ME中多个文件上传
对于数据上传有两种方式,这里我主要介绍post上传,post上传一般的数据流:如用户名和密码等等,在HttpConnection链接中设置了其Content-Type为application/x-www-form-urlencoded;如果上传文件,设置其Content-Type 为multipart/form-data类型。第一情况比较简单,主要对第二种介绍,并赋予相应代码,希望对初学者有帮助,希望同行指正!
使用multipart/form-data发送文件
下面一段介绍跟大部分文章介绍一样,不用多说。但是大部分都是一个文件上传,现在要实现多个上传,需要把多个文件的流完整整合起来,这样在服务器端解析流时根据JSR75规范来解析存储。
如果要在MIDP客户端向服务器上传文件,我们就必须模拟一个POST multipart/form-data类型的请求,Content-Type必须是multipart/form-data。
以multipart/form-data编码的POST请求格式与application/x-www-form-urlencoded完全不同,multipart/form-data需要首先在HTTP请求头设置一个分隔符,例如ABCD:
hc.setRequestProperty("Content-Type", "multipart/form-data; boundary=ABCD");
然后,将每个字段用“--分隔符”分隔,最后一个“--分隔符--”表示结束。例如,要上传一个title字段"Today"和一个文件d:/temp.png,HTTP正文如下:
--ABCD
Content-Disposition: form-data; name="title"
/r/n
Today
--ABCD
Content-Disposition: form-data; name="d:/temp.png"; filename="d:/temp.png"
Content-Type: text/plain
/r/n
<这里是d:/temp.png文件的内容>
--ABCD--
/r/n
请注意,每一行都必须以/r/n结束,包括最后一行。如果用Sniffer程序检测IE发送的POST请求,可以发现IE的分隔符类似于---------------------------7d4a6d158c9,这是IE产生的一个随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置。我们可以写一个固定的分隔符,只要足够复杂即可。
发送文件的POST代码如下:
String[] props = ... // 字段名
String[] values = ... // 字段值
byte[] file = ... // 文件内容
String BOUNDARY = "---------------------------7d4a6d158c9"; // 分隔符
StringBuffer sb = new StringBuffer();
// 发送每个字段:
for(int i=0; i sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("/r/n");
sb = sb.append("Content-Disposition: form-data; name=/""+ props[i] + "/"/r/n/r/n");
sb = sb.append(URLEncoder.encode(values[i]));
sb = sb.append("/r/n");
}
// 发送文件:
sb = sb.append("--");
sb = sb.append(BOUNDARY);
sb = sb.append("/r/n");
sb = sb.append("Content-Disposition: form-data; name=/"1/"; filename=/"d:/temp.png/"/r/n");
sb = 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();
// 设置HTTP头:
hc.setRequestProperty("Content-Type", MULTIPART_FORM_DATA + "; boundary=" + BOUNDARY);
hc.setRequestProperty("Content-Length", String.valueOf(data.length + file.length + end_data.length));
// 输出:
output = hc.openOutputStream();
output.write(data);
output.write(file);
output.write(end_data);
// 读取服务器响应:
// TODO...
对于多个文件上传,上传的流的合并是最重要的一个环节。主方法为:getAllPostData()
此方法中参数主要有:头部数据流和文件流(多个文件合并流)和尾部流("--" + boundary + "--/r/n"),下面就头部数据和文件数据谈谈:
1)获取头部流:
其中参数Hashtable 为存放 文件名及值,这个post上传时获取得到。通过方法getAllParams()
2)获取文件流:
辅助方法mergeBytes()把多个流合并:
辅助方法:getFileName()
至于多个file流合并,定义一个byte[]:allFilePostData[], 然后采用 allFilePostData=mergeBytes(allFilePostData,getFilePostData(parmName,fileName,inputNode.fileData)); 来对多个文件流组合起来。
最后把所有头部数据,文件数据调用public static byte[] getAllPostData(byte[] headPostData,byte[] filePostData ){}来作为一个完整流post上传。
如有不明白可以随时大家研究一下。希望对大家有些帮助。当时我写上传多个文件上传时,就是j2me方面介绍太少哦。最后是看了一片j2ee的在服务器端解析post流文章后逆向写的.