码迷,mamicode.com
首页 > 微信 > 详细

微信公众号基础开发

时间:2015-09-07 11:09:52      阅读:451      评论:0      收藏:0      [点我收藏+]

标签:

1.申请一个微信公众号(个人订阅号即可)

2.申请成为开发者,并打开开发者模式

  注:开发者模式和编辑模式 两者互斥,不能同时开启

3.外网映射工具ngrok,下载地址:http://pan.baidu.com/s/1o6mXNDK

4.验证服务器的有效性

  技术分享

  1).获取get请求携带的四个参数

技术分享
 1 package com.weinxin.servlet;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.util.Date;
 6 import java.util.Map;
 7 
 8 import javax.servlet.ServletException;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 
13 import com.weinxin.util.CheckUtils;
14 import com.weinxin.util.MessageUtil;
15 import com.weixin.entity.TextMessage;
16 
17 /**
18  * 微信接入
19  * @author chen
20  *
21  */
22 public class GetWxServlet extends HttpServlet{
23 
24     private static final long serialVersionUID = 1L;
25 
26     /**
27      * 验证服务器地址的有效性
28      */
29     @Override
30     @SuppressWarnings("static-access")
31     protected void doGet(HttpServletRequest requset, HttpServletResponse response)
32             throws ServletException, IOException {
33         
34         //微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
35         String signature = requset.getParameter("signature");
36         //时间戳
37         String timestamp = requset.getParameter("timestamp");
38         //随机数
39         String nonce = requset.getParameter("nonce");
40         //随机字符串
41         String echostr = requset.getParameter("echostr");
42         
43         CheckUtils cu = new CheckUtils();
44         
45         PrintWriter pw = response.getWriter();
46         
47         if(cu.checkSignature(signature, timestamp, nonce)){
48             pw.println(echostr);
49         }
50         
51     }
52     
53 }
GetWxServlet.java

  2).校验此次get请求是否来自微信服务器

技术分享
 1 package com.weinxin.util;
 2 
 3 import java.io.UnsupportedEncodingException;
 4 import java.security.MessageDigest;
 5 import java.security.NoSuchAlgorithmException;
 6 import java.util.Arrays;
 7 
 8 /**
 9  * 校验此次get请求是否来自微信服务器
10  * 加密/校验流程如下:
11  *    1. 将token、timestamp、nonce三个参数进行字典序排序
12  *    2. 将三个参数字符串拼接成一个字符串进行sha1加密
13  *    3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
14  * @author chen
15  *
16  */
17 public class CheckUtils {
18     
19     private static final String token = "***";//此处的token必须与服务器配置页面填写的token一致
20 
21     public static boolean checkSignature(String signature, String timestamp, String nonce){
22         
23         String[] arr = new String[]{token, timestamp, nonce};
24         //排序
25         Arrays.sort(arr);
26         //生成字符串
27         StringBuffer content = new StringBuffer();
28         //将需要的数值追加到content中
29         for(int i = 0; i < arr.length; i++){
30             content.append(arr[i]);
31         }
32         //sha1加密
33         String temp = getSha1(content.toString());
34         //返回结果
35         return temp.equals(signature);
36         
37     }
38     
39     /**
40      * sha1加密算法
41      * @param str
42      * @return
43      */
44     private static String getSha1(String str){
45         
46         if(str == null || str.length() == 0){
47             return null;
48         }
49         //十六进制数组
50         char hexDigits[] = {‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, 
51                 ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘};
52         try {
53             //创建具有指定算法名称的MessageDigest实例对象
54             MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
55             //通过调用update方法向MessageDigest对象传送要计算的数据,然后调用以下某个digest方法来计算摘要,即生成散列码
56             mdTemp.update(str.getBytes("UTF-8"));
57             //生成散列码
58             byte[] md = mdTemp.digest();
59             //计算散列码的长度
60             int i = md.length;
61             char buf[] = new char[i * 2];
62             int j = 0;
63             for(int k = 0; k < i; k++){
64                 byte byte0 = md[k];
65                 buf[j++] = hexDigits[byte0 >>> 4 & 0xf];
66                 buf[j++] = hexDigits[byte0 & 0xf];
67             }
68             return new String(buf);
69         } catch (NoSuchAlgorithmException e) {
70             e.printStackTrace();
71         } catch (UnsupportedEncodingException e) {
72             e.printStackTrace();
73         }
74         return null;
75         
76     }
77     
78 }
CheckUtils.java

    3).打开外网映射工具,在cmd中将当前目前切换至ngrok所在目录,然后执行ngrok -config ngrok.cfg -subdomain example 8080example自定义,执行成功后入下图:

  技术分享

  4).配置web.xml

    通过配置web.xml,正确的将请求转发到相应的处理类中,配置如下:

    技术分享
  5).配置服务器配置(开发者中心->服务器配置->修改配置)

    URL:填写上一步骤中ngrok生成的地址(比如:http://example.tunnel.mobi),再加上项目名和请求名(比如:weixin/weixin.do)

        weixin.do即为web.xml中的url-pattern中的请求名

        完整的URL即为http://example.tunnel.mobi/weixin/weixin.do

    token:可以随机填写,但此处填写的token必须与CheckUtils.java中的token保持一致

    EncodingAESKey:随机生成即可

    消息加解密方式:明文即可

    技术分享

    点击提交,若一切无误则提交成功!如果出现token验证失败,则检查此处的token是否与CheckUtils.java中的token一致。此时微信接入已成功!

5.消息自动回复

  ?当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

  其中文本消息的格式为:

  技术分享

  1).创建文本消息的实体类

