今天在寫微信的多媒體上傳下載接口,當時無論采用哪一個API都無法提交正確提交數據過去,不是連接不了微信服務器,就是微信服務器返回數據錯誤,后臺百度了下,找到一篇文章,但不是用HttpClient寫的,他是直接用jdk自帶的URLConnection提交的數據。初看之下,想想HttpClient應該也可以做到的,也就仿照了下那哥們組裝了下數據嘗試下,用了StringEntity、FileEntity、InputStreamEntity都無法正確提交數據。后來出去抽了支煙,理清下思路。重寫來過,結果竟然成功了,具體的結合下面的代碼分析。
/** * 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; }/** * 獲取響應內容,針對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。接口是實現了,但是總覺得哪里還有什么需要改善的地方。
新聞熱點
疑難解答