Java微信公众平台开发(七)--多媒体消息回复之图片回复
之前我们在做消息回复的时候我们对回复的消息简单做了分类,前面也有讲述如何回复【普通消息类型消息】,这里将讲述多媒体消息的回复方法,【多媒体消息】包含回复图片消息/回复语音消息/回复视频消息/回复音乐消息,这里以图片消息的回复为例进行讲解!
还记得之前将消息分类的标准就是一种是不需要上传多媒体资源到腾讯服务器的而另外一种是需要的,所以在这里我们所需要做的第一步就是上传资源到腾讯服务器,这里我们调用【素材管理】接口(后面将会有专门的章节讲述)进行图片的上传,同样的这个接口可以提供我们对语音、视频、音乐等消息的管理,这里以图片为例(文档地址:http://mp.weixin.qq.com/wiki/10/10ea5a44870f53d79449290dfd43d006.html )。在文档中我们可以发现这里上传的方式是模拟表单的方式上传,然后返回给我们我们需要在回复消息中需要用到的参数:media_id!
(一)素材接口图片上传
按照之前我们的约定将接口请求的url写入到配置文件interface_url.properties中:
1 #获取token的url 2 tokenUrl=https://api.weixin.qq.com/cgi-bin/token 3 #永久多媒体文件上传url 4 mediaUrl=http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=
然后我在这里写了一个模拟表单上传的工具类HttpPostUploadUtil.java,代码如下:
1 package com.gede.wechat.util; 2 3 import java.io.BufferedReader; 4 import java.io.DataInputStream; 5 import java.io.DataOutputStream; 6 import java.io.File; 7 import java.io.FileInputStream; 8 import java.io.InputStreamReader; 9 import java.io.OutputStream; 10 import java.net.HttpURLConnection; 11 import java.net.URL; 12 import java.util.Iterator; 13 import java.util.Map; 14 15 import javax.activation.MimetypesFileTypeMap; 16 17 import com.gede.web.util.GlobalConstants; 18 19 /** 20 * @author gede 21 * @version date:2019年5月26日 下午8:47:28 22 * @description : 23 */ 24 public class HttpPostUploadUtil { 25 26 public String urlStr; 27 28 public HttpPostUploadUtil() { 29 urlStr = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=" 30 + GlobalConstants.getInterfaceUrl("access_token") + "&type=image"; 31 } 32 33 /** 34 * 上传图片 35 * 36 * @param urlStr 37 * @param textMap 38 * @param fileMap 39 * @return 40 */ 41 @SuppressWarnings("rawtypes") 42 public String formUpload(Map<String, String> textMap, Map<String, String> fileMap) { 43 String res = ""; 44 HttpURLConnection conn = null; 45 String BOUNDARY = "---------------------------123821742118716"; // boundary就是request头和上传文件内容的分隔符 46 try { 47 URL url = new URL(urlStr); 48 conn = (HttpURLConnection) url.openConnection(); 49 conn.setConnectTimeout(5000); 50 conn.setReadTimeout(30000); 51 conn.setDoOutput(true); 52 conn.setDoInput(true); 53 conn.setUseCaches(false); 54 conn.setRequestMethod("POST"); 55 conn.setRequestProperty("Connection", "Keep-Alive"); 56 conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 6.1; zh-CN; rv:1.9.2.6)"); 57 conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY); 58 59 OutputStream out = new DataOutputStream(conn.getOutputStream()); 60 // text 61 if (textMap != null) { 62 StringBuffer strBuf = new StringBuffer(); 63 Iterator<?> iter = textMap.entrySet().iterator(); 64 while (iter.hasNext()) { 65 Map.Entry entry = (Map.Entry) iter.next(); 66 String inputName = (String) entry.getKey(); 67 String inputValue = (String) entry.getValue(); 68 if (inputValue == null) { 69 continue; 70 } 71 strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n"); 72 strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"\r\n\r\n"); 73 strBuf.append(inputValue); 74 } 75 out.write(strBuf.toString().getBytes()); 76 } 77 78 // file 79 if (fileMap != null) { 80 Iterator<?> iter = fileMap.entrySet().iterator(); 81 while (iter.hasNext()) { 82 Map.Entry entry = (Map.Entry) iter.next(); 83 String inputName = (String) entry.getKey(); 84 String inputValue = (String) entry.getValue(); 85 if (inputValue == null) { 86 continue; 87 } 88 File file = new File(inputValue); 89 String filename = file.getName(); 90 String contentType = new MimetypesFileTypeMap().getContentType(file); 91 if (filename.endsWith(".jpg")) { 92 contentType = "image/jpg"; 93 } 94 if (contentType == null || contentType.equals("")) { 95 contentType = "application/octet-stream"; 96 } 97 98 StringBuffer strBuf = new StringBuffer(); 99 strBuf.append("\r\n").append("--").append(BOUNDARY).append("\r\n"); 100 strBuf.append("Content-Disposition: form-data; name=\"" + inputName + "\"; filename=\"" + filename 101 + "\"\r\n"); 102 strBuf.append("Content-Type:" + contentType + "\r\n\r\n"); 103 104 out.write(strBuf.toString().getBytes()); 105 106 DataInputStream in = new DataInputStream(new FileInputStream(file)); 107 int bytes = 0; 108 byte[] bufferOut = new byte[1024]; 109 while ((bytes = in.read(bufferOut)) != -1) { 110 out.write(bufferOut, 0, bytes); 111 } 112 in.close(); 113 } 114 } 115 116 byte[] endData = ("\r\n--" + BOUNDARY + "--\r\n").getBytes(); 117 out.write(endData); 118 out.flush(); 119 out.close(); 120 121 // 读取返回数据 122 StringBuffer strBuf = new StringBuffer(); 123 BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); 124 String line = null; 125 while ((line = reader.readLine()) != null) { 126 strBuf.append(line).append("\n"); 127 } 128 res = strBuf.toString(); 129 reader.close(); 130 reader = null; 131 } catch (Exception e) { 132 System.out.println("发送POST请求出错。" + urlStr); 133 e.printStackTrace(); 134 } finally { 135 if (conn != null) { 136 conn.disconnect(); 137 conn = null; 138 } 139 } 140 return res; 141 } 142 143 }
我们将工具类写好之后就需要在我们消息回复中加入对应的响应代码,这里为了测试我将响应代码加在【关注事件】中!
(二)图片回复
这里我们需要修改的是我们的【事件消息业务分发器】的代码,这里我们将我们的回复加在【关注事件】中,简单代码如下:
1 String openid = map.get("FromUserName"); // 用户openid 2 String mpid = map.get("ToUserName"); // 公众号原始ID 3 ImageMessage imgmsg = new ImageMessage(); 4 imgmsg.setToUserName(openid); 5 imgmsg.setFromUserName(mpid); 6 imgmsg.setCreateTime(new Date().getTime()); 7 imgmsg.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_Image); 8 if (map.get("Event").equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { // 关注事件 9 System.out.println("==============这是关注事件!"); 10 Image img = new Image(); 11 HttpPostUploadUtil util=new HttpPostUploadUtil(); 12 String filepath="H:\\1.jpg"; 13 Map<String, String> textMap = new HashMap<String, String>(); 14 textMap.put("name", "testname"); 15 Map<String, String> fileMap = new HashMap<String, String>(); 16 fileMap.put("userfile", filepath); 17 String mediaidrs = util.formUpload(textMap, fileMap); 18 System.out.println(mediaidrs); 19 String mediaid=JSONObject.fromObject(mediaidrs).getString("media_id"); 20 img.setMediaId(mediaid); 21 imgmsg.setImage(img); 22 return MessageUtil.imageMessageToXml(imgmsg); 23 }
到这里代码基本就已经完成整个的图片消息回复的内容,同样的不论是语音回复、视频回复等流程都是一样的,下一篇再练习一个关于语音回复的,最后的大致效果如下: