最近刚做了微信开放平台全网发布的开发,整理一下贴出来

前置条件 已经做好了相关的开发工作(比如扫码授权之类的),项目导入了微信SDK(最后会附上我自己用的SDK jar包)

sdk jar 地址: https://github.com/liyiorg/weixin-popular

BUG :weixin.popular.bean.message.EventMessage 内的@XmlElement(name = "MsgID") private String msgId; // 消息ID号 红色处原来D是小写,应该是大写,不知道现在改了没有,自己注意

platformToken:你要全网发布的开放平台填写的token,  platformAESKey:你要全网发布的开放平台填写的加密秘钥,  platformAppId:你要全网发布的开放平台的appId

 /*** 功能描述:扫码授权,第三方开放平台每10分钟推送一次component_verify_ticket接受处理方法,这是controller* @author yanfei.li* @date 2017年9月26日 下午3:42:24  * @param request* @param response* @return "success"* @throws BusinessException*/@RequestMapping(value = "/platform/event/receive")@ResponseBodypublic String receiver(HttpServletRequest request, HttpServletResponse response) throws BusinessException{  try {ServletInputStream inputStream = request.getInputStream();if (inputStream != null) {String xmlData = StreamUtils.copyToString(inputStream,Charset.forName("utf-8"));String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String msgSignature = request.getParameter("msg_signature");//解密,platformToken:你要全网发布的开放平台填写的token,  platformAESKey:你要全网发布的开放平台填写的加密秘钥,  platformAppId:你要全网发布的开放平台的appIdWXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(platformToken, platformAESKey, platformAppId);xmlData = wxBizMsgCrypt.decryptMsg(msgSignature, timestamp, nonce, xmlData);//下面是将component_verify_ticket 信息保存到自己的数据库,这一块应该是调用service再调用dao的,为了方便整合到一起了,自己拆分。//转换成map,XMLConverUtil是微信SDK的工具Map<String,String> xmlMap=XMLConverUtil.convertToMap(xmlData);String appId = xmlMap.get("AppId");String componentVerifyTicket = xmlMap.get("ComponentVerifyTicket");Date createTime = new Date(Long.parseLong(xmlMap.get("CreateTime"))*1000);String infoType = xmlMap.get("InfoType");String authorizerAppid = xmlMap.get("AuthorizerAppid");String authCode = xmlMap.get("AuthorizationCode");String authCodeExpiredTime = xmlMap.get("AuthorizationCodeExpiredTime");//数据库表实体初始化WechatVerifyTicketEntity verifyticket = null;verifyticket = verifyticketDao.findOne(appId, infoType);if(verifyticket == null ) {verifyticket = new WechatVerifyTicketEntity();}verifyticket.setAppId(appId);verifyticket.setCreateTime(createTime);verifyticket.setInfoType(infoType);verifyticket.setAuthorizerAppid(authorizerAppid);verifyticket.setAuthCode(authCode);verifyticket.setAuthCodeExpiredTime(authCodeExpiredTime);verifyticket.setVerifyTicket(componentVerifyTicket);//保存到数据库this.verifyticketDao.saveOrUpdate(verifyticket);}} catch (IOException | AesException e) {logger.error("/wxopen/platform/event/receive error: ", e);} //不管出没出错,都返回了success,出错信息自己查自己的日志return "success";}

消息与事件推送受理入口

 /*** 功能描述:微信消息与事件推送 接受处理方法入口* @author yanfei.li* @date 2017年9月26日 下午3:44:29  * @param appid 公众号appid* @param request* @param response* @throws BusinessException*/@RequestMapping(value = "/platform/callback/{appid}")@ResponseBodypublic void callback(@PathVariable("appid") String appid, HttpServletRequest request, HttpServletResponse response) throws BusinessException{  try{ServletInputStream inputStream = request.getInputStream();if (inputStream != null) {//StreamUtils 微信SDK的工具类String xmlData = StreamUtils.copyToString(inputStream,Charset.forName("utf-8"));inputStream.close();String timestamp = request.getParameter("timestamp");String nonce = request.getParameter("nonce");String msgSignature = request.getParameter("msg_signature");//解密WXBizMsgCrypt wxBizMsgCrypt = new WXBizMsgCrypt(platformToken, platformAESKey, platformAppId);xmlData = wxBizMsgCrypt.decryptMsg(msgSignature, timestamp, nonce, xmlData);logger.info("==>receiveData=" + xmlData );EventMessage eventMessage = null;eventMessage = XMLConverUtil.convertToObject(EventMessage.class, xmlData);if("wx570bc396a51b8ff8".equals(appid)){//全网发布,wx570bc396a51b8ff8是固定的微信全网发布测试公众号appidpublishThirdPlatform(eventMessage, request, response);}else {//正常业务处理normalBusiness(appid, eventMessage, request, response);}}else {responseReplyMessage(response,"success");}}catch(Exception e){logger.error("/wxopen/platform/callback/" + appid + " error: ", e);if(!(e instanceof IOException)){try {responseReplyMessage(response,"success");} catch (IOException e1) {logger.error("/wxopen/platform/callback/" + appid + " return error: ", e1);}}else {logger.error("IOException");}}}

全网发布相关处理函数

 /*** 功能描述:全网发布主函数处理入口* @author yanfei.li* @date 2017年9月26日 下午3:41:22  * @param eventMessage* @param request* @param response* @throws IOException* @throws AesException */private void publishThirdPlatform(EventMessage eventMessage,HttpServletRequest request, HttpServletResponse response) throws IOException, AesException{String event = eventMessage.getMsgType();if("event".equals(event)){replyEventMessage(request, response,eventMessage);}else if ("text".equals(eventMessage.getMsgType())) {replyTextMessage(request, response, eventMessage);}}/*** 功能描述:全网发布,步骤二、三 回复文本消息* @author yanfei.li* @date 2017年9月26日 下午4:10:56  * @param request* @param response* @param eventMessage* @throws BusinessException * @throws IOException */private void replyTextMessage(HttpServletRequest request, HttpServletResponse response, EventMessage eventMessage) throws BusinessException, IOException{if(eventMessage == null){throw new BusinessException(BusinessException.ERROR_INTERNAL_SERVER_ERROR, "==>replyTextMessage,eventMessage is null");}String content = eventMessage.getContent();if("TESTCOMPONENT_MSG_TYPE_TEXT".equals(content)){//步骤二,回复文本消息content = content + "_callback";StringBuffer sb = new StringBuffer();  sb.append("<xml>");  sb.append("<ToUserName><![CDATA["+eventMessage.getFromUserName()+"]]></ToUserName>");  sb.append("<FromUserName><![CDATA["+eventMessage.getToUserName()+"]]></FromUserName>");  sb.append("<CreateTime>"+eventMessage.getCreateTime()+"</CreateTime>");  sb.append("<MsgType><![CDATA[text]]></MsgType>");  sb.append("<Content><![CDATA["+content+"]]></Content>");sb.append("</xml>");  String replyMsg = sb.toString();String returnValue = "";WXBizMsgCrypt pc;try {//platformToken:你要全网发布的开放平台填写的token,  platformAESKey:你要全网发布的开放平台填写的加密秘钥,  platformAppId:你要全网发布的开放平台的appIdpc = new WXBizMsgCrypt(platformToken, platformAESKey, platformAppId);returnValue = pc.encryptMsg(replyMsg, eventMessage.getCreateTime().toString(), request.getParameter("nonce"));responseReplyMessage(response,returnValue);} catch (AesException e) {throw new BusinessException(BusinessException.ERROR_INTERNAL_SERVER_ERROR, "replyTextMessage",e);}}else {//步骤三,回复空字符串,然后调用客服接口发送消息String touser = eventMessage.getFromUserName();//因为是往回发,所有接收人是消息发送人,容易写错String authCode = content.replaceAll("QUERY_AUTH_CODE:", "");//authcode 用于“使用授权码换取公众号的授权信息”API,将$query_auth_code$的值赋值给API所需的参数authorization_code获取接口调用凭证。try {//直接回复""字符串responseReplyMessage(response,"");} catch (IOException e) {throw new BusinessException(BusinessException.ERROR_INTERNAL_SERVER_ERROR, "replyTextMessage",e);}//调用客服接口发送消息//获取测试公众号接口调用凭证,接口方法实现 见最后同名方法String authorizerAccessToken = this.wechatTokenService.publishGetToken(authCode);if(authorizerAccessToken == null){throw new BusinessException(BusinessException.ERROR_INTERNAL_SERVER_ERROR, "==>get authorizer access token failure,value is null");}//Message TextMessage是微信SDK的Message message = new TextMessage(touser,authCode+"_from_api");//发送客服消息weixin.popular.api.MessageAPI.messageCustomSend(token,JSON.toJSONString(message));}}/*** 功能描述:全网发布,步骤一回复事件消息* @author yanfei.li* @date 2017年9月26日 下午4:34:14  * @param request* @param response* @param eventMessage* @throws IOException* @throws AesException */private void replyEventMessage(HttpServletRequest request, HttpServletResponse response, EventMessage eventMessage) throws BusinessException, IOException{if(eventMessage == null){throw new BusinessException(BusinessException.ERROR_INTERNAL_SERVER_ERROR, "==>replyEvetMessage,eventMessage is null");}String content = eventMessage.getEvent() + "from_callback";StringBuffer sb = new StringBuffer();sb.append("<xml>");  sb.append("<ToUserName><![CDATA["+eventMessage.getFromUserName()+"]]></ToUserName>");  sb.append("<FromUserName><![CDATA["+eventMessage.getToUserName()+"]]></FromUserName>");  sb.append("<CreateTime>"+eventMessage.getCreateTime()+"</CreateTime>");  sb.append("<MsgType><![CDATA[text]]></MsgType>");  sb.append("<Content><![CDATA["+content+"]]></Content>");  sb.append("</xml>");  String replyMsg = sb.toString(); String returnValue = "";WXBizMsgCrypt pc;try {//platformToken:你要全网发布的开放平台填写的token,  platformAESKey:你要全网发布的开放平台填写的加密秘钥,  platformAppId:你要全网发布的开放平台的appIdpc = new WXBizMsgCrypt(platformToken, platformAESKey, platformAppId);returnValue = pc.encryptMsg(replyMsg, eventMessage.getCreateTime().toString(), request.getParameter("nonce"));responseReplyMessage(response,returnValue);} catch (AesException e) {throw new BusinessException(BusinessException.ERROR_INTERNAL_SERVER_ERROR, "replyEventMessage",e);}}/*** 统一回复微信服务器     * @param response* @param content* @throws IOException*/public void responseReplyMessage(HttpServletResponse response,String content) throws IOException{PrintWriter pw = response.getWriter();pw.write(content);pw.flush();pw.close();} /*** 功能描述:获取access_token* @author yanfei.li* @date 2017年9月27日 下午2:18:24  * @param authCode* @return*/public String publishGetToken(String authCode) {if(authCode == null){logger.error("================>publishGetToken,authCode is null");return null;}//获取每十分钟推送一次的那个ticket, platformAppId:你要全网发布的开放平台的appIdString verifyTicket = this.verifyticketDao.getRecentTicket(platformAppId);if(verifyTicket == null){logger.error("================>publishGetToken,verifyTicket is null");return null;}//获取开放平台access_token,appSecret:你要全网发布的开放平台的appsecret,  appId:你要全网发布的开放平台的appIdComponentAccessToken accessToken = weixin.popular.api.ComponentAPI.api_component_token(appId, appSecret, verifyTicket);if(accessToken == null){logger.error("================>publishGetToken,accessToken is null");return null;}String accessTokenStr = accessToken.getComponent_access_token();ApiQueryAuthResult queryAuth = weixin.popular.api.ComponentAPI.api_query_auth(accessToken, appId, authCode);if(queryAuth == null){logger.error("================>publishGetToken,queryAuth is null");return null;}return queryAuth.getAuthorization_info().getAuthorizer_access_token();}

结合微信SDK工具包  实现的。请忽略日志打印,不能直接复制使用,另外正常的业务处理分支没有贴出来,只贴了全网发布的。消息推送入口对全网发布和正常业务处理做了分流处理,不影响原本的项目

全网发布,开放平台注意事项

1.公众号的IP白名单只针对通过公众号的appid和secret获取access_token时有效(直接通过api接口调用https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=xxx&secret=xxx),如果是通过扫码授权即微信开放平台则IP白名单无效(个人推测微信开放平台在所有微信公众号的默认白名单内),最好配置IP白名单,这样在appid和secret泄露后还有一层保护,因为IP白名单的修改需要管理员扫码确认,不能直接通过这俩值获取token

2.微信开放平台全网发布前,只接受授权测试公众号列表内的授权,一旦全网发布后会支持所有微信公众的授权。IP白名单配置的是访问开放平台的服务器的IP地址,发布不发布都需要,否则会报错

3.开放平台IP白名单的修改没有在发布的范畴内,可随时更改

4.调用开放平台接口所需要的appId和secret是对应开放平台应用的,跟公众号没有关系

5.授权事件接受URL主要是每十分钟推送一次component_verify_ticket,该值用户获取开放平台的接口调用凭证的参数之一

6.开放平台的公众号消息校验Token和加解密Key可以自己定义,但一定要和我们开发配置中保持对应一致

7.公众号消息与事件接受URL会将粉丝跟公众号的互动推送到该URL,%APPID%是当前公众号的APPID

8.已经发布的开放平台内容可以更改,更改完了还需要进行一次全网发布,会有一个覆盖现有发布,需要审核,审核完成之前将继续使用上次发布的内容

微信开放平台全网发布相关推荐

  1. 微信开放平台全网发布时,检测失败 —— C#

    主要就是三个:返回API文本消息,返回普通文本消息,发送事件消息   --会出现失败的情况 (后续补充说明:出现检测出错,不一定是代码出现了问题,也有可能是1.微信方面检测时出现服务器请求失败,2.我 ...

  2. 开放平台全网发布php,微信开放平台 全网发布 组件ticket检测失败

    api接口文本错误的 之前我也是遇到问题 困扰几天了终于搞好了 问题是这样解决的 发现有点坑爹 他这两个接口要求的code取值不一样 第三方平台方拿到$query_auth_code$的值后,通过接口 ...

  3. 微信三方平台全网发布总结

    相信很多第一次玩三方平台全网发布的童鞋同会遇到很多问题.这里将这两天我们在全网发布测试中遇到的问题做个总结,希望对大家有用: 在这里首先感慨一下微信有点店大欺客的感觉,文档写的确实不咋地,包括微信支付 ...

  4. 开放平台全网发布php,微信开放平台开发-受权、全网发布(PHP)

    接着看看全网发布的测试用例怎么作: 一.模拟粉丝触发专用测试公众号的事件,并推送事件消息到专用测试公众号,第三方平台方开发者须要提取推送XML信息中的event值,并在5秒内当即返回按照下述要求组装的 ...

  5. java微信第三方平台全网发布(三)

    在java微信第三方平台开发(二)中写了授权事件的处理,并且第三方平台代公众号发起网页授权,获取用户信息和发红包等基本业务.接下来代公众号处理消息和事件.这时候就需要用到在开发者资料中填写的公众号消息 ...

  6. 微信开放平台(公众号第三方平台) -- 全网发布

    一.微信开放平台,第三方平台,全网发布怎么通 过?  二. 微信开放平台 全网发布 组件ticket检测失败?      解决步骤 1.将附件中的代码发布到你配置的域名下: 2.直接点全网发布: 3. ...

  7. 微信开放平台-第三方平台-全网发布接入【java版本】

    微信给出的文档 概述 在第三方平台方创建成功并最终开发测试完毕,提交全网发布申请时,微信服务器会通过自动化测试的方式,检测服务的基础逻辑是否可用,在确保基础可用的情况下,才会允许公众号第三方平台提交全 ...

  8. 微信开放平台之公众号第三方平台开发及全网发布验证

    技术交流请加QQ群:Jeewx微信开发④[289709451] 微信公众号第三方平台的开放,让公众号运营者在面向垂直行业需求时,可以通过一键登录授权给第三方开发者,来完成相关的处理能力,方便快捷,那如 ...

  9. mysql 推送微信公众号_10分钟完成微信公众号第三方平台全网发布

    背景:在微信公众平台配置服务器URL时,使用了新浪云SAE自带的二级域名,提交时出现一个安全风险的警告,网上查了下,许多服务平台和团队也遇到同样的问题. 经过一番研究 - 为什么会有安全风险的警告? ...

最新文章

  1. 解决 PermGen space Tomcat内存设置
  2. scanf 接收 空格 输入_【C/C++】【输入】关于scanf:输入空格,多次使用
  3. Unity编译Mono
  4. java ftp 中文上传_java实现ftp文件上传下载,解决慢,中文乱码,多个文件下载等问题...
  5. 疑问:关于Microsoft Office InfoPath 2003 Toolkit for Visual Studio 2005 Beta 2
  6. ASP.NET Core 认证与授权[5]:初识授权
  7. 已知有几个数据存放在BUF为首址的字节存储区中,试统计其中正数的个数,并将结果存入ZNUM单元中。
  8. java int相除向上取整_java实战项目常用类,Date、Calendar、BigDecimal、Math、UUID
  9. 用python重构策略模式
  10. 工业物联网卡未来发展的优势和特点
  11. iOS开发,自定义字体,字体名称查询
  12. Android筑基——深入理解 LayoutInflater.inflate() 方法
  13. Windows的hosts文件在哪里?
  14. 怎么进行PDF合并?PDF合并方法
  15. 科目二经验之谈 10小时必过秘笈
  16. Win 10 任务栏中Google开启时出现两个Google图标
  17. gpasswd命令简介
  18. 京东科技风格 NutUI 发布了
  19. 对象数据如何转化成数组
  20. JavaScript 发明者布兰登·艾克成为 Mozilla CEO

热门文章

  1. 春晚的科技梦,与科技企业的春晚梦
  2. oracle怎么deadlock,APPARENT DEADLOCK!!! 错误解决过程
  3. [解决办法] Caused by: java.util.regex.PatternSyntaxException: Dangling meta character '*' near index 0
  4. IDEA 运行Java swing项目报错误: # Problematic frame: # C [rxtxSerial.dll+0x4465]
  5. pmsm simulink foc 仿真_汽车雷达场景仿真方法的研究
  6. java打印各种三角形
  7. 【论文阅读--WSOL】Spatial-Aware Token for Weakly Supervised Object Localization
  8. 算法刷题【一本通YbtOJ1488】新的开始
  9. 禅道CMS文件上传漏洞(CNVD-C-2020-121325)
  10. 每日学术速递5.26