微信公众平台账号分为三类,分别是服务号、订阅号和小程序,不同类型的账号功能和权限不尽相同,详细区别可访问 微信公众平台官方网站查看,本文分享接入微信公众平台服务号和订阅号(两者的接入方式一样)的java实现。
tips: 1. 以下内容都基于这样一个前提:您已经申请通过拥有一个服务号或者订阅号(对于没有资格申请公众号的开发爱好者,微信给出了开发测试号可申请,可用于研究和开发阶段的测试,申请入口点这里);2. 文中代码是使用IntelliJ IDEA开发的spring boot工程。
1. 微信服务器回调接口开发
这个接口的功能就是接收来自微信平台回调信息,主要包括服务器接入认证和微信平台消息接收(需要注意的是微信公众号将事件如关注、点击按钮等是当做type为event的消息处理的),这一步先说说服务器接入认证的处理。
当我们在微信公众号后台配置好服务器后提交时(第二步要做的事情),微信平台会发送GET请求到我们的接口中来,含有以下参数:
下边我们在控制器中添加方法用来接收微信平台推送的数据:
@Autowired
private TokenService tokenService;
@RequestMapping(value = "/access",method = RequestMethod.GET)
public String checkSignature(String signature, Long timestamp, String nonce, String echostr){
return tokenService.checkSignature(signature,timestamp,nonce,echostr);
}
校验签名,确认请求来自微信、数据未被篡改:
@Value("${wechat.token}")
private String wechatToken;//配置服务器时填写的token
/**
* 微信接入签名校验
* @param signature 加密后的签名
* @param timestamp 签名时间戳,单位为秒
* @param nonce 随机数
* @param echostr 随机串
* @return
*/
@Override
public String checkSignature(String signature, Long timestamp, String nonce, String echostr) {
String[] array = new String[]{timestamp+"",nonce,wechatToken};
Arrays.sort(array);//按字典序排序
StringBuilder builder = new StringBuilder();
for (String str : array) {
builder.append(str);
}//拼接为一个字符串
String digested = DigestUtils.sha1Hex(builder.toString());//sha1加密
if (signature.equals(digested)){
return echostr;
}
return null;
}
2. 微信公众号后台服务器配置
所谓服务器配置就是在微信公众号后台配置微信服务器回调的服务地址以及一些加密相关的参数。配置方法点击这里查看。需要说明的是,配置的URL就是我们第一步开发的接口,服务器要外网可访问的哦。
配置完成后,点击提交,微信平台就是发送GET请求到上边我们开发的接口中,如果签名校验通过,微信会提示成功,至此接入成功。
3. 微信公众号消息接收
消息接口说明文档请看这里。
微信公众平台对消息有一些规则和要求,这里不啰嗦,我们直接来聊聊怎么接收微信公众平台的消息。
微信平台会把消息(包括用户发送的文字、图片等)POST到第二步配置的URL中来,我们使用POST接口接收就可以了,上代码:
@Autowired
private MessageService messageService;
@RequestMapping(value = "/access",method = RequestMethod.POST)
public String accessEvent(@RequestBody String message){
messageService.parseMessage(message);
return "";
}
接收到推送到我们服务器中的消息后,剩下的就是解析了,根据不同的消息类型、不同的业务场景做处理:
/**
* 解析微信平台推送的消息
* @param xmlMessage 微信平台post的消息xml
* @return
*/
Map<String,String> params = new HashMap<>();
try {
/**解析xml字符串*/
Document document = DocumentHelper.parseText(xmlMessage);
Element rootElement = document.getRootElement();
List<Element> elements = rootElement.elements();
for (Element element : elements) {
params.put(element.getName(),element.getStringValue());
}
/**根据不同事件类型做不同处理*/
String msgType = params.get("MsgType");
if (msgType.equals(WechatEnums.MSG_TYPE_EVENT.getValue())){//事件推送
parseEventMsg(params);
}else if (msgType.equals(WechatEnums.MSG_TYPE_TEXT.getValue())){//文本消息
}else if (msgType.equals(WechatEnums.MSG_TYPE_IMAGE)){//图片消息
}
} catch (DocumentException e) {
logger.error(e.getMessage(),e);
}
return "";
}
工程源代码可在GitHub中查看下载,点击查看。
网友评论