微信公众帐号开拓教程第四篇—–开采情势启用及接口配置Java

 

应接参加群:347245650   3455318拾 实行座谈互相调换 我的微实信号:572839485**

本篇内容入眼教师咋样将微信公众平台定义的新闻及音信相关的操作封装成工具类,方面中期的接纳 官方文书档案

自己的微信公众账号
 作者的微社区招待关心
索取源码←请点击

图片 1

图片 2图片 3

 

 

接下去要做的正是将消息请求、回复中定义的音讯进行李包裹装,建立与之相应的Java类(Java是一门面向对象的编制程序语言,封装后使用起来更方便人民群众),下边包车型地铁伏乞新闻是指新闻推送中定义的音讯,响应新闻指音讯回复中定义的音讯。

图床:未有服务器 拖拽图片
外网就可以访问

http://2.crazyflower.duapp.com/home

音信的基类

微信公众帐号申请成功后,要想吸收管理用户的呼吁,就不能不要在“高端效率”里开始展览布局,点击“高等功用”,将见到如下分界面

把新闻推送中定义的具有音讯都有的字段提抽出来,封装成二个基类,这个公有的字段包蕴:ToUserName(开垦者微复信号)、FromUserName(发送方帐号,OPEN_ID)、CreateTime(音讯的创造时间)、MsgType(音信类型)、MsgId(新闻ID),封装后基类

图片 4

 1 package com.javen.course.message.resp;
 2 
 3 /**
 4  * 响应消息的基类
 5  * 消息基类(公众帐号 -> 普通用户)
 6  * @author Javen
 7  * @Email zyw205@gmail.com
 8  *
 9  */
10 public class BaseMessage {
11     // 接收方帐号(收到的OpenID)
12     private String ToUserName;
13     // 开发者微信号
14     private String FromUserName;
15     // 消息创建时间 (整型)
16     private long CreateTime;
17     // 消息类型(text/music/news)
18     private String MsgType;
19     // 位0x0001被标志时,星标刚收到的消息
20     private int FuncFlag;
21 
22     public String getToUserName() {
23         return ToUserName;
24     }
25 
26     public void setToUserName(String toUserName) {
27         ToUserName = toUserName;
28     }
29 
30     public String getFromUserName() {
31         return FromUserName;
32     }
33 
34     public void setFromUserName(String fromUserName) {
35         FromUserName = fromUserName;
36     }
37 
38     public long getCreateTime() {
39         return CreateTime;
40     }
41 
42     public void setCreateTime(long createTime) {
43         CreateTime = createTime;
44     }
45 
46     public String getMsgType() {
47         return MsgType;
48     }
49 
50     public void setMsgType(String msgType) {
51         MsgType = msgType;
52     }
53 
54     public int getFuncFlag() {
55         return FuncFlag;
56     }
57 
58     public void setFuncFlag(int funcFlag) {
59         FuncFlag = funcFlag;
60     }
61 }

从上海教室中得以看来,高等成效包蕴三种情势:编辑格局和付出方式,并且那三种格局是排斥关系,即二种方式无法而且开启。那两种方式有何样不一样吗?

信息之文本音讯

编制情势:首要针对非编程人士及音讯发布类公众帐号应用。开启该方式后,可以方便地通过界面配置“自定蒿子单”(认证的订阅号、服务号)和“自动回复的新闻”。

 

支付方式:重在针对富有开拓才干的人利用。开启该形式后,能够利用微信公众平台开放的接口,通过编制程序格局贯彻自定蒿子杆单的创导、删除、用户音讯的相互。那种情势越来越灵活,建议有接触过支付的人士用该格局。

 1 package com.javen.course.message.resp;
 2 
 3 /**
 4  * 文本消息
 5  * @author Javen
 6  * @Email zyw205@gmail.com
 7  *
 8  */
 9 public class TextMessage extends BaseMessage {
10     // 回复的消息内容
11     private String Content;
12 
13     public String getContent() {
14         return Content;
15     }
16 
17     public void setContent(String content) {
18         Content = content;
19     }
20 }

编排格局与支出形式 2者只可以张开一个

1、编辑情势请看:http://www.cnblogs.com/zyw-205520/p/3516495.html

二、开拓情势 

** 
一)PHP开辟者接入:http://www.cnblogs.com/zyw-205520/p/3500761.html
 
 二)Java开荒者接入如下
详细的接口文书档案表明:微信接口文书档案


   制造多个Java Web工程,命名自便**
