HttpClient上傳文件


今天在寫微信的多媒體上傳下載接口,當時無論采用哪一個API都無法提交正確提交數據過去,不是連接不了微信服務器,就是微信服務器返回數據錯誤,后台百度了下,找到一篇文章,但不是用HttpClient寫的,他是直接用jdk自帶的URLConnection提交的數據。初看之下,想想HttpClient應該也可以做到的,也就仿照了下那哥們組裝了下數據嘗試下,用了StringEntityFileEntityInputStreamEntity都無法正確提交數據。后來出去抽了支煙,理清下思路。重寫來過,結果竟然成功了,具體的結合下面的代碼分析。

  1. 下面代碼使用HttpClient代碼提交了一個POST請求給微信服務器。
    /**
         * HttpClient POST請求 ,上傳多媒體文件
         * 
         * @param url
         *            請求地址
         * @param params
         *            參數列表
         * @return 響應字符串
         * @throws UnsupportedEncodingException
         * @Author Jie
         * @Date 2015-2-12
         */
        public static String postMethod2(String url, String filePath) {
            log.info("------------------------------HttpClient POST開始-------------------------------");
            log.info("POST:" + url);
            log.info("filePath:" + filePath);
            if (StringUtils.isBlank(url)) {
                log.error("post請求不合法,請檢查uri參數!");
                return null;
            }
            StringBuilder content = new StringBuilder();
    
            // 模擬表單上傳 POST 提交主體內容
            String boundary = "-----------------------------" + new Date().getTime();
            // 待上傳的文件
            File file = new File(filePath);
    
            if (!file.exists() || file.isDirectory()) {
                log.error(filePath + ":不是一個有效的文件路徑");
                return null;
            }
    
            // 響應內容
            String respContent = null;
            InputStream is = null;
            OutputStream os = null;
            File tempFile = null;
            CloseableHttpClient httpClient = null;
            HttpPost httpPost = null;
            try {
                // 創建臨時文件,將post內容保存到該臨時文件下,臨時文件保存在系統默認臨時目錄下,使用系統默認文件名稱
                tempFile = File.createTempFile(new SimpleDateFormat("yyyy_MM_dd").format(new Date()), null);
                os = new FileOutputStream(tempFile);
                is = new FileInputStream(file);
    
                os.write(("--" + boundary + "\r\n").getBytes());
                os.write(String.format("Content-Disposition: form-data; name=\"media\"; filename=\"" + file.getName() + "\"\r\n").getBytes());
                os.write(String.format("Content-Type: %s\r\n\r\n", FileUtils.getMimeType(file)).getBytes());
    
                // 讀取上傳文件
                BufferedInputStream bis = new BufferedInputStream(is);
                byte[] buff = new byte[8096];
                int len = 0;
                while ((len = bis.read(buff)) != -1) {
                    os.write(buff, 0, len);
                }
    
                os.write(("\r\n--" + boundary + "--\r\n").getBytes());
    
                httpClient = HttpClients.createDefault();
                // 創建POST請求
                httpPost = new HttpPost(url);
    
                // 創建請求實體
                FileEntity reqEntity = new FileEntity(tempFile, ContentType.MULTIPART_FORM_DATA);
    
                // 設置請求編碼
                reqEntity.setContentEncoding("UTF-8");
                httpPost.setEntity(reqEntity);
                // 執行請求
                HttpResponse response = httpClient.execute(httpPost);
                // 獲取響應內容
                respContent = repsonse(content, response, "POST");
            } catch (ClientProtocolException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    close(tempFile, os, is, httpPost, httpClient);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            log.info("Respone:" + respContent);
            log.info("------------------------------HttpClient POST結束-------------------------------");
            return respContent;
        }
  2. 下面代碼是獲取微信服務器相應內容。
    /**
         * 獲取響應內容,針對MimeType為text/plan、text/json格式
         * 
         * @param content
         *            響應內容
         * @param response
         *            HttpResponse對象
         * @param method
         *            請求方式 GET|POST
         * @return 轉為UTF-8的字符串
         * @throws ParseException
         * @throws IOException
         * @Author Jie
         * @Date 2015-2-28
         */
        private static String repsonse(StringBuilder content, HttpResponse response, String method) throws ParseException, IOException {
            StatusLine statusLine = response.getStatusLine();
            int statusCode = statusLine.getStatusCode();// 響應碼
            String reasonPhrase = statusLine.getReasonPhrase();// 響應信息
            if (statusCode == 200) {// 請求成功
                HttpEntity entity = response.getEntity();
                log.info("MineType:" + entity.getContentType().getValue());
                content.append(EntityUtils.toString(entity));
            } else {
                log.error(method + ":code[" + statusCode + "],desc[" + reasonPhrase + "]");
            }
            return new String(content.toString().getBytes("ISO8859-1"), "UTF-8");
        }

總結:最后使用了FileEntity這個請求實體,成功將多媒體文件上傳到微信服務器上面,獲得了微信服務器返回的media_id。接口是實現了,但是總覺得哪里還有什么需要改善的地方。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM