热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Java微信公众平台之消息管理

这篇文章主要为大家详细介绍了Java微信公众平台之消息管理的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

Java微信公众平台开发之消息管理,一定要先看下官方文档

微信消息管理分为接收普通消息、接收事件推送、发送消息(被动回复)、客服消息、群发消息、模板消息这几部分

一、接收普通消息

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

关于MsgId,官方给出解释,相当于每个消息ID,关于重试的消息排重,推荐使用msgid排重。微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。

比如文本消息的Xml示例

 
  
  
 1348831860 
  
  
 1234567890123456 
  

其他的消息去官方文档查看,简单封装如下
消息抽象基类AbstractMsg.java

package com.phil.wechat.msg.model.req; 
 
import java.io.Serializable; 
 
/** 
 * 基础消息类 
 * 
 * @author phil 
 * 
 */ 
public abstract class AbstractMsg implements Serializable { 
  
 private static final long serialVersiOnUID= -6244277633057415731L; 
 private String ToUserName; // 开发者微信号 
 private String FromUserName; // 发送方帐号(一个OpenID) 
 private String MsgType = SetMsgType(); // 消息类型 例如 /text/image 
 private long CreateTime; // 消息创建时间 (整型) 
 private long MsgId; // 消息id,64位整型 
 /** 
  * 消息类型 
  * 
  * @return 
  */ 
 public abstract String SetMsgType(); 
} 

文本消息TextMsg.java

package com.phil.wechat.msg.model.req; 
 
/** 
 * 文本消息 
 * @author phil 
 * @date 2017年6月30日 
 * 
 */ 
public class TextMsg extends AbstractMsg { 
 
 private static final long serialVersiOnUID= -1764016801417503409L; 
 private String Content; // 文本消息 
 @Override 
 public String SetMsgType() { 
  return "text"; 
 } 
} 

其他的依样画葫芦......

二、被动回复用户消息

微信服务器在将用户的消息发给公众号的开发者服务器地址(开发者中心处配置)后,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次,如果在调试中,发现用户无法收到响应的消息,可以检查是否消息处理超时。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。

如果出现“该公众号暂时无法提供服务,请稍后再试”,原因有两个

  • 开发者在5秒内未回复任何内容
  • 开发者回复了异常数据

比如回复的文本消息Xml示例

 
 
 
12345678 
 
 
 

简单封装下

回复消息抽象基类RespAbstractMsg.java

package com.phil.wechat.msg.model.resp; 
 
import java.io.Serializable; 
 
/** 
 * 消息基类(公众帐号 -> 普通用户) 
 * 
 * @author phil 
 * 
 */ 
public abstract class RespAbstractMsg{ 
 // 接收方帐号(收到的OpenID) 
 private String ToUserName; 
 // 开发者微信号 
 private String FromUserName; 
 // 消息创建时间 (整型) 
 private long CreateTime; 
 // 消息类型(text/music/news) 
 private String MsgType = setMsgType(); // 消息类型 
 public abstract String setMsgType(); 
} 

回复文本消息RespTextMsg.java

package com.phil.wechat.msg.model.resp; 
 
/** 
 * 回复图片消息 
 * 
 * @author phil 
 * @data 2017年3月26日 
 * 
 */ 
public class RespImageMsg extends RespAbstractMsg { 
 private Image Image; 
 @Override 
 public String setMsgType() { 
  return "image"; 
 } 
 
 /** 
  * 
  * @author phil 
  * @date 2017年7月19日 
  * 
  */ 
 public class Image { 
 
  // 通过素材管理中的接口上传多媒体文件,得到的id。 
  private String MediaId; 
 
  public String getMediaId() { 
   return MediaId; 
  } 
 
  public void setMediaId(String mediaId) { 
   MediaId = mediaId; 
  } 
 } 
} 

其他消息类型依样画葫芦......

三、消息的处理

掌握xml解析

package com.phil.wechat.msg.controller; 
 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.Map; 
import java.util.Objects; 
 
import org.apache.commons.lang3.StringUtils; 
import org.dom4j.DocumentException; 
import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
 
import com.phil.modules.config.WechatConfig; 
import com.phil.modules.util.MsgUtil; 
import com.phil.modules.util.SignatureUtil; 
import com.phil.modules.util.XmlUtil; 
import com.phil.wechat.base.controller.BaseController; 
import com.phil.wechat.base.result.WechatResult; 
import com.phil.wechat.msg.model.req.BasicMsg; 
import com.phil.wechat.msg.model.resp.RespAbstractMsg; 
import com.phil.wechat.msg.model.resp.RespNewsMsg; 
import com.phil.wechat.msg.service.WechatMsgService; 
 
/** 
 * @author phil 
 * @date 2017年9月19日 
 * 
 */ 
@Controller 
@RequestMapping("/wechat") 
public class WechatMsgController extends BaseController { 
  
 private Logger logger = LoggerFactory.getLogger(this.getClass()); 
  
 @Autowired 
 private WechatMsgService wechatMsgService; 
  
 /** 
  * 校验信息是否是从微信服务器发出,处理消息 
  * @param out 
  * @throws IOException 
  */ 
 @RequestMapping(value = "/handler", method = { RequestMethod.GET, RequestMethod.POST }) 
 public void processPost() throws Exception { 
  this.getRequest().setCharacterEncoding("UTF-8"); 
  this.getResponse().setCharacterEncoding("UTF-8"); 
  boolean ispost = Objects.equals("POST", this.getRequest().getMethod().toUpperCase()); 
  if (ispost) { 
   logger.debug("接入成功,正在处理逻辑"); 
   String respXml = defaultMsgDisPose(this.getRequest().getInputStream());//processRequest(request, response); 
   if (StringUtils.isNotBlank(respXml)) { 
    this.getResponse().getWriter().write(respXml); 
   } 
  } else { 
   String signature = this.getRequest().getParameter("signature"); 
   // 时间戳 
   String timestamp = this.getRequest().getParameter("timestamp"); 
   // 随机数 
   String nOnce= this.getRequest().getParameter("nonce"); 
   // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 
   if (SignatureUtil.checkSignature(signature, timestamp, nonce)) { 
    // 随机字符串 
    String echostr = this.getRequest().getParameter("echostr"); 
    logger.debug("接入成功,echostr {}", echostr); 
    this.getResponse().getWriter().write(echostr); 
   } 
  } 
 } 
 
 /** 
  * 默认处理方法 
  * @param input 
  * @return 
  * @throws Exception 
  * @throws DocumentException 
  */ 
 private String defaultMsgDisPose(InputStream inputStream) throws Exception { 
  String result = null; 
  if (inputStream != null) { 
   Map params = XmlUtil.parseStreamToMap(inputStream); 
   if (params != null && params.size() > 0) { 
    BasicMsg msgInfo = new BasicMsg(); 
    String createTime = params.get("CreateTime"); 
    String msgId = params.get("MsgId"); 
    msgInfo.setCreateTime((createTime != null && !"".equals(createTime)) ? Integer.parseInt(createTime) : 0); 
    msgInfo.setFromUserName(params.get("FromUserName")); 
    msgInfo.setMsgId((msgId != null && !"".equals(msgId)) ? Long.parseLong(msgId) : 0); 
    msgInfo.setToUserName(params.get("ToUserName")); 
    WechatResult resultObj = coreHandler(msgInfo, params); 
    if(resultObj == null){ // 
     return null; 
    } 
    boolean success = resultObj.isSuccess(); //如果 为true,则表示返回xml文件, 直接转换即可,否则按类型 
    if (success) { 
     result = resultObj.getObject().toString(); 
    } else { 
     int type = resultObj.getType(); // 这里规定 1 图文消息 否则直接转换 
     if (type == WechatResult.NEWSMSG) { 
      RespNewsMsg newsMsg = (RespNewsMsg) resultObj.getObject(); 
      result = MsgUtil.newsMsgToXml(newsMsg); 
     } else { 
      RespAbstractMsg basicMsg = (RespAbstractMsg) resultObj.getObject(); 
      result = MsgUtil.msgToXml(basicMsg); 
     } 
    } 
   } else { 
    result = "msg is wrong"; 
   } 
  } 
  return result; 
 } 
  