代码如下 


 1 package com.javen.course.servlet;
 2 
 3 import java.io.IOException;
 4 import java.io.PrintWriter;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 import com.javen.course.service.CrazyService;
12 import com.javen.course.util.SignUtil;
13 
14 /**
15  * 核心请求处理类 
16  * @author 简爱微萌
17  * @Email zyw205@gmail.com
18  * 
19  */
20 public class CrazyServlet extends HttpServlet {
21 
22     private static final long serialVersionUID = -5021188348833856475L;
23     @Override
24     protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
25         // 微信加密签名  
26         String signature = request.getParameter("signature");  
27         // 时间戳  
28         String timestamp = request.getParameter("timestamp");  
29         // 随机数  
30         String nonce = request.getParameter("nonce");  
31         // 随机字符串  
32         String echostr = request.getParameter("echostr");  
33         PrintWriter out = response.getWriter();  
34         // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败  
35         if (SignUtil.checkSignature(signature, timestamp, nonce)) {  
36             out.print(echostr);  
37         }  
38         out.close();
39         out = null;
40     }
41     
42     
43     @Override
44     protected void doPost(HttpServletRequest request, HttpServletResponse response)
45             throws ServletException, IOException {
46         // TODO 消息的接收、处理、响应  
47     }
48 }

代码中只完结了doGet方法,它的成效便是确认请求是不是来自于微信服务器;而doPost方法那里表达不须要我们先放着。

在doGet方法中调用了SignUtil.java 落成代码如下 一 package com.javen.course.util;

 

 1 package com.javen.course.util;
 2 
 3 import java.security.MessageDigest;
 4 import java.security.NoSuchAlgorithmException;
 5 import java.util.Arrays;
 6 
 7 /**
 8  * 请求校验工具类
 9  * 
10  * @author 简爱微萌
11  * @Email zyw205@gmial.com
12  * 
13  */
14 public class SignUtil {
15     // 与接口配置信息中的Token要一致
16     private static String token = "Javen";
17 
18     /**
19      * 验证签名
20      * 
21      * @param signature
22      * @param timestamp
23      * @param nonce
24      * @return
25      */
26     public static boolean checkSignature(String signature, String timestamp,
27             String nonce) {
28         String[] arr = new String[] { token, timestamp, nonce };
29         // 将token、timestamp、nonce三个参数进行字典序排序
30         //Arrays.sort(arr);
31         sort(arr);
32         StringBuilder content = new StringBuilder();
33         for (int i = 0; i < arr.length; i++) {
34             content.append(arr[i]);
35         }
36         MessageDigest md = null;
37         String tmpStr = null;
38 
39         try {
40             md = MessageDigest.getInstance("SHA-1");
41             // 将三个参数字符串拼接成一个字符串进行sha1加密
42             byte[] digest = md.digest(content.toString().getBytes());
43             tmpStr = byteToStr(digest);
44         } catch (NoSuchAlgorithmException e) {
45             e.printStackTrace();
46         }
47 
48         content = null;
49         // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
50         return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
51     }
52 
53     /**
54      * 将字节数组转换为十六进制字符串
55      * 
56      * @param byteArray
57      * @return
58      */
59     private static String byteToStr(byte[] byteArray) {
60         String strDigest = "";
61         for (int i = 0; i < byteArray.length; i++) {
62             strDigest += byteToHexStr(byteArray[i]);
63         }
64         return strDigest;
65     }
66 
67     /**
68      * 将字节转换为十六进制字符串
69      * 
70      * @param mByte
71      * @return
72      */
73     private static String byteToHexStr(byte mByte) {
74         char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
75                 'B', 'C', 'D', 'E', 'F' };
76         char[] tempArr = new char[2];
77         tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
78         tempArr[1] = Digit[mByte & 0X0F];
79 
80         String s = new String(tempArr);
81         return s;
82     }
83 
84     public static void sort(String a[]) {
85         for (int i = 0; i < a.length - 1; i++) {
86             for (int j = i + 1; j < a.length; j++) {
87                 if (a[j].compareTo(a[i]) < 0) {
88                     String temp = a[i];
89                     a[i] = a[j];
90                     a[j] = temp;
91                 }
92             }
93         }
94     }
95 }

 

 

 

小心:SignUtil类中的成员变量token,那里赋予什么值,在接口配置音讯中的Token就要填写什么值,两边要保持一致

最后再来看一下CoreServlet是怎么安顿的,web.xml中的配置代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
 3   <display-name></display-name>
 4   <servlet>
 5     <servlet-name>CrazyServlet</servlet-name>
 6     <servlet-class>  
 7             com.javen.course.servlet.CrazyServlet 
 8         </servlet-class>
 9   </servlet>
