微信公众号测试账号-消息管理/事件推送

记录一下微信公众号开发的时候的一些过程。。。
首先注册一个微信公众测试账号,虽然个人注册的订阅号也有此功能,但是却没有用户管理功能,所以这里就先拿测试账号开发微信公众号。。。
申请微信测试号在这里http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
这里写图片描述

成功申请之后会有自己的APPID和appsecret。。。
微信开发者文档在这里 。。。 http://mp.weixin.qq.com/wiki/home/index.html

开发人员可以根据该文档对微信公众号进行接口的开发。。。

简单的申请完之后。。。尝试配置接口配置信息需要填写公网可以访问的链接地址以及TOKEN,以确定微信可以访问你的程序。。。
公网能访问的链接地址不一定是特意去申请的域名或者买服务器,可以用国内已有的一些网络映射工具,这里我用的是Sunny-Ngrok启动工具,也可以用花生壳。。。

根据这些映射工具,可以在公网上访问该网址。。。这样微信也可以访问我的程序来调用相应的服务。。。
这里写图片描述

package org.ssm.maven.test1.controller;

import java.security.MessageDigest;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/wechat")
public class WechatValidToken {

    public static final String TOKEN = "ivy";
    private static char[] hexDigits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
            'f' };

    @RequestMapping(value="/valid", method = RequestMethod.GET)
    @ResponseBody
    public String validToken( HttpServletRequest request) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String echostr = request.getParameter("echostr");
        String[] paramStr = new String[] { TOKEN, timestamp, nonce };
        Arrays.sort(paramStr);
        String str="";
        for(String s : paramStr){
            str += s;
        }
        String afterSha1 = sha1(str);
        if (afterSha1.equals(signature))
            return echostr;
        else
            return "null";
    }

    private static String sha1(String source) {
        if ((source == null) || source.isEmpty()) {
            return source;
        }
        try {
            MessageDigest sha1 = MessageDigest.getInstance("SHA-1");
            byte[] sha1Bytes = sha1.digest(source.getBytes());
            return toHexArray(sha1Bytes);

        } catch (Exception e) {
            // do nothing
        }

        return source;
    }

    private static String toHexArray(byte[] array) {
        char[] resultCharArray = new char[array.length * 2];
        int index = 0;
        for (byte b : array) {
            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
            resultCharArray[index++] = hexDigits[b & 0xf];
        }
        return new String(resultCharArray);
    }
}

该代码用于微信校验是否接收到信息的功能。。。

我的微信公众号的后台是基于ssm的java企业级的程序,关于ssm的配置文件在网上随便百度都可以找得到。。。
对于订阅号的消息管理,微信公众平台提供了简单的对于消息管理的功能。。。对于不是开发人员来说该功能已经能满足普通微信公众号的需求。。。
但是对于需求不仅满足于普通的信息管理的系统而言,这只是冰山一角。。。

对于消息信息管理分为以下几类:

1 文本消息
2 图片消息
3 语音消息
4 视频消息
5 小视频消息
6 地理位置消息
7 链接消息

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

文本消息


package org.ssm.maven.test1.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.ssm.maven.test1.model.TextMessage;
import org.ssm.maven.test1.util.MessageType;
import org.ssm.maven.test1.util.MessageUtil;

@Controller
@RequestMapping("/wechat")
public class WechatController {

    @RequestMapping(value = "/valid", method = RequestMethod.POST)
    @ResponseBody
    public String accpetMessage(HttpServletRequest request) throws IOException {
        request.setCharacterEncoding("utf-8");
        Map<String, String> param = MessageUtil.xmlToMap(request);
        String fromUserName = param.get("FromUserName");
        String toUserName = param.get("ToUserName");
        String msgType = param.get("MsgType");
        String content = param.get("Content");
        Long createTime = Long.valueOf(param.get("CreateTime"));
        Long msgId = Long.valueOf(param.get("MsgId") );
        System.out.println("--------->" + param);
        String message = null;
        if (MessageType.TEXT.equals(msgType)) {
            if ("1".equals(content)) {
                message = MessageUtil.initText(MessageUtil.firstMenu(), createTime, fromUserName, toUserName, msgId);
            } else if ("2".equals(content)) {
                message = MessageUtil.initNewsMessage(toUserName, fromUserName);
            } else if ("?".equals(content)) {
                message = MessageUtil.initText(MessageUtil.menuText(), createTime, fromUserName, toUserName, msgId);
            } else {
                TextMessage text = new TextMessage();
                text.setContent("the message is:" + content);
                text.setCreateTime(createTime);
                text.setToUserName(fromUserName);
                text.setFromUserName(toUserName);
                text.setMsgType("text");
                message = MessageUtil.textMessageToXml(text);
                System.out.println("message--------->" + message);
            }

            // StringBuffer sb = new StringBuffer();
            // sb.append("<xml>");
            // sb.append("<ToUserName><![CDATA[" + fromUserName +
            // "]]></ToUserName>");
            // sb.append("<FromUserName><![CDATA[" + toUserName +
            // "]]></FromUserName>");
            // sb.append("<CreateTime>" + new Date().getTime() +
            // "</CreateTime>");
            // sb.append("<MsgType><![CDATA[text]]></MsgType>");
            // sb.append("<Content><![CDATA[this is a test]]></Content>");
            // sb.append("<MsgId>1234567890123456</MsgId>");
            // sb.append("</xml>");

            // response.getWriter().write(message);
        } else if (MessageType.EVENT.equals(msgType)) {
            String event = param.get("Event");
            if (MessageType.SUBSCRIBE.equals(event)) {
                message = MessageUtil.initText(MessageUtil.menuText(), createTime, fromUserName, toUserName, msgId);
            } else if (MessageType.CLICK.equals(event)) {
                message = MessageUtil.initText(MessageUtil.menuText(), createTime, fromUserName, toUserName, msgId);
            } else if (MessageType.VIEW.equals(event)) {
                message = MessageUtil.initText(param.get("EventKey"), createTime, fromUserName, toUserName, msgId);
            } else if (MessageType.SCANCODE.equals(event)) {
                message = MessageUtil.initText(param.get("EventKey"), createTime, fromUserName, toUserName, msgId);
            }
        } else if (MessageType.LOCATION.equals(msgType)) {
            message = MessageUtil.initText(param.get("Label"), createTime, fromUserName, toUserName, msgId);
        }
        return message;
    }

}