 /** 
  * 核心处理 
  * 
  * @param msg 
  *   消息基类 
  * @param params 
  *   xml 解析出来的 数据 
  * @return 
  */ 
 private WechatResult coreHandler(BasicMsg msg, Map params) { 
  WechatResult result = null; 
  String msgType = params.get("MsgType"); 
  if (StringUtils.isEmpty(msgType)) { 
   switch (msgType) { 
   case WechatConfig.REQ_MESSAGE_TYPE_TEXT: // 文本消息 
    result = wechatMsgService.textMsg(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_IMAGE: // 图片消息 
    result = wechatMsgService.imageMsg(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_LINK: // 链接消息 
    result = wechatMsgService.linkMsg(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_LOCATION: // 地理位置 
    result = wechatMsgService.locationMsg(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_VOICE: // 音频消息 
    result = wechatMsgService.voiceMsg(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_SHORTVIDEO: // 短视频消息 
    result = wechatMsgService.shortvideo(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_VIDEO: // 视频消息 
    result = wechatMsgService.videoMsg(msg, params); 
    break; 
   case WechatConfig.REQ_MESSAGE_TYPE_EVENT: // 事件消息 
    String eventType = params.get("Event"); // 
    if (eventType != null && !"".equals(eventType)) { 
     switch (eventType) { 
     case WechatConfig.EVENT_TYPE_SUBSCRIBE: 
      result = wechatMsgService.subscribe(msg, params); 
      break; 
     case WechatConfig.EVENT_TYPE_UNSUBSCRIBE: 
      result = wechatMsgService.unsubscribe(msg, params); 
      break; 
     case WechatConfig.EVENT_TYPE_SCAN: 
      result = wechatMsgService.scan(msg, params); 
      break; 
     case WechatConfig.EVENT_TYPE_LOCATION: 
      result = wechatMsgService.eventLocation(msg, params); 
      break; 
     case WechatConfig.EVENT_TYPE_CLICK: 
      result = wechatMsgService.eventClick(msg, params); 
      break; 
     case WechatConfig.EVENT_TYPE_VIEW: 
      result = wechatMsgService.eventView(msg, params); 
      break; 
     case WechatConfig.KF_CREATE_SESSION: 
      result = wechatMsgService.kfCreateSession(msg, params); 
      break; 
     case WechatConfig.KF_CLOSE_SESSION: 
      result = wechatMsgService.kfCloseSession(msg, params); 
      break; 
     case WechatConfig.KF_SWITCH_SESSION: 
      result = wechatMsgService.kfSwitchSession(msg, params); 
      break; 
     default: 
      wechatMsgService.eventDefaultReply(msg, params); 
      break; 
     } 
    } 
    break; 
   default: 
    wechatMsgService.defaultMsg(msg, params); 
   } 
  } 
  return result; 
 } 
} 

只是提供个思路,如若参考代码请移步

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 解决CSS因MIME类型不匹配导致的加载失败问题
    本文详细介绍了在Web开发过程中,遇到CSS文件因MIME类型不匹配而无法正确加载的问题及其解决方案,适合前端开发者阅读。 ... [详细]
  • 解决getallheaders函数导致的500错误及8种服务器性能优化策略
    本文探讨了解决getallheaders函数引起的服务器500错误的方法,并介绍八种有效的服务器性能优化技术,包括内存数据库的应用、Spark RDD的使用、缓存策略的实施、SSD的引入、数据库优化、IO模型的选择、多核处理策略以及分布式部署方案。 ... [详细]
  • 深入理解FastDFS
    FastDFS是一款高效、简洁的分布式文件系统,广泛应用于互联网应用中,用于处理大量用户上传的文件,如图片、视频等。本文探讨了FastDFS的设计理念及其如何通过独特的架构设计提高性能和可靠性。 ... [详细]
  • 本文详细介绍了如何手动编写兼容IE的Ajax函数,以及探讨了跨域请求的实现方法和原理,包括JSONP和服务器端设置HTTP头部等技术。 ... [详细]
  • ###########性能监控脚本###########################!binbash#监控cpu系统负载IPifconfigeth0|grepinetaddr ... [详细]
  • 本文介绍了jQuery的基本使用方法及AJAX技术的基础知识,包括选择器、事件处理、DOM操作、动画效果等核心功能,以及如何利用AJAX实现页面的部分刷新。 ... [详细]
  • 本文详细解析了Tomcat服务器的核心配置文件server.xml,包括其主要功能、结构组成及各标签的具体作用。 ... [详细]
  • 本文详细介绍如何在Android模拟器上安装TaintDroid的过程,包括解决源代码链接失效及服务器文件变动等问题,旨在帮助后续用户避免不必要的麻烦。 ... [详细]
  • 增强Tomcat安全性:有效防止后台攻击
    在构建可靠的系统架构时,确保安全是至关重要的一步。本文将重点探讨Tomcat这一流行的开源Web应用服务器的安全配置,以帮助开发者和运维人员提高其应用程序的安全性。 ... [详细]
  • 本文介绍如何使用 Google 开发的 libphonenumber 库在 Java 应用中实现电话号码的有效性验证。该库不仅支持多种国际电话号码的格式化与解析,还提供了一系列强大的验证工具。 ... [详细]
  • 本文探讨了Go语言(Golang)的学习价值及其在Web开发领域的应用潜力,包括其独特的语言特性和为什么它是现代软件开发的理想选择。 ... [详细]
  • Linux中实用的文件传输命令:rz与sz
    在生物信息学研究中,频繁地在本地与远程Linux服务器间传输文件是一项常见需求。无论是上传待分析的数据集还是下载处理后的结果,高效便捷的文件传输方法至关重要。 ... [详细]
  • 本文详细记录了在Ubuntu 9.10操作系统上从零开始搭建LAMP(Linux, Apache, MySQL, PHP)环境的过程,包括遇到的问题及解决方案。旨在为初次尝试搭建LAMP环境的开发者提供参考。 ... [详细]
  • CentOS 7.4 KVM虚拟化平台搭建指南
    本文详细介绍了如何在CentOS 7.4系统上搭建KVM虚拟化平台,包括环境准备、网络配置、KVM安装与管理等步骤,适用于希望利用KVM进行虚拟化部署的技术人员。 ... [详细]
  • 告别酷暑,Python带你探寻全国最热城市
    随着九月的到来,炎热的夏季似乎终于画上了句号。对于许多人来说,夏天不仅仅是高温的代名词,更是对户外活动的一种限制。本文将通过Python编程技术,带领读者探索并找出今年夏季全国最热的城市。 ... [详细]
author-avatar
mobiledu2502876293
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有