Android中发送Http请求(包括文件上传、servlet接收)的实例代码
/**
* 通过http协议提交数据到服务端,实现表单提交功能,包括上传文件
* @param actionurl 上传路径
* @param params 请求参数 key为参数名,value为参数值
* @param file 上传文件
*/
public static void postmultiparams(string actionurl, map<string, string> params, formbean[] files) {
try {
postmethod post = new postmethod(actionurl);
list<art> formparams = new arraylist<art>();
for(map.entry<string, string> entry : params.entryset()){
formparams.add(new stringpart(entry.getkey(), entry.getvalue()));
}
if(files!=null)
for(formbean file : files){
//filename为在服务端接收时希望保存成的文件名,filepath是本地文件路径(包括了源文件名),filebean中就包含了这俩属性
formparams.add(new filepart("file", file.getfilename(), new file(file.getfilepath())));
}
part[] parts = new part[formparams.size()];
iterator<art> pit = formparams.iterator();
int i=0;
while(pit.hasnext()){
parts[i++] = pit.next();
}
//如果出现乱码可以尝试一下方式
//stringpart sp = new stringpart("text", "testvalue", "gb2312");
//filepart fp = new filepart("file", "test.txt", new file("./temp/test.txt"), null, "gb2312"
//postmethod.getparams().setcontentcharset("gb2312");
multipartrequestentity mrp = new multipartrequestentity(parts, post.getparams());
post.setrequestentity(mrp);
//execute post method
httpclient client = new httpclient();
int code = client.executemethod(post);
system.out.println(code);
} catch ...
}
通过以上代码可以成功的模拟java客户端发送post请求,服务端也能接收并保存文件
java端测试的main方法:
public static void main(string[] args){
string actionurl = "http://192.168.0.123:8080/wsserver/androiduploadservlet";
map<string, string> strparams = new hashmap<string, string>();
strparams.put("paramone", "valueone");
strparams.put("paramtwo", "valuetwo");
formbean[] files = new formbean[]{new formbean("dest1.xml", "f:/testpostsrc/main.xml")};
httptool.postmultiparams(actionurl,strparams,files);
}
本以为大功告成了,结果一移植到android工程中,编译是没有问题的。
但是运行时抛了异常 先是说找不到postmethod类,org.apache.commons.httpclient.methods.postmethod这个类绝对是有包含的;
还有个异常就是verifyerror。 开发中有几次碰到这个异常都束手无策,觉得是sdk不兼容还是怎么地,哪位知道可得跟我说说~~
于是看网上有直接分析http request的内容构建post请求的,也有找到带上传文件的,拿下来运行老是有些问题,便直接通过运行上面的java工程发送的post请求,在servlet中打印出请求内容,然后对照着拼接字符串和流终于给实现了!代码如下:
***********************************************************
/**
* 通过拼接的方式构造请求内容,实现参数传输以及文件传输
* @param actionurl
* @param params
* @param files
* @return
* @throws ioexception
*/
public static string post(string actionurl, map<string, string> params,
map<string, file> files) throws ioexception {
string boundary = java.util.uuid.randomuuid().tostring();
string prefix = "--" , linend = "\r\n";
string multipart_from_data = "multipart/form-data";
string charset = "utf-8";
url uri = new url(actionurl);
httpurlconnection conn = (httpurlconnection) uri.openconnection();
conn.setreadtimeout(5 * 1000); // 缓存的最长时间
conn.setdoinput(true);// 允许输入
conn.setdooutput(true);// 允许输出
conn.setusecaches(false); // 不允许使用缓存
conn.setrequestmethod("post");
conn.setrequestproperty("connection", "keep-alive");
conn.setrequestproperty("charsert", "utf-8");
conn.setrequestproperty("content-type", multipart_from_data + ";boundary=" + boundary);
// 首先组拼文本类型的参数
stringbuilder sb = new stringbuilder();
for (map.entry<string, string> entry : params.entryset()) {
sb.append(prefix);
sb.append(boundary);
sb.append(linend);
sb.append("content-disposition: form-data; name=\"" + entry.getkey() + "\"" + linend);
sb.append("content-type: text/plain; charset=" + charset+linend);
sb.append("content-transfer-encoding: 8bit" + linend);
sb.append(linend);
sb.append(entry.getvalue());
sb.append(linend);
}
dataoutputstream outstream = new dataoutputstream(conn.getoutputstream());
outstream.write(sb.tostring().getbytes());
// 发送文件数据
if(files!=null)
for (map.entry<string, file> file: files.entryset()) {
stringbuilder sb1 = new stringbuilder();
sb1.append(prefix);
sb1.append(boundary);
sb1.append(linend);
sb1.append("content-disposition: form-data; name=\"file\"; filename=\""+file.getkey()+"\""+linend);
sb1.append("content-type: application/octet-stream; charset="+charset+linend);
sb1.append(linend);
outstream.write(sb1.tostring().getbytes());
inputstream is = new fileinputstream(file.getvalue());
byte[] buffer = new byte[1024];
int len = 0;
while ((len = is.read(buffer)) != -1) {
outstream.write(buffer, 0, len);
}
is.close();
outstream.write(linend.getbytes());
}
//请求结束标志
byte[] end_data = (prefix + boundary + prefix + linend).getbytes();
outstream.write(end_data);
outstream.flush();
// 得到响应码
int res = conn.getresponsecode();
if (res == 200) {
inputstream in = conn.getinputstream();
int ch;
stringbuilder sb2 = new stringbuilder();
while ((ch = in.read()) != -1) {
sb2.append((char) ch);
}
}
outstream.close();
conn.disconnect();
return in.tostring();
}
**********************
button响应中的代码:
**********************
public void onclick(view v){
string actionurl = getapplicationcontext().getstring(r.string.wtsb_req_upload);
map<string, string> params = new hashmap<string, string>();
params.put("strparamname", "strparamvalue");
map<string, file> files = new hashmap<string, file>();
files.put("tempandroid.txt", new file("/sdcard/temp.txt"));
try {
httptool.postmultiparams(actionurl, params, files);
} catch ...
***************************
服务器端servlet代码:
***************************
public void dopost(httpservletrequest request, httpservletresponse response)
throws servletexception, ioexception {
//print request.getinputstream to check request content
//httptool.printstreamcontent(request.getinputstream());
requestcontext req = new servletrequestcontext(request);
if(fileupload.ismultipartcontent(req)){
diskfileitemfactory factory = new diskfileitemfactory();
servletfileupload fileupload = new servletfileupload(factory);
fileupload.setfilesizemax(file_max_size);
list items = new arraylist();
try {
items = fileupload.parserequest(request);
} catch ...
iterator it = items.iterator();
while(it.hasnext()){
fileitem fileitem = (fileitem)it.next();
if(fileitem.isformfield()){
system.out.println(fileitem.getfieldname()+" "+fileitem.getname()+" "+new string(fileitem.getstring().getbytes("iso-8859-1"),"gbk"));
} else {
system.out.println(fileitem.getfieldname()+" "+fileitem.getname()+" "+
fileitem.isinmemory()+" "+fileitem.getcontenttype()+" "+fileitem.getsize());
if(fileitem.getname()!=null && fileitem.getsize()!=0){
file fullfile = new file(fileitem.getname());
file newfile = new file(file_save_path+fullfile.getname());
try {
fileitem.write(newfile);
} catch ...
} else {
system.out.println("no file choosen or empty file");
}
}
}
}
}
public void init() throws servletexception {
//读取在web.xml中配置的init-param
file_max_size = long.parselong(this.getinitparameter("file_max_size"));//上传文件大小限制
file_save_path = this.getinitparameter("file_save_path");//文件保存位置
}
上一篇: 基于Android本地代码生成器详解