消息类型主要分为

package org.ssm.maven.test1.util;

public class MessageType {

    public static final String TEXT = "text";
    public static final String NEWS = "news";
    public static final String IMAGE = "image";
    public static final String VOICE = "voice";
    public static final String VIDEO = "video";
    public static final String SHORTVIDEO = "shortvideo";
    public static final String LINK = "link";
    public static final String LOCATION = "location";
    public static final String EVENT = "event";
    public static final String SUBSCRIBE = "subscribe";//event
    public static final String UNSUBSCRIBE = "unsubscribe";//event
    public static final String CLICK = "CLICK";//event
    public static final String VIEW = "VIEW";//event
    public static final String SCANCODE = "scancode_push";//event

}

大致用到的分为这几类,subscribe,unsubscribe,CLICK,VIEW,scancode_push为event下

程序入口沿用了之间接收消息接口的名称。。。

这里附上转化成xml的代码以及初始化消息返回的代码。。。

package org.ssm.maven.test1.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.ssm.maven.test1.controller.WechatController;
import org.ssm.maven.test1.model.TextMessage;
import org.ssm.maven.test1.model.WechatNews;
import org.ssm.maven.test1.model.WechatNewsMessage;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;

public class MessageUtil {

    protected static String PREFIX_CDATA = "<![CDATA[";
    protected static String SUFFIX_CDATA = "]]>";

    /**
     * xml to map����
     * @param request
     * @return
     */
    public static Map<String, String> xmlToMap(HttpServletRequest request){

        Map<String, String> map = new HashMap<String, String>();
        SAXReader reader = new SAXReader();

        try {
            InputStream ins = request.getInputStream();
            Document doc = reader.read(ins);
            Element root = doc.getRootElement();
            List<Element> list = root.elements();

            for (Element element : list) {
                map.put(element.getName(), element.getText());
            }
            ins.close();

        } catch (IOException e) {
            e.printStackTrace();
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        return map;
    }

    public static String textMessageToXml(TextMessage textMessage){
        XStream xstream = new XStream();
        xstream.alias("xml", textMessage.getClass());
        return xstream.toXML(textMessage);
    }

    public static String newsMessageToXml(WechatNewsMessage wechatNewsMessage){
        XStream xstream = new XStream();
        xstream.alias("xml", wechatNewsMessage.getClass());
        xstream.alias("item", new WechatNews().getClass());
        return xstream.toXML(wechatNewsMessage);
    }
    /*初始化文本消息*/
    public static String initText(String content, Long createTime, String fromUserName, String toUserName, Long msgId){
        String message = "";
        TextMessage text = new TextMessage();
         text.setContent("the message is:"+content);
         text.setCreateTime(createTime);
         text.setToUserName(fromUserName);
         text.setFromUserName(toUserName);
         text.setMsgType(MessageType.TEXT);
         text.setMsgId(msgId);
         message = MessageUtil.textMessageToXml(text);
         System.out.println("message--------->" + message);
         return message;
    }
    /*初始化图文消息*/
    public static String initNewsMessage(String toUserName, String fromUserName){
        String message = "";
        WechatNewsMessage wechatNewsMessage = new WechatNewsMessage();
        WechatNews wechatNews = new WechatNews();
        WechatNews wechatNews1 = new WechatNews();
        List<WechatNews> wechatNewss = new ArrayList<WechatNews>();

        wechatNews.setTitle("ivy's description");
        wechatNews.setPicUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0151.JPG");
        wechatNews.setUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0151.JPG");
        wechatNews.setDescription("i am ivy");

        wechatNews1.setTitle("haha's description");
        wechatNews1.setPicUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0152.JPG");
        wechatNews1.setUrl("http://ivytest.ngrok.cc/org.ssm.maven.test1/images/IMG_0152.JPG");
        wechatNews1.setDescription("i am gaga");

        wechatNewss.add(wechatNews);
        wechatNewss.add(wechatNews1);

        wechatNewsMessage.setArticleCount(wechatNewss.size());
        wechatNewsMessage.setArticles(wechatNewss);
        wechatNewsMessage.setFromUserName(toUserName);
        wechatNewsMessage.setToUserName(fromUserName);
        wechatNewsMessage.setCreateTime(new Date().getTime());
        wechatNewsMessage.setMsgType(MessageType.NEWS);

        message = newsMessageToXml(wechatNewsMessage);

        return message;
    }

    public static String menuText(){
        StringBuffer sb = new StringBuffer();
        sb.append("Welcome here\n");
        sb.append("1.text field\n");
        sb.append("2.news field\n");
        sb.append("enter ? for help\n");
        return sb.toString();
    }

    public static String firstMenu(){
        return "Hi,i am ivy";
    }

    public static String secondMenu(){
        return "Bye,i am ivy";
    }
}
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页