15 
16   <servlet-mapping>
17     <servlet-name>CrazyServlet</servlet-name>
18     <url-pattern>/Javen</url-pattern>
19   </servlet-mapping>
20   
24   <welcome-file-list>
25     <welcome-file>index.jsp</welcome-file>
26   </welcome-file-list>
27 </web-app>

 

到近年来截至,全部编码都产生了,正是如此简单。接下来即是将工程宣布到公网服务器上,如若未有公网服务器意况,能够去打听下BAE、SAE或然租借二个服务器。公布到服务器上后,大家在浏览器里访http://你服务器的Ip或者域名/Javen(项目名)/Javen,如果看到如下界面就表示我们的代码没有问题:

图片 5

PS:在浏览器中直接待上访问就一定于付出的是GET请求,而笔者辈什么参数都不曾传,在表达的时候自然会报空指针卓殊。

 

最佳在职能>>高档功用>>开荒方式中填入对应的UPAJEROL和Token就能够 未有找到页面包车型大巴能够参照
 http://www.cnblogs.com/zyw-205520/p/3500761.html

 

自身的微信公众账号
人脸识别、天气查询、公共交通查询、周公解梦、星座运势、手提式有线电话机归属地询问、聊天唠嗑等

 

图片 6

 

 

  

 

 

音讯之地理地方消息

 1 package com.javen.course.message.resp;
 2 
 3 /**
 4  * 响应消息的基类
 5  * 消息基类(公众帐号 -> 普通用户)
 6  * @author Javen
 7  * @Email zyw205@gmial.com
 8  *
 9  */
10 public class BaseMessage {
11     // 接收方帐号(收到的OpenID)
12     private String ToUserName;
13     // 开发者微信号
14     private String FromUserName;
15     // 消息创建时间 (整型)
16     private long CreateTime;
17     // 消息类型(text/music/news)
18     private String MsgType;
19     // 位0x0001被标志时,星标刚收到的消息
20     private int FuncFlag;
21 
22     public String getToUserName() {
23         return ToUserName;
24     }
25 
26     public void setToUserName(String toUserName) {
27         ToUserName = toUserName;
28     }
29 
30     public String getFromUserName() {
31         return FromUserName;
32     }
33 
34     public void setFromUserName(String fromUserName) {
35         FromUserName = fromUserName;
36     }
37 
38     public long getCreateTime() {
39         return CreateTime;
40     }
41 
42     public void setCreateTime(long createTime) {
43         CreateTime = createTime;
44     }
45 
46     public String getMsgType() {
47         return MsgType;
48     }
49 
50     public void setMsgType(String msgType) {
51         MsgType = msgType;
52     }
53 
54     public int getFuncFlag() {
55         return FuncFlag;
56     }
57 
58     public void setFuncFlag(int funcFlag) {
59         FuncFlag = funcFlag;
60     }
61 }

**音讯之图像和文字新闻
**

 

 1 package com.javen.course.message.resp;
 2 
 3 import java.util.List;
 4 
 5 /**
 6  * 图文消息
 7  * @author Javen
 8  * @Email zyw205@gmial.com
 9  *
10  */
11 public class NewsMessage extends BaseMessage {
12     // 图文消息个数,限制为10条以内
13     private int ArticleCount;
14     // 多条图文消息信息,默认第一个item为大图
15     private List<Article> Articles;
16 
17     public int getArticleCount() {
18         return ArticleCount;
19     }
20 
21     public void setArticleCount(int articleCount) {
22         ArticleCount = articleCount;
23     }
24 
25     public List<Article> getArticles() {
26         return Articles;
27     }
28 
29     public void setArticles(List<Article> articles) {
30         Articles = articles;
31     }
32 }

