微信公众号获取用户发送的普通消息

最近开始写微信公众号了,作为小白的我,有些懵,参考各种大神写的博客,总算实现了第一个功能。写此博客作为记录吧。

第一步:注册登录相应微信公众号信息
微信公众号平台地址:https://mp.weixin.qq.com/

第二步:实现内外网穿透
参考博客:http://blog.csdn.net/xyang81/article/details/52141881

第三步:仔细阅读开发文档,地址:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432,然后开始进行编码实现。

我要实现的功能,简单来说就是,获取用户向公众号发送的消息,然后依据一定条件进行消息筛选,符合要求的进行入库操作。
话不多说,开始贴代码吧。

package com.weixin.controller;

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

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

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.weixin.entity.RequestTextMessage;
import com.weixin.entity.Serial;
import com.weixin.service.SerialService;
import com.weixin.util.ReplyMessage;
import com.weixin.util.SHA1;

@Controller
@RequestMapping
public class RecognitionSerialNumberController {

    private static final Logger log =Logger.getLogger(RecognitionSerialNumberController.class);

  // 设置一个全局的token,开发者自己设置。api这样解释:Token可由开发者可以任意填写,
  // 用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性) 
  private String TOKEN = "guoyou";

    @Autowired
    private SerialService  serialService ;

    @RequestMapping(value="/addSerialNumber.html")
    public void  addSerialNumber(HttpServletRequest request, HttpServletResponse response) throws Exception{ 

        //checkToken(request, response); //仅在认证微信开发者模式时调用一次即可

        response.setContentType("text/html;charset=UTF-8");
        PrintWriter pw = response.getWriter();
        String wxMsgXml =IOUtils.toString(request.getInputStream(), "utf-8");
        log.info("获取的数据信息>>>>>"+wxMsgXml);

        boolean eventType =wxMsgXml.contains("Event") ;// 如果包含,则是触发事件
        RequestTextMessage textMsg =null ;
        String returnXml ="";
        StringBuffer replyMsg = new StringBuffer();
        if(!eventType){ //信息交互事件
            textMsg = ReplyMessage.getRequestTextMessage(wxMsgXml);//解析用户输入的信息
            String content = textMsg.getContent().trim();//用户发送信息
            String openId= textMsg.getFromUserName().trim();//发送方账号(OpenID)
            String creattime=textMsg.getCreateTime();
            String msgType=textMsg.getMessageType();// 发送类型
            String tousername=textMsg.getToUserName();//用户微信号
            boolean  flag= isContainsNumOrLetter(content);

            if(flag) {
                //将数据入库
                Serial serial = new Serial();
                serial.setAddtime(new Date());
                serial.setOpen_id(openId);
                serial.setName(tousername);
                serial.setSn(content);
                serial.setBt_mac_addr("");
                serial.setWifi_mac_addr("");
                serialService.insertSelective(serial);
                //serialService.insert(serial);
                replyMsg.append("返回信息!");
                returnXml = ReplyMessage.getReplyTextMessage(replyMsg.toString(), textMsg.getFromUserName(),textMsg.getToUserName());
            }else {
                replyMsg.append("输入字符不符合格式!");
                returnXml = ReplyMessage.getReplyTextMessage(replyMsg.toString(), textMsg.getFromUserName(),textMsg.getToUserName());
            }
        }

        log.info("wxMsgXml>>>>>>>>>>>>>>"+wxMsgXml);
        log.info("returnXml>>>>>>>>>>>>>>"+returnXml);
        pw.println(returnXml);

    }


    /**
     * 
        * @Title: isContainsNumOrLetter  
        * @Description: TODO(判断字符是否符合要求即包含数字和字母且长度为12) 
        * @param @param str
        * @param @return    参数  
        * @return boolean    返回类型  
        * @throws
     */
    private  boolean isContainsNumOrLetter(String  str) {
        boolean flag = false;

        boolean isDigit = false;//定义一个boolean值,用来表示是否包含数字
        boolean isLetter = false;//定义一个boolean值,用来表示是否包含字母
      //假设有一个字符串
        for (int i=0 ; i<str.length() ; i++){ //循环遍历字符串   
            if (Character.isDigit(str.charAt(i))){     //用char包装类中的判断数字的方法判断每一个字符
                isDigit = true;   
            }
            if (Character.isLetter(str.charAt(i))){   //用char包装类中的判断字母的方法判断每一个字符
                isLetter = true;
            }
        }
            /*循环完毕以后
            *如果isDigit为true,则代表字符串中包含数字,否则不包含
            *如果isLetter为true,则代表字符串中包含字母,否则不包含                 
            */
        //System.out.println(isDigit);          //System.out.println(isLetter);

        if(isDigit && isLetter) {
            //根据字符长度、判断输入是Wifi 还是蓝牙
             int len=str.length();
             if( len == 12) {
                flag = true;
             }
        }
            return flag;
    }


