HttpClient以multipart/form-data上传文件

来源:互联网 发布:银河历险记3 mac 下载 编辑:程序博客网 时间:2024/06/08 03:39
POST上传文件
最早的HTTP POST是不支持文件上传的,给编程开发带来很多问题。但是在1995年,ietf出台了rfc1867,也就是《RFC 1867 -Form-based File Upload in HTML》,用以支持文件上传。所以Content-Type的类型扩充了multipart/form-data用以支持向服务器发送二进制数据。因此发送post请求时候,表单<form>属性enctype共有二个值可选,这个属性管理的是表单的MIME编码:
 ①application/x-www-form-urlencoded(默认值)
 ②multipart/form-data
其实form表单在你不写enctype属性时,也默认为其添加了enctype属性值,默认值是enctype="application/x- www-form-urlencoded".
用multipart/form-data上传文件
今天我们主要谈谈使用httpclient以multipart/form-data来实现文件上传。
multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,且其值也必须规定为multipart/form-data,同时还需要规定一个内容分割符用于分割请求体中的多个post的内容,如文件内容和文本内容自然需要分割开来,不然接收方就无法正常解析和还原这个文件了。具体的头信息如下:Content-Type: multipart/form-data; boundary=${bound}
其中${bound} 是一个占位符,--${bound}代表我们规定的分割符,可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容,通常由客户端自主生成,如占位符为:yurnnlukjwfbrdiqvnqnegfitaaddkom,则分隔符为:--yurnnlukjwfbrdiqvnqnegfitaaddkom
一个真实的请求体
一个真实的请求体大致如下:
--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="Filename"2.jpg--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="pictitle"2.jpg--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="dir"upload1--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="fileNameFormat"{time}{rand:6}--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="fileName"2.jpg--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="upfile"; filename="2.jpg"Content-Type: application/octet-streamÿØÿàJFIFÿÛC $.' ",#(7),01444'9=82<.342ÿÛC2!!22222222222222222222222222222222222222222222222222ÿÀ22"ÿÄÿÄ3!1Aa"Qq¡Á2BR#3¢±ÿÄÿÄ !13QAÿÚ?ÇÛ{çZ3ãçjãêµrÖåcñ÷·µO åÃKë¥Tv®ÊhíI§~2,ºFT4É÷åò©Ëë¹¢Y¼9 etúÍD=ÞØâ¡1Mº:î~þõStY)vè°l¦t¶îðâHùË=E>ÿ¤R3µ³/îEæÞb¿¸Í§\6£O­J#4Ý÷åFÀÕh_E5âw¢§ßg®÷1V¯/­Å·Ô³nDÞ=9ÏÒªi ,xïS^2Ûx¦ÊF²åÐåHûÒ¬±}K;h×ZóøÂîïÝÐàx®Z4]©¦àr_Ç-yç½q4Ó2FVÎÀáïåì\Ó¯á×%½6[=Pë9lëÔcJcæ;-²½Ø'ÒPÝÈË5ÉÎ=´©%¶·ÜFc«1%±Û'SL?´íã8¢¶y@zc^]»Tm8·Ss"É1æQwGË'þÔÁ¢ÊQçYµmÁÐýim<mk9b]ç¡ç^Uðã}MxB8bÛÆk`·ÃÈãw?í\¥º7sÆ¢Ù~i9·&ÞÖÍ #Õ»èF:{Ò6Ûfç¡°à2érj§{âÝðÞâ['u×ãD>clä4§H35ÕÛlÅp4=¥,·(íA~xçO~]êjWÒªçók­gëæ%¼lª&27ër[áL¤ñÌr7¦II?¹4©`Q^Í,$¤gw9î(¬ÃùÝÆSþTØÿ쯨]?WÞ«¾%b¯C]EVÊÎoþÂ:Ùê¦î,¨>¡Ìw¢Ô0K7£ô.¬:TÒ${B0ª1E¢æUãÉéôïEQÿÙ--yurnnlukjwfbrdiqvnqnegfitaaddkomContent-Disposition: form-data; name="Upload"Submit Query--yurnnlukjwfbrdiqvnqnegfitaaddkom--
请求体以--yurnnlukjwfbrdiqvnqnegfitaaddkom--结束,其中乱码部分为上传的文件流。
HttpClient使用multipart/form-data来上传文件
封装的方法:
public static String postFileMultiPart(String url,Map<String,ContentBody> reqParam) throws ClientProtocolException, IOException{        CloseableHttpClient httpclient = HttpClients.createDefault();                try {            // 创建httpget.                HttpPost httppost = new HttpPost(url);                    //setConnectTimeout:设置连接超时时间,单位毫秒。setConnectionRequestTimeout:设置从connect Manager获取Connection 超时时间,单位毫秒。这个属性是新加的属性,因为目前版本是可以共享连接池的。setSocketTimeout:请求获取数据的超时时间,单位毫秒。 如果访问一个接口,多少时间内无法返回数据,就直接放弃此次调用。            RequestConfig defaultRequestConfig = RequestConfig.custom().setConnectTimeout(5000).setConnectionRequestTimeout(5000).setSocketTimeout(15000).build();            httppost.setConfig(defaultRequestConfig);                        System.out.println("executing request " + httppost.getURI());                        MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();            for(Entry<String,ContentBody> param : reqParam.entrySet()){            multipartEntityBuilder.addPart(param.getKey(), param.getValue());            }            HttpEntity reqEntity = multipartEntityBuilder.build();            httppost.setEntity(reqEntity);                        // 执行post请求.                CloseableHttpResponse response = httpclient.execute(httppost);                        System.out.println("got response");                        try {                  // 获取响应实体                    HttpEntity entity = response.getEntity();                  //System.out.println("--------------------------------------");                  // 打印响应状态                    //System.out.println(response.getStatusLine());                  if (entity != null) {                 return EntityUtils.toString(entity,Charset.forName("UTF-8"));                }                //System.out.println("------------------------------------");              } finally {                  response.close();                            }        } finally {              // 关闭连接,释放资源                try {                  httpclient.close();              } catch (IOException e) {                  e.printStackTrace();              }          }        return null;      }
调用postMultipart
String url = "xxxxxxx";   String httpRes = null;   String localFileName = "E:/2.jpg";   Map<String,ContentBody> reqParam = new HashMap<String,ContentBody>();   reqParam.put("Filename", new StringBody(localFileName, ContentType.MULTIPART_FORM_DATA));   reqParam.put("pictitle", new StringBody(localFileName, ContentType.MULTIPART_FORM_DATA));   reqParam.put("dir", new StringBody("upload1", ContentType.MULTIPART_FORM_DATA));   reqParam.put("fileNameFormat", new StringBody("{time}{rand:6}", ContentType.MULTIPART_FORM_DATA));   reqParam.put("fileName", new StringBody(localFileName, ContentType.MULTIPART_FORM_DATA));   reqParam.put("fileName", new StringBody(localFileName, ContentType.MULTIPART_FORM_DATA));   reqParam.put("upfile", new FileBody(new File(fileLocation)));   reqParam.put("Upload", new StringBody("Submit Query", ContentType.MULTIPART_FORM_DATA));   httpRes = HttpClientUtil.postFileMultiPart(url,reqParam);
利用httpclient上传文件需要两点:
1.这里一定不能有httppost.addHeader("Content-Type","multipart/form-data; boundary=yurnnlukjwfbrdiqvnqnegfitaaddkom"); 因为这里面有个boundary参数属性是不可控的。这个值是由浏览器生成的。如果强行指明和可能导致边界值不一致 就会请求失败 详细参见 http://blog.csdn.net/xiaojianpitt/article/details/6856536
2.StringBody的ContentType是multipart/form-data
HttpClientUtil工具类
附HttpClientUtil工具类,https://gitee.com/qigugu/dsb-capture-image/blob/master/src/main/java/com/dsb/util/HttpClientUtil.java


阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 迸溅的拼音 迸溅拼音 鼻息肉466专家 比波网 比尔泽兰 比嘉爱未种子 比利亚断腿 比特猪影视 比亚迪l4 笔仙惊魂2百度影音 必得剧 毕福剑出场费 毕福剑从央视网失踪 毕福剑完美专卖店 毕福剑微博发道歉信 毕建福 碧海情天录 碧香亭论坛 边防官兵滑雪射击 边疆颂歌歌词 鞭策之宝石 鞭尾草哪里多 变脸迷情百度影音 变身皇后与王妃 变态女假面小希 变调的人鱼小姐 便利贴女孩插曲 便利贴女孩主题曲 便衣支队2 便衣支队百度影音 辩护手套 彪悍少年2百度影音 表白遭拒跳钱塘江 表叔大口袋 别把自己不当干部 别惹大魔王2 别惹亿万大人物 别用下辈子来安慰我 别再惊动爱情 缤纷言情热点小说坊 冰碧帝皇蝎图片