Java微信二次开发
Posted wangtianze
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java微信二次开发相关的知识,希望对你有一定的参考价值。
消息加密
需要到入库:commons-io-2.4.jar,commons-codec-1.9.jar(在官网的Java微信加密demo下)
第一步:访问https://mp.weixin.qq.com/wiki,下载AES加密的示例代码
第二步:新建com.wtz.aes包,把实例代码中的8个AES加密类复制进去,将这些类的包名改为com.wtz.aes,导入库commons-codec-1.9.jar,选上面的Project下的Properties,点击Java Build Path,Libraries,Add Library,选Junit 4,Next,Finish,OK,AES加密导入完成
第三步:找到包com.wtz.util,新建类Parameter.java类,存放参数token,encodingAESKey(随机戳),corpId(AppID),这些在基本配置处可以得到
1 package com.wtz.util; 2 3 /** 4 * @author wangtianze QQ:864620012 5 * @date 2017年4月21日 下午9:27:50 6 * <p>version:1.0</p> 7 * <p>description:参数api</p> 8 */ 9 public class Parameter { 10 //token 11 public static String token = "wangtianze"; 12 //随机戳 13 public static String encodingAESKey = "X78dYU3MXpijKArRbiozTRq0jZZnjxxvuB4n8KJwRH1"; 14 //应用AppID 15 public static String corpId = "wx9621c31e147dfdf9"; 16 }
第四步:找到包com.wtz.util下的MessageUtil.java类,修改parseXml方法
1 package com.wtz.util; 2 3 import java.io.ByteArrayInputStream; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.Writer; 7 import java.util.HashMap; 8 import java.util.List; 9 import java.util.Map; 10 11 import javax.servlet.http.HttpServletRequest; 12 13 import org.dom4j.Document; 14 import org.dom4j.DocumentException; 15 import org.dom4j.Element; 16 import org.dom4j.io.SAXReader; 17 18 import com.thoughtworks.xstream.XStream; 19 import com.thoughtworks.xstream.core.util.QuickWriter; 20 import com.thoughtworks.xstream.io.HierarchicalStreamWriter; 21 import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; 22 import com.thoughtworks.xstream.io.xml.XppDriver; 23 import com.wtz.message.response.ImageMessage; 24 import com.wtz.message.response.MusicMessage; 25 import com.wtz.message.response.NewsMessage; 26 import com.wtz.message.response.TextMessage; 27 import com.wtz.message.response.VideoMessage; 28 import com.wtz.message.response.VoiceMessage; 29 30 /** 31 * @author wangtianze QQ:864620012 32 * @date 2017年4月19日 下午3:29:58 33 * <p>version:1.0</p> 34 * <p>description:消息处理工具类</p> 35 */ 36 public class MessageUtil { 37 //请求消息类型:文本 38 public static final String REQ_MESSAGE_TYPE_TEXT = "text"; 39 //请求消息类型:图片 40 public static final String REQ_MESSAGE_TYPE_IMAGE = "image"; 41 //请求消息类型:语音 42 public static final String REQ_MESSAGE_TYPE_VOICE = "voice"; 43 //请求消息类型:视频 44 public static final String REQ_MESSAGE_TYPE_VIDEO = "video"; 45 //请求消息类型:地理位置 46 public static final String REQ_MESSAGE_TYPE_LOCATION = "location"; 47 //请求消息类型:链接 48 public static final String REQ_MESSAGE_TYPE_LINK = "link"; 49 //请求消息类型:事件推送 50 public static final String REQ_MESSAGE_TYPE_EVENT = "event"; 51 52 //--------------------------------------------------------------- 53 54 //事件类型:subscribe(订阅) 55 public static final String EVENT_TYPE_SUBSCRIBE = "subscribe"; 56 //事件类型:unsubscribe(取消订阅) 57 public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe"; 58 //事件类型:scan(用户已关注时的扫描带参数的二维码) 59 public static final String EVENT_TYPE_SCAN = "scan"; 60 //事件类型:LOCATION(上报地理位置) 61 public static final String EVENT_TYPE_LOCATION = "LOCATION"; 62 //事件类型:CLICK(自定义菜单) 63 public static final String EVENT_TYPE_CLICK = "CLICK"; 64 65 //--------------------------------------------------------------- 66 67 //响应消息类型:文本 68 public static final String RESP_MESSAGE_TYPE_TEXT = "text"; 69 //响应详细类型:图片 70 public static final String RESP_MESSAGE_TYPE_IMAGE = "image"; 71 //响应消息类型:语音 72 public static final String RESP_MESSAGE_TYPE_VOICE = "voice"; 73 //响应消息类型:视频 74 public static final String RESP_MESSAGE_TYPE_VIDEO = "video"; 75 //响应详细类型:音乐 76 public static final String RESP_MESSAGE_TYPE_MUSIC = "music"; 77 //响应消息类型:图文 78 public static final String RESP_MESSAGE_TYPE_NEWS = "news"; 79 80 //--------------------------------------------------------------- 81 82 //-----------------------------------------老的,加密前--------------------------------------------- 83 // //从流中解析出每个节点的内容 84 // public static Map<String,String> parseXml(HttpServletRequest request) throws IOException{ 85 // Map<String,String> map = new HashMap<String,String>(); 86 // 87 // //从输入流中获取流对象 88 // InputStream in = request.getInputStream(); 89 // 90 // //构建SAX阅读器对象 91 // SAXReader reader = new SAXReader(); 92 // try { 93 // //从流中获得文档对象 94 // Document doc = reader.read(in); 95 // 96 // //获得根节点 97 // Element root = doc.getRootElement(); 98 // 99 // //获取根节点下的所有子节点 100 // List<Element> children = root.elements(); 101 // 102 // for(Element e:children){ 103 // //遍历每一个节点,并按照节点名--节点值放入map中 104 // map.put(e.getName(), e.getText()); 105 // System.out.println("用户发送的消息XML解析为:" + e.getName() + e.getText()); 106 // } 107 // 108 // //关闭流 109 // in.close(); 110 // in = null; 111 // } catch (DocumentException e) { 112 // // TODO Auto-generated catch block 113 // e.printStackTrace(); 114 // } 115 // 116 // return map; 117 // } 118 //-----------------------------------------新的,加密后-------------------------------------------- 119 //从流中解析出每个节点的内容 120 public static Map<String,String> parseXml(String request) throws IOException{ 121 Map<String,String> map = new HashMap<String,String>(); 122 123 //从request中获取流对象 124 InputStream in = new ByteArrayInputStream(request.getBytes("UTF-8")); 125 126 //构建SAX阅读器对象 127 SAXReader reader = new SAXReader(); 128 try { 129 //从流中获得文档对象 130 Document doc = reader.read(in); 131 132 //获得根节点 133 Element root = doc.getRootElement(); 134 135 //获取根节点下的所有子节点 136 List<Element> children = root.elements(); 137 138 for(Element e:children){ 139 //遍历每一个节点,并按照节点名--节点值放入map中 140 map.put(e.getName(), e.getText()); 141 System.out.println("用户发送的消息XML解析为:" + e.getName() + e.getText()); 142 } 143 144 //关闭流 145 in.close(); 146 in = null; 147 } catch (DocumentException e) { 148 // TODO Auto-generated catch block 149 e.printStackTrace(); 150 } 151 152 return map; 153 } 154 //---------------------------------------------------------------------------------------------- 155 156 /** 157 * 用于扩展节点数据按照<ToUserName><![CDATA[toUser]]></ToUserName>,中间加了CDATA段 158 */ 159 private static XStream xstream = new XStream(new XppDriver(){ 160 public HierarchicalStreamWriter createWriter(Writer out){ 161 return new PrettyPrintWriter(out){ 162 boolean cdata = true; 163 public void startNode(String name,Class clazz){ 164 super.startNode(name,clazz); 165 } 166 167 protected void writeText(QuickWriter writer,String text){ 168 if(cdata){ 169 writer.write("<![CDATA["); 170 writer.write(text); 171 writer.write("]]>"); 172 }else{ 173 writer.write(text); 174 } 175 } 176 }; 177 } 178 }); 179 180 /** 181 * 将文本消息对象转换成XML格式 182 * params:textMessage 文本消息对象 183 * return:xml 184 */ 185 public static String messageToXml(TextMessage textMessage){ 186 xstream.alias("xml",textMessage.getClass()); 187 return xstream.toXML(textMessage); 188 } 189 190 /** 191 * 将图片消息对象转换成XML格式 192 * params:imageMessage 193 * return:xml 194 */ 195 public static String messageToXml(ImageMessage imageMessage){ 196 xstream.alias("xml", imageMessage.getClass()); 197 return xstream.toXML(imageMessage); 198 } 199 200 /** 201 * 将语音消息对象转换成XML格式 202 * params:voiceMessage 203 * return:xml 204 */ 205 public static String messageToXml(VoiceMessage voiceMessage){ 206 xstream.alias("xml",voiceMessage.getClass()); 207 return xstream.toXML(voiceMessage); 208 } 209 210 /** 211 * 将视频消息对象转换成XML格式 212 * params:videoMessage 213 * return:xml 214 */ 215 public static String messageToXml(VideoMessage videoMessage){ 216 xstream.alias("xml",videoMessage.getClass()); 217 return xstream.toXML(videoMessage); 218 } 219 220 /** 221 * 将音乐消息对象转换成XML格式 222 * params:musicMessage 223 * return:xml 224 */ 225 public static String messageToXml(MusicMessage musicMessage){ 226 xstream.alias("xml",musicMessage.getClass()); 227 return xstream.toXML(musicMessage); 228 } 229 230 /** 231 * 将图文消息对象转换成XML格式 232 * params:newsMessage 233 * return:xml 234 */ 235 public static String messageToXml(NewsMessage newsMessage){ 236 xstream.alias("xml",newsMessage.getClass()); 237 return xstream.toXML(newsMessage); 238 } 239 }
第五步:找到包com.wtz.util下的ProcessService.java类,修改dealRequest方法
1 package com.wtz.util; 2 3 import java.io.IOException; 4 import java.util.Date; 5 import java.util.Map; 6 7 import javax.servlet.http.HttpServletRequest; 8 9 import com.wtz.dao.PostCodeDao; 10 import com.wtz.message.response.TextMessage; 11 12 /** 13 * @author wangtianze QQ:864620012 14 * @date 2017年4月19日 下午8:04:14 15 * <p>version:1.0</p> 16 * <p>description:核心服务类</p> 17 */ 18 public class ProcessService { 19 //定义数据访问的dao 20 private static PostCodeDao dao = new PostCodeDao(); 21 22 //-----------------------------------老的,加密前-------------------------------------------------- 23 // public static String dealRequest(HttpServletRequest request){ 24 // //XML格式的消息数据 25 // String respXml = ""; 26 // //默认返回的文本消息内容 27 // String respContent = "未知的消息类型"; 28 // //调用parseXml方法解析请求消息 29 // Map<String, String> requestMap; 30 // try { 31 // requestMap = MessageUtil.parseXml(request); 32 // //发送方账号 33 // String fromUserName = requestMap.get("FromUserName"); 34 // //开发者微信号 35 // String toUserName = requestMap.get("ToUserName"); 36 // //消息类型 37 // String MsgType = requestMap.get("MsgType"); 38 // //消息内容 39 // String content = requestMap.get("Content"); 40 // 41 // //回复文本消息 42 // TextMessage textMessage = new TextMessage(); 43 // textMessage.setToUserName(fromUserName); 44 // textMessage.setFromUserName(toUserName); 45 // textMessage.setCreateTime(new Date().getTime()); 46 // textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT); 47 // 48 // if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)){ 49 // respContent = "感谢您关注【王天泽的服务号】\\n" + "微信号:wangtianze1\\n" + "请回复序号:\\n" + "1.查邮政编码\\n" + "2.查电话区号\\n" + "?.返回帮助菜单\\n"; 50 // if(content.equals("1")){ 51 // respContent = "请按照格式输入地区名,例如输入 邮编:东城"; 52 // } 53 // if(content.equals("2")){ 54 // respContent = "请按照格式输入地区名,例如输入 区号:东城"; 55 // } 56 // if(content.equals("?")){ 57 // respContent = "感谢您关注【王天泽的服务号】\\n" + "微信号:wangtianze1\\n" + "请回复序号:\\n" + "1.查邮政编码\\n" + "2.查电话区号\\n" + "?.返回帮助菜单\\n"; 58 // } 59 // if(content.startsWith("邮编:")){ 60 // int pos = content.indexOf(":"); 61 // String cityName = content.substring(pos + 1); 62 // respContent = dao.findPostCodeByCityName(cityName); 63 // System.out.println("邮编:respContent:" + respContent); 64 // } 65 // if(content.startsWith("区号:")){ 66 // int pos = content.indexOf(":"); 67 // String cityName = content.substring(pos + 1); 68 // respContent = dao.findTelCodeByCityName(cityName); 69 // System.out.println("区号:respContent:" + respContent); 70 // } 71 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)){ 72 // respContent = "您发送的是图片消息"; 73 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)){ 74 // respContent = "您发送的是语音消息"; 75 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)){ 76 // respContent = "您发送的是视频消息"; 77 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)){ 78 // respContent = "您发送的是地理位置消息"; 79 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)){ 80 // respContent = "您发送的是链接消息"; 81 // }else if(MsgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)){ 82 // //事件类型 83 // String eventType = requestMap.get("Event"); 84 // if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){ 85 // respContent = "感谢您关注【王天泽的服务号】\\n" + "微信号:wangtianze1\\n" + "请回复序号:\\n" + "1.查邮政编码\\n" + "2.查电话区号\\n" + "?.返回帮助菜单\\n"; 86 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){ 87 // //TODO 取消订阅后用户不会再收到公众号发送的消息,因此不需要回复 88 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)){ 89 // //TODO 处理扫描带参数二维码事件 90 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)){ 91 // //TODO 处理上报地理位置事件 92 // }else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){ 93 // //TODO 处理菜单点击事件 94 // } 95 // } 96 // //设置文本消息的内容 97 // textMessage.setContent(respContent); 98 // //将文本消息对象转换成xml 99 // respXml = MessageUtil.messageToXml(textMessage); 100 // } catch (IOException e) { 101 // // TODO Auto-generated catch block 102 // e.printStackTrace(); 103 // } 104 // 105 // return respXml; 106 // } 以上是关于Java微信二次开发的主要内容,如果未能解决你的问题,请参考以下文章