图像和文字音信中Article类的实业

 

 1 package com.javen.course.message.resp;
 2 
 3 /**
 4  * 图文消息中Article类的定义
 5  * @author Javen
 6  * @Email zyw205@gmial.com
 7  *
 8  */
 9 public class Article {
10     // 图文消息名称
11     private String Title;
12     // 图文消息描述
13     private String Description;
14     // 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80,限制图片链接的域名需要与开发者填写的基本资料中的Url一致
15     private String PicUrl;
16     // 点击图文消息跳转链接
17     private String Url;
18 
19     public String getTitle() {
20         return Title;
21     }
22 
23     public void setTitle(String title) {
24         Title = title;
25     }
26 
27     public String getDescription() {
28         return null == Description ? "" : Description;
29     }
30 
31     public void setDescription(String description) {
32         Description = description;
33     }
34 
35     public String getPicUrl() {
36         return null == PicUrl ? "" : PicUrl;
37     }
38 
39     public void setPicUrl(String picUrl) {
40         PicUrl = picUrl;
41     }
42 
43     public String getUrl() {
44         return null == Url ? "" : Url;
45     }
46 
47     public void setUrl(String url) {
48         Url = url;
49     }
50 
51 }

 

 音信之音乐音信

 

 1 package com.javen.course.message.resp;
 2 
 3 /**
 4  * 音乐消息  响应消息之音乐消息
 5  * @author Javen
 6  * @Email zyw205@gmail.com
 7  *
 8  */
 9 public class MusicMessage extends BaseMessage {
10     // 音乐
11     private Music Music;
12 
13     public Music getMusic() {
14         return Music;
15     }
16 
17     public void setMusic(Music music) {
18         Music = music;
19     }
20 }

音乐音信中Music类的实业

 

package com.javen.course.message.resp;

/**
 *  音乐消息中Music类的定义
 * @author Javen
 * @Email zyw205@gmail.com
 *
 */
public class Music {
    // 音乐名称
    private String Title;
    // 音乐描述
    private String Description;
    // 音乐链接
    private String MusicUrl;
    // 高质量音乐链接,WIFI环境优先使用该链接播放音乐
    private String HQMusicUrl;

    public String getTitle() {
        return Title;
    }

    public void setTitle(String title) {
        Title = title;
    }

    public String getDescription() {
        return Description;
    }

    public void setDescription(String description) {
        Description = description;
    }

    public String getMusicUrl() {
        return MusicUrl;
    }

    public void setMusicUrl(String musicUrl) {
        MusicUrl = musicUrl;
    }

    public String getHQMusicUrl() {
        return HQMusicUrl;
    }

    public void setHQMusicUrl(String musicUrl) {
        HQMusicUrl = musicUrl;
    }

}

 

 

 

 浅析呼吁新闻**

 微信服务器会将用户的央求通过doPost方法发送给我们,回想接入成为开垦者

微信公众帐号开采教程第陆篇—–开垦形式启用及接口配置Java

 

@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO 消息的接收、处理、响应  
    }

 

 

 解析微信发来的呼吁(XML)

那边大家赖以开源框架dom四j去解析xml(那里运用的是dom4j-一.陆.一.jar),然后将分析获得的结果存入HashMap

 

哪些将响应新闻转变来xml重回

此间我们将采取开源框架xstream来促成Java类到xml的转移(那里运用的是xstream-1.3.一.jar)

**新闻管理项目标包装**