技术分享
 1 package com.weixin.entity;
 2 
 3 public class TextMessage {
 4 
 5     private String ToUserName;//开发者微信号
 6     private String FromUserName;//发送方账号
 7     private long CreateTime;//消息创建时间
 8     private String MsgType;//text
 9     private String Content;//文本消息内容
10     private String MsgId;//消息id,64位整形
11     
12     public String getToUserName() {
13         return ToUserName;
14     }
15     public void setToUserName(String toUserName) {
16         ToUserName = toUserName;
17     }
18     public String getFromUserName() {
19         return FromUserName;
20     }
21     public void setFromUserName(String fromUserName) {
22         FromUserName = fromUserName;
23     }
24     public long getCreateTime() {
25         return CreateTime;
26     }
27     public void setCreateTime(long l) {
28         CreateTime = l;
29     }
30     public String getMsgType() {
31         return MsgType;
32     }
33     public void setMsgType(String msgType) {
34         MsgType = msgType;
35     }
36     public String getContent() {
37         return Content;
38     }
39     public void setContent(String content) {
40         Content = content;
41     }
42     public String getMsgId() {
43         return MsgId;
44     }
45     public void setMsgId(String msgId) {
46         MsgId = msgId;
47     }
48     
49 }
TextMessage.java

    2).创建格式转换类

技术分享
 1 package com.weinxin.util;
 2 
 3 import java.io.IOException;
 4 import java.io.InputStream;
 5 import java.util.HashMap;
 6 import java.util.List;
 7 import java.util.Map;
 8 
 9 import javax.servlet.http.HttpServletRequest;
