今天在写微信的多媒体上传下载接口,当时无论采用哪一个API都无法提交正确提交数据过去,不是连接不了微信服务器,就是微信服务器返回数据错误,后台百度了下,找到一篇文章,但不是用HttpClient写的,他是直接用jdk自带的URLConnection提交的数据。初看之下,想想HttpClient应该也可以做到的,也就仿照了下那哥们组装了下数据尝试下,用了StringEntity、FileEntity、InputStreamEntity都无法正确提交数据。后来出去抽了支烟,理清下思路。重写来过,结果竟然成功了,具体的结合下面的代码分析。
-
下面代码使用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; }
-
下面代码是获取微信服务器相应内容。
/** * 获取响应内容,针对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。接口是实现了,但是总觉得哪里还有什么需要改善的地方。