 /*
  * 第一步:验证服务器地址的有效性 开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,
  * GET请求携带四个参数:signature、timestamp、nonce、echostr
  * 开发者通过检验signature对请求进行校验(下面有校验方式)。 若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,
  * 则接入生效, 成为开发者成功,否则接入失败。
  * 
  * 加密/校验流程如下: 
  * 1. 将token、timestamp、nonce三个参数进行字典序排序 
  * 2. 将三个参数字符串拼接成一个字符串进行sha1加密 
  * 3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
  * 
  *  字典排序(lexicographical order)是一种对于随机变量形成序列的排序方法。其方法是,按照字母顺序,或者数字小大顺序,由小到大的形成序列。
  */
    public boolean checkToken(HttpServletRequest request, HttpServletResponse response) throws IOException {
        boolean flag = false;
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");

        String[] str = { TOKEN, timestamp, nonce };
        Arrays.sort(str); // 字典序排序

        String bigStr = str[0] + str[1] + str[2];
        // SHA1加密
        String digest = new SHA1().getDigestOfString(bigStr.getBytes()).toLowerCase();

        // 确认请求来至微信
        if (digest.equals(signature)) {
            response.getWriter().print(echostr);
            flag = true;
        }else {
            System.out.println("TAG"+"接入失败");
        }
        return flag;
    }

}

ReplyMessage.java

package com.weixin.util;

import java.util.Date;
import java.util.List;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.weixin.entity.Item;
import com.weixin.entity.ReplyTextMessage;
import com.weixin.entity.ReplyTuwenMessage;
import com.weixin.entity.RequestTextMessage;

public class ReplyMessage {

//  获取关注事件
    public static RequestTextMessage getRequestFocus(String xml){

            XStream xstream = new XStream(new DomDriver());

            xstream.alias("xml", RequestTextMessage.class);
            xstream.aliasField("ToUserName", RequestTextMessage.class, "toUserName");
            xstream.aliasField("FromUserName", RequestTextMessage.class, "fromUserName");
            xstream.aliasField("CreateTime", RequestTextMessage.class, "createTime");
            xstream.aliasField("MsgType", RequestTextMessage.class, "messageType");
            xstream.aliasField("Event", RequestTextMessage.class, "event");
            xstream.aliasField("EventKey", RequestTextMessage.class, "eventKey");
//            xstream.aliasField("Content", RequestTextMessage.class, "content");
//            xstream.aliasField("MsgId", RequestTextMessage.class, "msgId");
            RequestTextMessage requestTextMessage = (RequestTextMessage)xstream.fromXML(xml); 
            return requestTextMessage;

    }

//  获取推送文本消息
    public static RequestTextMessage getRequestTextMessage(String xml){
            XStream xstream = new XStream(new DomDriver());
            xstream.alias("xml", RequestTextMessage.class);
            xstream.aliasField("URL", RequestTextMessage.class, "url");
            xstream.aliasField("ToUserName", RequestTextMessage.class, "toUserName");
            xstream.aliasField("FromUserName", RequestTextMessage.class, "fromUserName");
            xstream.aliasField("CreateTime", RequestTextMessage.class, "createTime");
            xstream.aliasField("MsgType", RequestTextMessage.class, "messageType");
            xstream.aliasField("Content", RequestTextMessage.class, "content");
            xstream.aliasField("MsgId", RequestTextMessage.class, "msgId");

            RequestTextMessage requestTextMessage = (RequestTextMessage)xstream.fromXML(xml); 
            return requestTextMessage;
    }


//    回复文本消息
    public static String getReplyTextMessage(String content, String fromUserName,String toUserName){
        ReplyTextMessage we = new ReplyTextMessage();
        we.setMessageType("text");
        we.setFuncFlag("0");
        we.setCreateTime(new Long(new Date().getTime()).toString());
        we.setContent(content);
        we.setToUserName(fromUserName);  
        we.setFromUserName(toUserName);
        XStream xstream = new XStream(new DomDriver()); 
        xstream.alias("xml", ReplyTextMessage.class);
        xstream.aliasField("ToUserName", ReplyTextMessage.class, "toUserName");
        xstream.aliasField("FromUserName", ReplyTextMessage.class, "fromUserName");
        xstream.aliasField("CreateTime", ReplyTextMessage.class, "createTime");
        xstream.aliasField("MsgType", ReplyTextMessage.class, "messageType");
        xstream.aliasField("Content", ReplyTextMessage.class, "content");
        xstream.aliasField("FuncFlag", ReplyTextMessage.class, "funcFlag");
        String xml =xstream.toXML(we);
        return xml;

    }


//    回复图文消息
    public static String getReplyTuwenMessage(String fromUserName,String toUserName,List<Item> articleList){
//      NewsMessage newsMessage = new NewsMessage();
//      MessageUtil messageUtil = new MessageUtil();
        ReplyTuwenMessage we = new ReplyTuwenMessage();
      //  List<Item> articleList = new ArrayList<>();
  //      Articles articles = new Articles();

//        Item item = new Item();
//        Item item2 = new Item();
//        Item item3 = new Item();

        we.setMessageType("news");
        we.setCreateTime(new Long(new Date().getTime()).toString());
        we.setToUserName(fromUserName);  
        we.setFromUserName(toUserName);
        we.setFuncFlag("0");
        we.setArticleCount(articleList.size());
        we.setArticles(articleList);

        XStream xstream = new XStream(new DomDriver()); 
        xstream.alias("xml", ReplyTuwenMessage.class);
        xstream.aliasField("ToUserName", ReplyTuwenMessage.class, "toUserName");
        xstream.aliasField("FromUserName", ReplyTuwenMessage.class, "fromUserName");
        xstream.aliasField("CreateTime", ReplyTuwenMessage.class, "createTime");
        xstream.aliasField("MsgType", ReplyTuwenMessage.class, "messageType");
        xstream.aliasField("Articles", ReplyTuwenMessage.class, "Articles");

        xstream.aliasField("ArticleCount", ReplyTuwenMessage.class, "articleCount");
        xstream.aliasField("FuncFlag", ReplyTuwenMessage.class, "funcFlag");

        //xstream.aliasField("item", Articles.class, "item");
        xstream.alias("item", new Item().getClass());
        xstream.aliasField("Title", Item.class, "title");
        xstream.aliasField("Description", Item.class, "description");
        xstream.aliasField("PicUrl", Item.class, "picUrl");
        xstream.aliasField("Url", Item.class, "url");
        String xml =xstream.toXML(we);
        return xml;
        }


}

RequestTextMessage.java

package com.weixin.entity;
 public class RequestTextMessage {
     private String url;
     private String toUserName;
     private String fromUserName;
     private String createTime;
     private String messageType;
     private String content;
     private String msgId;
     private String event;
     private String eventKey;



    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public String getToUserName() {
        return toUserName;
    }
    public void setToUserName(String toUserName) {
        this.toUserName = toUserName;
    }
    public String getFromUserName() {
        return fromUserName;
    }
    public void setFromUserName(String fromUserName) {
        this.fromUserName = fromUserName;
    }
    public String getCreateTime() {
        return createTime;
    }
    public void setCreateTime(String createTime) {
        this.createTime = createTime;
    }
    public String getMessageType() {
        return messageType;
    }
    public void setMessageType(String messageType) {
        this.messageType = messageType;
    }
    public String getContent() {
        return content;
    }
    public void setContent(String content) {
        this.content = content;
    }
    public String getMsgId() {
        return msgId;
    }
    public void setMsgId(String msgId) {
        this.msgId = msgId;
    }
    public String getEvent() {
        return event;
    }
    public void setEvent(String event) {
        this.event = event;
    }
    public String getEventKey() {
        return eventKey;
    }
    public void setEventKey(String eventKey) {
        this.eventKey = eventKey;
    }
}

获取/回复用户发送的其他类型消息还未实现,有时间整理出来一并贴出来。革命尚未成功,还需努力呀。

猜你喜欢

转载自blog.csdn.net/lethe0624/article/details/79226315