微信公众号的开发 springBoot

1、微信公众号的申请

        具体申请流程此处略过,百度一下有人教你怎样一步一步申请的。

       不过,个人账号什么的限制太多,而其他又要求营业执照等,太麻烦,所以如果是小白只是想学一下的话,可以申请一个测试号,具体申请方法见:https://jingyan.baidu.com/article/e2284b2b95f423e2e6118de3.html

2、springBoot多子模块项目的搭建(具体见XXXXX)

       该demo后端采用的是springboot,搭建一个这样的项目(具体见springBoot多模块项目的搭建)虽然很简单,但重复的工作没什么意义,所以使用了脚手架(具体见利用velocity模板引擎实现脚手架),一个请求就生成一个springboot多模块项目,如果有需求,还可以直接上传到git。

3、利用业务代码生成器自动生成业务代码(具体见XXXXX)

数据库的crud等基础操作总是那么的让人觉得无奈(毕竟大部分都没什么技术含量),要是用springdata可能还好一点,用mybatis的话,特别是mybatis XML版(非注解版)的话,如果不用生成工具的话,是不是想死。而那个mybatis generator代码生成工具,本人只能说,非常一般般,局限太多了,所以特意推一波业务代码生成器(具体见:springboot多模块项目业务代码生成器),创建好数据库后,执行一个test方法,就可以生成所有的业务代码。

4、基本配置

4.1 基本配置

点击“开发者工具”-〉"开发者文档"-〉"开始开发"-〉"接入指南"-〉""

如下图所示,点击“基本配置”

 

基本配置的URL包含两个方法:get方法和post方法

get方法,验证消息的确来自微信服务器,点击“提交”按钮时,请求的就是该方法

post方法,现业务逻辑都走该方法,当然前提是上面的“提交”能成功。

4.2 url get方法的开发与验证的实现

4.2.1 get方法开发

get方法的思路:

      将填写的token与请求参数signature,timestamp拼接成字符串,然后用sha1加密,如果加密后的值等于nonce,则将请求参数echostr返回。

@RequestMapping(value = {"/connect"},method = RequestMethod.GET)
    public String connect(String signature,String timestamp,String nonce,String echostr){
        if(WexinSha1.checkSignature(signature, timestamp, nonce)) {
            return  echostr;
        }else{
            return null;
        }
    }

WexinSha1.java

package cn.inovance.wechat.utils.tool;

import java.util.Arrays;

import cn.inovance.wechat.utils.constant.WechatConstant;
import org.apache.commons.codec.digest.DigestUtils;

public class WexinSha1 {
	public static boolean checkSignature(String signature,String timestamp,String nonce) {
		String[] arr = new String[] {WechatConstant.WECHAT_TOKEN,timestamp,nonce};
		Arrays.sort(arr);
		StringBuffer content = new StringBuffer();
		for(String a:arr) {
			content.append(a);
		}
		String sign = DigestUtils.shaHex(content.toString());
		if(sign.equals(signature)) {
			return true;
		}else {
			return false;
		}
	}
}

 

4.2.2 公网映射

(土豪能直接进行域名映射的请忽略哈) 那对于普通的开发者,如何进行公网映射呢?

有花生壳,万金维,nat123,dnspod等等,具体用哪个以及具体怎么使用,自己百度哈。

5、具体业务的开发

5.1 url post方法的开发与验证的实现

微信平台和我们自己的平台的主动交互,都是通过该post方法来进行消息的回调的,下面是controller中的post方法。

@RequestMapping(value = {"/connect"},method = RequestMethod.POST)
    public String post(HttpServletRequest request){
        String result=null;
        try {
            result= messageService.reponseMessage(request);
        } catch (Exception e) {
            logger.error("自动回复出错"+e.getMessage());
        }
        return result;
    }

post最终调用了MessageService.java的 reponseMessage(HttpServletRequest request) 方法。该方法主要是被动消息的接收(比如订阅/取消订阅,扫码,用户给公众号发消息等),主动消息的结果回调(比如模板消息,群发消息的回调等),具体大致包括以下内容:

 

MessageService.java

package cn.inovance.wechat.service.message;

import cn.inovance.wechat.module.message.Message;
import com.github.pagehelper.PageInfo;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

public interface MessageService {
    int save(Message message);
    int update(Message message);
    int delete(String id);
    int check(Message message);
    Message get(String id);
    Message getByKeyWord(String keyWord);
    List<Message> getList(Message message);
    PageInfo<Map> getListByPage(Map<String, Object> map, int page, int rows);
    String reponseMessage(HttpServletRequest request) throws Exception;
}

MessageServiceImpl.java

package cn.inovance.wechat.service.message.impl;

import cn.inovance.wechat.dao.message.MessageMapper;
import cn.inovance.wechat.module.message.EventMessage;
import cn.inovance.wechat.module.message.Message;
import cn.inovance.wechat.module.message.TextMessage;
import cn.inovance.wechat.service.message.MessageService;
import cn.inovance.wechat.utils.constant.WechatConstant;
import cn.inovance.wechat.utils.tool.XmlUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.thoughtworks.xstream.XStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Service
public class MessageServiceImpl implements MessageService {
    @Autowired
    private MessageMapper messageMapper;
    protected  static final Logger logger= LoggerFactory.getLogger(MessageServiceImpl.class);

    @Override
    public int save(Message message) {
        return messageMapper.save(message);
    }

    @Override
    public int update(Message message) {
        return messageMapper.update(message);
    }

    @Override
    public int delete(String id) {
        return messageMapper.delete(id);
    }

    @Override
    public int check(Message message) {
        Message message1= messageMapper.check(message);
        if(message1==null){
            return 1;
        }else{
            return 0;
        }
    }

    @Override
    public Message get(String id) {
        return messageMapper.get(id);
    }

    @Override
    public Message getByKeyWord(String keyWord) {
        return messageMapper.getByKeyWord(keyWord);
    }

    @Override
    public List<Message> getList(Message message) {
        return messageMapper.getList(message);
    }

    @Override
    public PageInfo<Map> getListByPage(Map<String, Object> map, int page, int rows) {
        PageHelper.startPage(page,rows);
        List<Map<String, Object>> collection=messageMapper.getListByPage(map);
        return new PageInfo(collection);
    }

    @Override
    public String reponseMessage(HttpServletRequest request) throws Exception {
        Map<String,String> map= XmlUtil.xmlToMap(request);
        String msgType = map.get("MsgType");
        String result=null;
        switch (msgType){
            case "text":
                result=handlerTextMessage(map);
                break;
            case "event":
                result=handlerEventMessage(map);
                break;
            default:
                break;
        }
        logger.info(result);
        return result;
    }

    public String handlerTextMessage(Map<String,String> map){
        Message message=messageMapper.getByKeyWord(map.get("Content"));
        TextMessage textMessage=new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setCreateTime(new Date().getTime());
        textMessage.setMsgType(WechatConstant.WECHAT_MESSAGE_TYPE_TEXT);
        if(message!=null){
            textMessage.setContent(message.getResult());
        } else{
            textMessage.setContent(WechatConstant.WECHAT_HELPER);
        }
        return XmlUtil.objToXml(textMessage);
    }

    public String handlerEventMessage(Map<String,String> map){
        String result=null;
        String event=map.get("Event");
        switch (event){
            case "subscribe":
                result=handlerSubscribeEventMessage(map);
                break;
            case "unsubscribe":
                result=null;
                break;
            case "SCAN":
                result=handlerScanEventMessage(map);
                break;
            case "LOCATION":
                result=null;
                break;
            case "CLICK":
                result=null;
                break;
            case "VIEW":
                result=null;
                break;
            case "TEMPLATESENDJOBFINISH":
                result=null;
                break;
            default:
                break;
        }
        return result;
    }

    public static String handlerSubscribeEventMessage(Map<String,String> map){
        TextMessage textMessage=new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setCreateTime(new Date().getTime());
        textMessage.setMsgType(WechatConstant.WECHAT_MESSAGE_TYPE_TEXT);
        textMessage.setContent(WechatConstant.WECHAT_SUBSCRIBE);
        return XmlUtil.objToXml(textMessage);
    }

    public static String handlerScanEventMessage(Map<String,String> map){
        TextMessage textMessage=new TextMessage();
        textMessage.setToUserName(map.get("FromUserName"));
        textMessage.setFromUserName(map.get("ToUserName"));
        textMessage.setCreateTime(new Date().getTime());
        textMessage.setMsgType(WechatConstant.WECHAT_MESSAGE_TYPE_TEXT);
        textMessage.setContent(WechatConstant.WECHAT_SCAN);
        return XmlUtil.objToXml(textMessage);
    }


}
BaseWechatMessage.java
package cn.inovance.wechat.utils.base;

import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class BaseWechatMessage {
    // 开发者微信号
    private String ToUserName;
    // 发送方帐号(一个OpenID)
    private String FromUserName;
    // 消息创建时间 (整型)
    private long CreateTime;
    // 消息类型(text/image/location/link)
    private String MsgType;
}
TextMessage.java
package cn.inovance.wechat.module.message;

import cn.inovance.wechat.utils.base.BaseWechatMessage;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class TextMessage extends BaseWechatMessage{
    // 消息id,64位整型
    private long MsgId;
    // 消息内容
    private String Content;


}
BaseModel.java
package cn.inovance.wechat.utils.base;

import lombok.Data;
import lombok.ToString;

import java.io.Serializable;
import java.util.Date;

@Data
@ToString
public class BaseModel implements Serializable {
    private static final long serialVersionUID = 1L;
    private String id;
    private String creator;
    private Date createTime;
    private String updator;
    private String updateTime;
    private String description;
}

Message.java

package cn.inovance.wechat.module.message;

import cn.inovance.wechat.utils.base.BaseModel;
import lombok.Data;
import lombok.ToString;

@Data
@ToString
public class Message extends BaseModel{
    private String keyWord;
    private String result;


}

待会儿继续。。。

6、事件的开发

7、扫码事件

8、主动推送事件

9、消息群发

10、自定义菜单

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值