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微信二次开发的主要内容,如果未能解决你的问题,请参考以下文章

微信二次开发自定义接受事件推送的代码

微信二次开发SDK

微信二次分享功能开发笔记

微信二次开发sdk使用教程--手机微信上回复好友的聊天消息通知服务端

微信二次开发点击菜单openId的获取

微信二次开发 之 微信文本消息接口实现