同时上传参数和文件到服务器

毕业两年了,也工作两年了,但是由于具体的工作内容原因,真正去按照老大的要求去写一个程序,还是第一次。

这次就遇到了一个问题,从来没有接触过的Android网络编程,需求是按照指定的三种方法,,以POST方法,分别用HTTP和Socket上传一个文件到服务器。

指定的三种方法为:

第一种:形如 ":port/xxx/xxx/xxx/param?param1=xxx&param2=xxx"的形式

Params:

param1

param2

Data:

file:要上传的文件

第二种:形如“:port/xxx/xxx/xxx”的形式

Part1:

param1

Part2:

param2

Part3:

file:要上传的文件

第三种:形如“:port/xxx/xxx/xxx”的形式

Part1:

param1

Part2:

param2

Part3:

file:要上传的文件

利用Socket方法来发送

三种方法,首先搞得我头晕脑胀,纠结了整整一天,后来终于理顺了一些,现在把这些方法陈列出来,大家来批评指正,有不对的地方及时通知我来进行修改,大家共勉。

第一种和第二种都是模拟HTTP协议来发送的,使用HttpURLConnection类来发送,第三种使用Socket方法来发送。

首先我定义了一个上传工具类:UploadUtil.java,里面只是定义了一个Static的服务器地址,INTERNAL_HOST。

代码如下

public class UploadUtil {static String INTERNAL_HOST = ":port/xxx/xxx/xxx/upload/";}这个主机是在第一种方法的地址中,位于“param?”前面的部分。

完成第一种方法:

第一种方法的“:port/xxx/xxx/xxx/param?param1=xxx&param2=xxx”,其实已经给出了POST的参数,param1和param2,我为了弄着方便,就直接写死了参数键值。其实也可以在方法内部,通过传入的参数,进行循环拼装,最后只要能组出类似“:port/xxx/xxx/xxx/param?param1=xxx&param2=xxx”的字符串就行,最后通过URL来生成一个url对象即可。

public static void queryParam(String fileName){String BOUNDARY = "—————————7db1c523809b2";//数据分割线File file = new File(fileName); // 要上传的文件String host = INTERNAL_HOST + "param?param1=xxxm2=xxx"; // 这个字符串就是要上传的带参数的服务器地址try{byte[] after = ("–" + BOUNDARY + "–\r\n").getBytes("UTF-8");// 构造URL和ConnectionURL url = new URL(host);HttpURLConnection conn = (HttpURLConnection)url.openConnection();// 设置HTTP协议的头属性conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);conn.setRequestProperty("Content-Length", String.valueOf(file.length()));conn.setRequestProperty("HOST", url.getHost());conn.setDoOutput(true);// 得到Connection的OutputStream流,准备写数据OutputStream out = conn.getOutputStream();InputStream in = new FileInputStream(file);// 写文件数据。因为服务器地址已经带有参数了,所以这里只要直接写入文件部分就可以了。byte[] buf = new byte[1024];int len;while ((len = in.read(buf)) != -1){out.write(buf, 0, len);}// 数据结束标志,整个HTTP报文就构造结束了。//out.write(after);in.close();out.close();Log.d("carter", "queryParam 返回码为: " + conn.getResponseCode());Log.d("carter", "queryParam 返回信息为: " + conn.getResponseMessage());}catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

大概的步骤:

1.先构造好URL服务器地址

2.初始化一个URL对象,得到里面的HttpURLConnection对象

3.设置connection对象的头部信息,包括POST方法、HOST、Content-Type、Content-Length等属性

4.写入要上传的文件内容

完成第二种方法:

第二种的方法,不想第一种方法那样简单,但基本语法结构都相似,因为都是模仿HTTP协议的形式。

第二种方法,在服务器地址上,只提供了上传的HOST和PATH,具体的参数没有提供,所以要通过在HTTP报文中添加来实现。

public static void multiPart(String fileName){String BOUNDARY = "—————————7db1c523809b2";//数据分割线File file = new File(fileName); // 要上传的文件// 构造param参数部分的数据内容,格式都是相同的,依次添加param1和param2StringBuilder sb = new StringBuilder();sb.append("–" + BOUNDARY + "\r\n");sb.append("Content-Disposition: form-data; name=\&;param1\&;" + "\r\n");sb.append("\r\n");sb.append("xxx" + "\r\n");sb.append("–" + BOUNDARY + "\r\n");sb.append("Content-Disposition: form-data; name=\&;param2\&;" + "\r\n");sb.append("\r\n");sb.append("xxx" + "\r\n");// 构造要上传文件的前段参数内容,和普通参数一样,在这些设置后就可以紧跟文件内容了。sb.append("–" + BOUNDARY + "\r\n");sb.append("Content-Disposition: form-data; name=\&;data\&;; filename=\&;" + fileName + "\&;" + "\r\n");sb.append("Content-Type: text/plain" + "\r\n");sb.append("\r\n");try{byte[] before = sb.toString().getBytes("UTF-8");byte[] after = ("–" + BOUNDARY + "–\r\n").getBytes("UTF-8");URL url = new URL(INTERNAL_HOST);// 得到HttpURLConnection对象,设置一些头信息基本属性HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);conn.setRequestProperty("Content-Length", String.valueOf(before.length + file.length() + after.length));conn.setRequestProperty("HOST", url.getHost());conn.setDoOutput(true);OutputStream out = conn.getOutputStream();InputStream in = new FileInputStream(file);// 写入参数信息out.write(before);// 写入文件数据byte[] buf = new byte[1024];int len;while ((len = in.read(buf)) != -1){out.write(buf, 0, len);}// 写结束符,代表该HTTP组包完毕out.write(after);// 发送出去out.flush();// 关闭流in.close();out.close();Log.d("carter", "multipart 返回码为: " + conn.getResponseCode());Log.d("carter", "multipart 返回信息为: " + conn.getResponseMessage());}catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (UnsupportedEncodingException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}具体步骤为:

1.分别把param1等参数通过格式组织起来

2.得到HttpURLConnection对象,设置一些基本头属性,其中的Content-Length是所有param和文件加上尾标志的总长度。

3.发送outputStream。

完成第三种方法:

第三种方法和第二种方法很相似,只是使用了Socket对象,而不是HttpURLConnection方法。

爱的力量大到可以使人忘记一切,却又小到连一粒嫉妒的沙石也不能容纳

同时上传参数和文件到服务器

相关文章:

你感兴趣的文章:

标签云: