微信公众号开发(二)

原创
2017/07/27 11:44
阅读数 343

一、与微信服务器进行握手验证

(1)验证流程

在了解了微信公众号的通信过程之后,下一步就需要进行微信消息的收发。在此之前,首先要进行服务器验证:比如你通过手机端向微信服务器发送请求并获取微信服务器返回的几个参数,如下:

signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
timestamp 时间戳
nonce 随机数
echostr 随机字符串

然后通过对应的方法对参数进行加密后,比对签名是否一致;若一致,则表明消息来自于微信服务器,是安全的。

具体过程请看流程图(来源微信公众号官方):

(2)具体代码

新建一个controller,并添加如下方法:

 /**
     * 校验信息是否是从微信服务器发过来的
     * @param signature 微信加密签名
     * @param timestamp 时间戳
     * @param nonce     随机数
     * @param echostr   随机字符串
     * @param response
     */
    @RequestMapping(value = "wechat",method = {RequestMethod.GET}, produces = "application/json;charset=UTF-8")
    public void valid(@RequestParam String signature,@RequestParam String timestamp,
                      @RequestParam String nonce,@RequestParam String echostr,HttpServletResponse response) {
        PrintWriter out = null;
        try {
            out = response.getWriter();
            //将以上数据进行排序
            String[] str = {ConstantValue.TOKEN, timestamp, nonce};
            Arrays.sort(str); // 字典序排序
            String signStr = str[0] + str[1] + str[2];
            // SHA1加密
            String sign = DigestUtils.sha1Hex(signStr);
            // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
            if (signature.equals(sign)) {// 验证成功返回ehcostr
                out.print("微信向你发来消息:" + echostr);
            } else {
                log.error("不是微信服务器发来的请求,请小心!");
            }
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

验证到此结束。然后就可以开始获取token并收发消息了。

二、收发消息

(1)消息类型分类

微信公众号提供的消息类型较多,如:

1)普通文本消息

2)图片消息

3)语音消息

4)视频消息

5)小视频消息

6)地理位置消息

7)链接消息等

不排除在后续发展过程中会出现新的类型,以微信公众号官方发布为准。其消息体主要包含的属性有:收发人、消息类型、时间、其他特性等,具体的消息体就不在此赘述,请查看微信公众号官方文档即可。

地址:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453

(2)具体代码

微信收消息的方式是POST方式,实质是流读取的方式。因此创建一个下面的方法进行消息接收。

  /**
     * 微信消息的处理
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping(method = {RequestMethod.POST}, produces = "application/xml;charset=UTF-8")
    public void reply2User(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
            PrintWriter pw = response.getWriter();
            String wxMsgXml = IOUtils.toString(request.getInputStream(), CharEncoding.UTF_8);
            ReceivedMessage receivedMsg = null;
            try {
                //将收到的微信消息转化为对象
                if(wxMsgXml!=null){
                    receivedMsg = XmlUtil.toBean(wxMsgXml, ReceivedMessage.class);
                }
                log.info("接收到的微信请求消息:"+wxMsgXml);
            } catch (Exception e) {
                e.printStackTrace();
            }

            StringBuffer replyMsg = new StringBuffer();
            if (receivedMsg != null) {
                // 增加你所需要的处理逻辑,这里只是简单重复消息
//			replyMsg.append("您给我的消息是:");
                if(receivedMsg.getContent().contains("帮助")||receivedMsg.getContent().contains("指南")||receivedMsg.getContent().contains("help")){
                    replyMsg.append(CommonMsg.HELP_DESC);
                }
                if(receivedMsg.getContent().contains("吴老狗")){
                    replyMsg.append(receivedMsg);
                }else if(receivedMsg.getContent().contains("老马")){
                    replyMsg.append("老马正在写程序,欢迎访问:");
                }else if(receivedMsg.getContent().contains("水")){
                    replyMsg.append("不积跬步无以至千里,不积小流无以成江海");
                }
            } else {
                replyMsg.append("不是文本的消息,我暂时看不懂");
            }
            //创建回复消息对象
            String returnXml = receivedMsg.toString();// MessageUtil.createRspMsg(receivedMsg, replyMsg);
            pw.println(returnXml);
        }

 

ReceivedMessage.java

package com.mark.entity.message;

import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("xml")
public class ReceivedMessage {
	@XStreamAlias("ToUserName")
	private String toUserName;// 接收人:开发者微信号
	@XStreamAlias("FromUserName")
	private String fromUserName;// 发送人:用户OpenId
	@XStreamAlias("CreateTime")
	private String createTime;// 创建日期
	@XStreamAlias("MsgType")
	private String messageType;// 消息类型
	@XStreamAlias("Content")
	private String content;// 内容
	@XStreamAlias("MsgId")
	private String msgId;// 消息编号

	public String getMsgId() {
		return msgId;
	}

	public void setMsgId(String msgId) {
		this.msgId = msgId;
	}

	public String getFromUserName() {
		return fromUserName;
	}

	public void setFromUserName(String fromUserName) {
		this.fromUserName = fromUserName;
	}

	public String getToUserName() {
		return toUserName;
	}

	public void setToUserName(String toUserName) {
		this.toUserName = toUserName;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getMessageType() {
		return messageType;
	}

	public void setMessageType(String messageType) {
		this.messageType = messageType;
	}

	public String getCreateTime() {
		return createTime;
	}

	public void setCreateTime(String createTime) {
		this.createTime = createTime;
	}

	@Override
	public String toString() {
		return "ReceivedMessage [toUserName=" + toUserName + ", fromUserName="
				+ fromUserName + ", createTime=" + createTime
				+ ", messageType=" + messageType + ", content=" + content
				+ ", msgId=" + msgId + "]";
	}
	
	

}

ReplyMessage.java

package com.mark.entity.message;

import com.thoughtworks.xstream.annotations.XStreamAlias;
@XStreamAlias("xml")
public class ReplyMessage {
//	private String FuncFlag;// 消息编号
	@XStreamAlias("FromUserName")
	private String fromUserName;// 发送人
	@XStreamAlias("ToUserName")
	private String toUserName;// 接收人
	@XStreamAlias("CreateTime")
	private String createTime;// 创建日期
	@XStreamAlias("MsgType")
	private String messageType;// 消息类型
	@XStreamAlias("Content")
	private String content;// 内容

//	public String getFuncFlag() {
//		return FuncFlag;
//	}
//
//	public void setFuncFlag(String funcFlag) {
//		FuncFlag = funcFlag;
//	}

	public String getFromUserName() {
		return fromUserName;
	}

	public void setFromUserName(String fromUserName) {
		this.fromUserName = fromUserName;
	}

	public String getToUserName() {
		return toUserName;
	}

	public void setToUserName(String toUserName) {
		this.toUserName = toUserName;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getMessageType() {
		return messageType;
	}

	public void setMessageType(String messageType) {
		this.messageType = messageType;
	}

	public String getCreateTime() {
		return createTime;
	}

	public void setCreateTime(String createTime) {
		this.createTime = createTime;
	}

	@Override
	public String toString() {
		return "ReplyMessage [fromUserName=" + fromUserName + ", toUserName="
				+ toUserName + ", createTime=" + createTime + ", messageType="
				+ messageType + ", content=" + content + "]";
	}
	
	
	

}

具体代码见:https://git.oschina.net/mark0931/spring-wechat

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部