10 
11 import org.dom4j.Document;
12 import org.dom4j.DocumentException;
13 import org.dom4j.Element;
14 import org.dom4j.io.SAXReader;
15 
16 import com.thoughtworks.xstream.XStream;
17 import com.weixin.entity.TextMessage;
18 
19 /**
20  * 类型转换类
21  * @author chen
22  *
23  */
24 public class MessageUtil {
25 
26     /**
27      * 将xml中转化为map
28      * @param request
29      * @return
30      */
31     @SuppressWarnings("unchecked")
32     public static Map<String, String> xmlToMap(HttpServletRequest request){
33         
34         Map<String, String> map = new HashMap<String, String>();
35         SAXReader reader = new SAXReader();
36         try {
37             //从request中获取输入流
38             InputStream is = request.getInputStream();
39             //获取document对象,即文档对象
40             Document doc = reader.read(is);
41             //获取根节点
42             Element root = doc.getRootElement();
43             //将根节点下的数据写入list中
44             List<Element> list = root.elements();
45             //遍历list,将数据放入map中
46             for(Element e: list){
47                 map.put(e.getName(), e.getText());
48             }
49             //关闭输入流
50             is.close();
51         } catch (IOException e) {
52             e.printStackTrace();
53         } catch (DocumentException e) {
54             e.printStackTrace();
55         }
56         return map;
57         
58     }
59     
60     /**
61      * 将文本对象转化为xml
62      * @param textMessage
63      * @return
64      */
65     public static String textMessageToXml(TextMessage textMessage){
66         
67         XStream stream = new XStream();
68         //将序列化中的类全量名称,用别名替换
69         //即将根节点由"com.weixin.entity.TextMessage"转化为"xml"
70         stream.alias("xml", textMessage.getClass());
71         return stream.toXML(textMessage);
72         
73     }
74     
75 }
MessageUtil.java

  3).消息回复

技术分享
 1 package com.weinxin.servlet;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 import java.util.Date;
 6 import java.util.Map;
 7 
 8 import javax.servlet.ServletException;
 9 import javax.servlet.http.HttpServlet;
10 import javax.servlet.http.HttpServletRequest;
11 import javax.servlet.http.HttpServletResponse;
12 
13 import com.weinxin.util.CheckUtils;
14 import com.weinxin.util.MessageUtil;
15 import com.weixin.entity.TextMessage;
16 
17 /**
18  * 微信接入
19  * @author chen
20  *
21  */
22 public class GetWxServlet extends HttpServlet{
23 
24     private static final long serialVersionUID = 1L;
25 
26     /**
27      * 验证服务器地址的有效性
28      */
29     @Override
30     @SuppressWarnings("static-access")
31     protected void doGet(HttpServletRequest requset, HttpServletResponse response)
32             throws ServletException, IOException {
33         
34         //微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数
35         String signature = requset.getParameter("signature");
36         //时间戳
37         String timestamp = requset.getParameter("timestamp");
38         //随机数
39         String nonce = requset.getParameter("nonce");
40         //随机字符串
41         String echostr = requset.getParameter("echostr");
42         
43         CheckUtils cu = new CheckUtils();
44         
45         //获取response的输出流
46         PrintWriter pw = response.getWriter();
47         
48         if(cu.checkSignature(signature, timestamp, nonce)){
49             pw.println(echostr);
50         }
51         
52     }
53     
54     /**
55      * 自动回复用户发送的消息
56      */
57     @SuppressWarnings("static-access")
58     @Override
59     protected void doPost(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
60 
61         //设置编码格式
62         requset.setCharacterEncoding("UTF-8");
63         response.setCharacterEncoding("UTF-8");
64         
65         MessageUtil mu = new MessageUtil();
66         TextMessage tm = new TextMessage();
67         
68         PrintWriter pw = response.getWriter();
69         
70         Map<String, String> map = mu.xmlToMap(requset);
71         String fromUserName = map.get("FromUserName");
72         String toUserName = map.get("ToUserName");
73         String msgType = map.get("MsgType");
74         String content = map.get("Content");
75         String message = null;
76         
77         if("text".equals(msgType)){//文本消息
78             tm.setFromUserName(toUserName);
79             tm.setToUserName(fromUserName);
80             tm.setMsgType("text");
81             tm.setCreateTime(new Date().getTime());
82             tm.setContent("您发送的消息是:" + content);
83             message = mu.textMessageToXml(tm);
84         }
85         pw.write(message);
86         pw.close();
87     
88     }
89     
90 }
GetWxServlet.java

  然后关注该公众号,发送消息测试即可。

  此处只是大致介绍,更多内容请参考官方文档:http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html

    参考:http://www.imooc.com

微信公众号基础开发

标签:

原文地址:http://www.cnblogs.com/jinjiyese/p/4788221.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!