• (十)HttpClient以multipart/form-data上传文件


    原文链接:https://blog.csdn.net/wsdtq123/article/details/78888734

    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

    一个真实的请求体

    一个真实的请求体大致如下:
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-Disposition: form-data; name="Filename"
     
    2.jpg
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-Disposition: form-data; name="pictitle"
     
    2.jpg
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-Disposition: form-data; name="dir"
     
    upload1
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-Disposition: form-data; name="fileNameFormat"
     
    {time}{rand:6}
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-Disposition: form-data; name="fileName"
     
    2.jpg
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-Disposition: form-data; name="upfile"; filename="2.jpg"
    Content-Type: application/octet-stream
     
    ÿØÿàJFIFÿÛC		
     
     $.' ",#(7),01444'9=82<.342ÿÛC			
     
    2!!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¢Ô0K
    7£ô.¬:TÒ${B0ª	
    1E¢æUãÉéôïEQ	ÿÙ
    --yurnnlukjwfbrdiqvnqnegfitaaddkom
    Content-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

      

  • 相关阅读:
    CDN实现原理
    openstack测试集群扩容配置
    ELK5.2.2自动化部署脚本
    Python多线程
    Python反射
    OpenStack快照分析:(三)从磁盘启动云主机离线(在线)快照分析
    OpenStack快照分析:(二)从镜像启动的云主机离在线快照分析
    OpenStack快照分析:(一)从镜像启动的云主机离线快照分析
    Python元编程
    Python源码阅读:对象
  • 原文地址:https://www.cnblogs.com/lvchengda/p/13036332.html
Copyright © 2020-2023  润新知