**以上代码如下:**

  1 package com.javen.course.util;
  2 
  3 import java.io.InputStream;
  4 import java.io.Writer;
  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.Element;
 13 import org.dom4j.io.SAXReader;
 14 
 15 
 16 import com.javen.course.message.resp.Article;
 17 import com.javen.course.message.resp.MusicMessage;
 18 import com.javen.course.message.resp.NewsMessage;
 19 import com.javen.course.message.resp.TextMessage;
 20 import com.thoughtworks.xstream.XStream;
 21 import com.thoughtworks.xstream.core.util.QuickWriter;
 22 import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
 23 import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
 24 import com.thoughtworks.xstream.io.xml.XppDriver;
 25 
 26 /**
 27  * 消息工具类
 28  * @author Javen
 29  * @Email zyw205@gmail.com
 30  */
 31 public class MessageUtil {
 32     /**
 33      * 返回消息类型:文本
 34      */
 35     public static final String RESP_MESSAGE_TYPE_TEXT = "text";
 36 
 37     /**
 38      * 返回消息类型:音乐
 39      */
 40     public static final String RESP_MESSAGE_TYPE_MUSIC = "music";
 41 
 42     /**
 43      * 返回消息类型:图文
 44      */
 45     public static final String RESP_MESSAGE_TYPE_NEWS = "news";
 46 
 47     /**
 48      * 请求消息类型:文本
 49      */
 50     public static final String REQ_MESSAGE_TYPE_TEXT = "text";
 51 
 52     /**
 53      * 请求消息类型:图片
 54      */
 55     public static final String REQ_MESSAGE_TYPE_IMAGE = "image";
 56 
 57     /**
 58      * 请求消息类型:链接
 59      */
 60     public static final String REQ_MESSAGE_TYPE_LINK = "link";
 61 
 62     /**
 63      * 请求消息类型:地理位置
 64      */
 65     public static final String REQ_MESSAGE_TYPE_LOCATION = "location";
 66 
 67     /**
 68      * 请求消息类型:音频
 69      */
 70     public static final String REQ_MESSAGE_TYPE_VOICE = "voice";
 71 
 72     /**
 73      * 请求消息类型:推送
 74      */
 75     public static final String REQ_MESSAGE_TYPE_EVENT = "event";
 76 
 77     /**
 78      * 事件类型:subscribe(订阅)
 79      */
 80     public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";
 81 
 82     /**
 83      * 事件类型:unsubscribe(取消订阅)
 84      */
 85     public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";
 86 
 87     /**
 88      * 事件类型:CLICK(自定义菜单点击事件)
 89      */
 90     public static final String EVENT_TYPE_CLICK = "CLICK";
 91     
 92     /**
 93      * 事件类型:scan(用户已关注时的事件推送)
 94      */
 95     public static final String EVENT_TYPE_SCAN = "SCAN";
 96 
 97     /**
 98      * 解析微信发来的请求(XML)
 99      * 
100      * @param request
101      * @return
102      * @throws Exception
103      */
104     @SuppressWarnings("unchecked")
105     public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
106         // 将解析结果存储在HashMap中
107         Map<String, String> map = new HashMap<String, String>();
108 
109         // 从request中取得输入流
110         InputStream inputStream = request.getInputStream();
111         // 读取输入流
112         SAXReader reader = new SAXReader();
113         Document document = reader.read(inputStream);
114         // 得到xml根元素
115         Element root = document.getRootElement();
116         // 得到根元素的所有子节点
117         List<Element> elementList = root.elements();
118 
119         // 遍历所有子节点
120         for (Element e : elementList)
121             map.put(e.getName(), e.getText());
122 
123         // 释放资源
124         inputStream.close();
125         inputStream = null;
126 
127         return map;
128     }
129 
130     /**
131      * 文本消息对象转换成xml
132      * 
133      * @param textMessage 文本消息对象   XStream是一个Java对象和XML相互转换的工具
134      * @return xml
135      */
136     public static String textMessageToXml(TextMessage textMessage) {
137         xstream.alias("xml", textMessage.getClass());
138         return xstream.toXML(textMessage);
139     }
140 
141     /**
142      * 音乐消息对象转换成xml
143      * 
144      * @param musicMessage 音乐消息对象
145      * @return xml
146      */
147     public static String musicMessageToXml(MusicMessage musicMessage) {
148         xstream.alias("xml", musicMessage.getClass());
149         return xstream.toXML(musicMessage);
150     }
151 
152     /**
153      * 图文消息对象转换成xml
154      * 
155      * @param newsMessage 图文消息对象
156      * @return xml
157      */
158     public static String newsMessageToXml(NewsMessage newsMessage) {
159         xstream.alias("xml", newsMessage.getClass());
160         xstream.alias("item", new Article().getClass());
161         return xstream.toXML(newsMessage);
162     }
163 
164     /**
165      * 扩展xstream,使其支持CDATA块
166      * 
167      */
168     private static XStream xstream = new XStream(new XppDriver() {
169         public HierarchicalStreamWriter createWriter(Writer out) {
170             return new PrettyPrintWriter(out) {
171                 // 对所有xml节点的转换都增加CDATA标记
172                 boolean cdata = true;
173 
174                 @SuppressWarnings("unchecked")
175                 public void startNode(String name, Class clazz) {
176                     super.startNode(name, clazz);
177                 }
178 
179                 protected void writeText(QuickWriter writer, String text) {
180                     if (cdata) {
181                         writer.write("<![CDATA[");
182                         writer.write(text);
183                         writer.write("]]>");
184                     } else {
185                         writer.write(text);
186                     }
187                 }
188             };
189         }
190     });
191 }

到此地关于音信及音信管理工科具的包装基本做到,其实正是对请求音讯/响应音信建立了与之对应的Java类、对xml新闻实行辨析、将响应新闻的Java对象转变来xml

 

自己的微信公众账号
人脸识别、音乐点播、在线翻译、气候查询、公共交通查询、周公解梦、星座运势、手提式有线电话机归属地询问、聊天唠嗑等

 

图片 7

 

应接出席群:347245650   3455318十 举办座谈相互沟通 作者的微非信号:572839485**

笔者的微信公众账号
 小编的微社区应接关心 索取源码←请点击

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图