• 微信开发中的消息验证与消息回复处理逻辑 判断微信服务器传来的数据是否含有名为echostr的GET参数 有则进行服务器消息验证(valid) 没有则微信推送过来的是一条消息,需要我们处理。 消息类型分为 1)事件类型:...

    微信开发中的消息验证与消息回复

    处理逻辑

    1. 判断微信服务器传来的数据是否含有名为echostr的GET参数
    2. 有则进行服务器消息验证(valid)
    3. 没有则微信推送过来的是一条消息,需要我们处理。
      消息类型分为
      1)事件类型:用户关注/取消关注事件、扫描二维码事件……
      2)被动回复类型:用户发送过来一条文字、图片、语音……
      然后根据需求回复相应的文字、图片、图文….

    代码示例

    <?php
    define("TOKEN","###your token###");
    require_once 'response.class.php';
    
    $res=new response();
    if(!isset($_GET['echostr'])){
        responseMsg();
    }else{
        valid();
    }
    
    function valid(){
        /* @微信服务器消息验证
         *
         * 1)将token、timestamp、nonce三个参数进行字典序排序
         * 2)将三个参数字符串拼接成一个字符串进行sha1加密
         * 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
         *
         * */
        $echoStr=$_GET['echostr'];
        $signature=$_GET['signature'];
        $timestamp=$_GET['timestamp'];
        $nonce=$_GET['nonce'];
        $token=TOKEN;
        $tmpArr=array($token,$timestamp,$nonce);
        sort($tmpArr,SORT_STRING);
        $tmpStr=implode($tmpArr);
        $tmpStr=sha1($tmpStr);
        if($tmpStr==$signature){
            echo $echoStr;
            exit();
        }
    }
    
    function responseMsg(){
        /* @获取微信推送过来的post数据(xml)
         * 
         * 以下旧的提取方式,php高版本已经废弃了
         * $postStr=$GLOBALS['HTTP_RAW_POST_DATA'];
         * 
         * */
        $postStr=file_get_contents("php://input");
    
        /* @将xml数据转化为obj
         * 
         * */
        $postObj=simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);
    
        /* @根据接收到的不同消息,进行相应回复
         * 1.用户关注事件
         * 2.用户发送消息被动回复
         * 
         * */
        if(strtolower($postObj->MsgType)=='event'){
            if(strtolower($postObj->Event)=='subscribe'){//用户关注事件
                $content="欢迎关注XXXX";
                responseText($postObj, $content);
            }
        }else if(strtolower($postObj->MsgType)=='text'){
            switch(trim($postObj->Content)){
                /*被动回复文本信息*/
                case 'test':
                    $content="this is test!";
                    responseText($postObj, $content);
                    break;
                case 'time':
                    $content="现在是北京时间:".date("Y-m-d H:i:s",time());
                    responseText($postObj, $content);
                    break;
                case 'website':
                    $content="<a href='http://www.hewie.cn'>乘风破浪</a>";
                    responseText($postObj, $content);
                    break;
                /*被动回复图文信息*/
                case 'news':
                    $arr=array(
                        array(
                        'title'=>'我的csdn博客',
                        'description'=>'欢迎访问我的csdn博客',
                        'picUrl'=>'http://avatar.csdn.net/9/5/4/1_somehow1002.jpg',
                        'url'=>'http://blog.csdn.net/somehow1002',
                        ),
                        array(
                        'title'=>'开源中国',
                        'description'=>'。。。。。',
                        'picUrl'=>'https://www.oschina.net/img/ie/logo_osc.png','',
                        'url'=>'https://www.oschina.net/',
                        ),
                    );
                    responseNews($postObj, $arr);
                    break;
                default:
                    $content="sorry, I don't understand!";
                    $res->responseText($postObj, $content);
                    break;
            }
        }
    }
    
    function responseText($postObj,$content){
        /* @文字消息回复格式
         * 
         * <xml>
         * <ToUserName><![CDATA[toUser]]></ToUserName>
         * <FromUserName><![CDATA[fromUser]]></FromUserName>
         * <CreateTime>12345678</CreateTime>
         * <MsgType><![CDATA[text]]></MsgType>
         * <Content><![CDATA[你好]]></Content>
         * </xml>
         * 
         * */
        $fromUserName=$postObj->ToUserName;
        $toUserName=$postObj->FromUserName;
        $time=time();
        $msgType='text';
        $template="<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        </xml>";
        echo sprintf($template,$toUserName,$fromUserName,$time,$msgType,$content);
    }
    
    function responseNews($postObj,$arr){
        /* @图文消息回复格式
         * #一个item一则图文消息
         * 
         * <xml>
         * <ToUserName><![CDATA[toUser]]></ToUserName>
         * <FromUserName><![CDATA[fromUser]]></FromUserName>
         * <CreateTime>12345678</CreateTime>
         * <MsgType><![CDATA[news]]></MsgType>
         * <ArticleCount>2</ArticleCount>
         * <Articles>
         * <item>
         * <Title><![CDATA[title1]]></Title>
         * <Description><![CDATA[description1]]></Description>
         * <PicUrl><![CDATA[picurl]]></PicUrl>
         * <Url><![CDATA[url]]></Url>
         * </item>
         * <item>
         * <Title><![CDATA[title]]></Title>
         * <Description><![CDATA[description]]></Description>
         * <PicUrl><![CDATA[picurl]]></PicUrl>
         * <Url><![CDATA[url]]></Url>
         * </item>
         * </Articles>
         * </xml>
         * 
         * */
        $fromUserName=$postObj->ToUserName;
        $toUserName=$postObj->FromUserName;
        $time=time();
        $msgType='text';
        $template="<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[news]]></MsgType>
                        <ArticleCount>".count($arr)."</ArticleCount>
                        <Articles>";
        foreach($arr as $v){
            $template.="
                        <item>
                        <Title><![CDATA[".$v[title]."]]></Title>
                        <Description><![CDATA[".$v[description]."]]></Description>
                        <PicUrl><![CDATA[".$v['picUrl']."]]></PicUrl>
                        <Url><![CDATA[".$v[url]."]]></Url>
                        </item>";
        }
        $template.="
                        </Articles>
                        </xml>";
        echo sprintf($template,$toUserName,$fromUserName,time());
    }

    参考微信开发手册
    原文地址:http://blog.csdn.net/somehow1002/article/details/76919270
    个人见解,如有错误之处,欢迎指正。

    展开全文
  • 微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开发接口则是提供服务的基础。 接入微信公众平台开发,开发者需要按照如下步骤完成: 1、填写服务器配置 2、验证服务器地址的有效性...

    微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,而公众平台开发接口则是提供服务的基础。

    接入微信公众平台开发,开发者需要按照如下步骤完成:

    1、填写服务器配置

    2、验证服务器地址的有效性

    3、依据接口文档实现业务逻辑

    以上步骤可在微信开发公众官方文档中查看 点击查看

    下面主要说下开发过程中会接触到的一些问题。

    1.微信接入问题

       开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:

    1)将token、timestamp、nonce三个参数进行字典序排序

    2)将三个参数字符串拼接成一个字符串进行sha1加密

    3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

      以上为官方文档内容,具体实现如下

     1 @RequestMapping(value="/wechat.do",method = RequestMethod.GET)
     2     public @ResponseBody String authGet(@RequestParam(value="signature",required=false) String signature,
     3                    @RequestParam("timestamp") String timestamp, 
     4                    @RequestParam("nonce") String nonce,
     5                    @RequestParam("echostr") String echostr) throws Exception {
     6         
     7         String sysytemAppid =(String)wxPropertiesBean.getProperties("system").get("system_appid");
     8         Map config = this.wxMpService.queryWxAccountByCode(sysytemAppid);
     9         String token = (String) config.get("account_token");
    10         if (!WxCryptUtil.checkSignature(token,signature, timestamp, nonce)) {
    11             logger.error("微信接入验证失败!");
    12             return null;
    13         }
    14         return echostr;
    15     }
    public static boolean checkSignature(String token, String signature, String timestamp, String nonce) {
            String[] arr = new String[] { token, timestamp, nonce };
            Arrays.sort(arr);
            StringBuilder content = new StringBuilder();
            for (int i = 0; i < arr.length; i++) {
                content.append(arr[i]);
            }
            MessageDigest md = null;
            String tmpStr = null;
            try {
                md = MessageDigest.getInstance("SHA-1");
                byte[] digest = md.digest(content.toString().getBytes());
                tmpStr = byteToStr(digest);
            } catch (NoSuchAlgorithmException e) {
                
            }
            return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
        }
        
        /**
         * 将字节数组转换为十六进制字符
         *
         * @param byteArray
         * @return
         */
        public static String byteToStr(byte[] byteArray) {
            String strDigest = "";
            for (int i = 0; i < byteArray.length; i++) {
                strDigest += byteToHexStr(byteArray[i]);
            }
            return strDigest;
        }
    
        /**
         * 将字节转换为十六进制字符
         *
         * @param mByte
         * @return
         */
        public static String byteToHexStr(byte mByte) {
            char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
            char[] tempArr = new char[2];
            tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
            tempArr[1] = Digit[mByte & 0X0F];
    
            String s = new String(tempArr);
            return s;
        }

    2.获取access_token

    access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

    接口调用请求说明

    https请求方式: GET
    https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

    参数说明

    参数 是否必须 说明
    grant_type 获取access_token填写client_credential
    appid 第三方用户唯一凭证
    secret 第三方用户唯一凭证密钥,即appsecret

    返回说明

    正常情况下,微信会返回下述JSON数据包给公众号:

    {"access_token":"ACCESS_TOKEN","expires_in":7200}

     

    参数说明

    参数说明
    access_token 获取到的凭证
    expires_in 凭证有效时间,单位:秒
    private String getAcessTokenEntity(Map accountConfig) {
            String requestUrl = (String) wxPropertiesBean.getProperties("wxpt").get("access_token_url");
            Map urlParams = new HashMap();
            urlParams.put("grant_type", "client_credential");
            urlParams.put("appid", accountConfig.get("account_appid"));
            urlParams.put("secret", accountConfig.get("account_appsecret"));
            requestUrl = HttpUtil.getUrl(requestUrl, urlParams);
            try{
                WxApiResult apiResult = HttpUtil.httpsRequest(requestUrl, "GET", null);
                Map result = HttpUtil.getCommonResult(apiResult);
                String accessToken = (String) result.get("access_token");
                if(StringUtils.isBlank(accessToken)){
                    throw new WxErrorException("获取accessToken失败!");
                }
                String accountId = (String) accountConfig.get("account_id");
                wxMpService.updateAccessToken(accountId, accessToken);
                return accessToken;
            }catch (WxErrorException e){
                throw e;
            }catch (Exception e){
                logger.error(e.getMessage());
                throw new WxErrorException("获取accessToken失败!");
            }
        }

    由于access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。我这里是将token落地在自己的库中,单独一张表用于记录和微信相关的所有的配置。
    刷新token后再重新存入表中(包括存入时间记录),每次需要获取token的时候从表中获取,这样可以先判断是否过期,再决定是否需要重新获取。

    未完待续,后面将介绍自定义菜单,oauth2认证等。

    转载于:https://www.cnblogs.com/Onedayzk/p/7792778.html

    展开全文
  • 微信开发校验工具

    2019-04-21 20:51:08
    校验工具 微信 JS 接口签名校验工具 微信卡券JSAPI签名校验工具
    展开全文
  • 接入微信公众平台开发 接入微信公众平台开发,开发者需要...要注意在微信开发中,是需要提供一个外网可以访问的网址,这里我使用natapp映射本地服务器。Natapp的使用这里不做介绍了。Token的填写可以自定义。 如图,

    接入微信公众平台开发
    接入微信公众平台开发,开发者需要按照如下步骤完成:
    1、填写服务器配置
    2、验证服务器地址的有效性
    第一步:填写服务器配置
    这里我用的是测试号,测试号具有所有的权限,方便后面的接口调用。
    这里写图片描述
    要注意在微信开发中,是需要提供一个外网可以访问的网址,这里我使用natapp映射本地服务器。Natapp的使用这里不做介绍了。

    Token的填写可以自定义。
    这里写图片描述
    如图,
    http://lonbon.natapp4.cc等同于http://192.168.2.39:80
    192.168.2.39是本地服务器的ip;80是服务器的端口,微信开发文档规定,以http//开头只支持80端口。
    在IDEA中配置tomcat服务器,如下图,
    这里写图片描述
    项目是创建在IEDA中。
    url中的/respMsg是微信服务器与本地项目进行交互的入口。
    需要在项目的web.xml进行配置,如下图
    这里写图片描述
    第二步:验证消息的确来自微信服务器
    开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:
    参数 描述
    signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    timestamp 时间戳
    nonce 随机数
    echostr 随机字符串

    开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
    1)将token、timestamp、nonce三个参数进行字典序排序
    2)将三个参数字符串拼接成一个字符串进行sha1加密
    3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

    检验signature的Java示例代码:
    新建一个Servlet,继承httpServlet,重写doGet方法,在daGet方法中对signature进行校验。(Tomcat默认执行doGet方法)
    这里写图片描述

    新建一个校验signature的工具类SignUtil,如下
    package com.lonbon.util;

    import java.security.MessageDigest;
    import java.util.Arrays;

    /**
    * 描述: 验证消息的确来自微信服务器
    * Created by hst on 2017/10/20.
    */
    public class SignUtil {
    private static String token = “imooc”;

    public static boolean checkSignature(String signature, String timestamp, String nonce) {
        boolean result = false;
    
        // 对token、timestamp和nonce按字典序排序
        String[] array = new String[]{token, timestamp, nonce};
        Arrays.sort(array);
    
        // 将三个参数字符拼接成一个字符串
        String str = array[0].concat(array[1]).concat(array[2]);
    
        String sha1Str = null;
        try {
            // 对拼接后的字符串进行sha1加密
            MessageDigest md = MessageDigest.getInstance("SHA-1");
            byte[] digest = md.digest(str.getBytes());
            sha1Str = byte2str(digest);
        }
        catch(Exception e) {
        }
    
        if(sha1Str != null &&  sha1Str.equals(signature)) {
            result = true;
        }
    
        return result;
    }
    
    /*
     * 将字节数组转换成字符串
     */
    public static String byte2str(byte[] array) {
        StringBuffer hexstr = new StringBuffer();
        String shaHex="";
        for(int i = 0; i < array.length; i++) {
            shaHex = Integer.toHexString(array[i] & 0xFF);
            if(shaHex.length() < 2) {
                hexstr.append(0);
            }
            hexstr.append(shaHex);
        }
        return hexstr.toString();
    }
    

    }

    这里需要注意一点。Token要和接口配置信息的token一致。

    代码写完后,再去配置接口信息,如果配置失败,大概是服务器没开或者填写的url不对。
    Goog lucky!!!

    展开全文
  • 微信开发验证文件

    2020-07-10 23:31:18
    微信开发token验证文件。可以通过这个文件验证通过微信开发者平台的验证。
  • 一定要先看下官方文档微信消息管理分为接收普通消息、接收事件推送、发送消息(被动回复)、客服消息、群发消息、模板消息这几部分一、接收普通消息当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML...

    一定要先看下官方文档

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

    一、接收普通消息

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

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

    比如文本消息的Xml示例

    <xml>
     <ToUserName><![CDATA[toUser]]></ToUserName>
     <FromUserName><![CDATA[fromUser]]></FromUserName>
     <CreateTime>1348831860</CreateTime>
     <MsgType><![CDATA[text]]></MsgType>
     <Content><![CDATA[this is a test]]></Content>
     <MsgId>1234567890123456</MsgId>
     </xml>
    其他的消息去官方文档查看,简单封装如下

    消息抽象基类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示例
    <xml>
    <ToUserName><![CDATA[toUser]]></ToUserName>
    <FromUserName><![CDATA[fromUser]]></FromUserName>
    <CreateTime>12345678</CreateTime>
    <MsgType><![CDATA[text]]></MsgType>
    <Content><![CDATA[你好]]></Content>
    </xml>
    简单封装下
    回复消息抽象基类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<String, String> 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<String, String> params) {
    		WechatResult result = null;
    		String msgType = params.get("MsgType");
    		if (StringUtils.isNotEmpty(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;
    	}
    }
    只是提供个思路,如若参考代码请移步
    展开全文
  • 微信公众平台是运营者通过公众号为微信用户提供资讯和服务的平台,首先我们登录微信公众平台,通过其后台设置一些基础服务,如菜单设置、消息自动回复,但由于企业服务具有复杂性。通过微信公众平台后台设置一般无法...
  • 微信公众平台开发

    2018-02-22 18:21:13
    在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序、MySQL...启用微信公众平台开发模式 体验常用接收消息及发送消息类型 了解数据收发原理及消息格式 &nbsp; 第一章 申请服务器资源 创建新浪...
  • 我们学习了使用Java语言开发微信公众平台的第一部分——环境搭建与开发接入。那么,本篇文章,我们将在此基础上,学习【消息的接收与响应】。 当然,我们在后续的开发过程中肯定还是离不开微信提供的开发者文档:...
  • 微信公众平台应用开发:方法、技巧与案例》,基于Java语言编写,是目前微信公众平台应用开发领域内容最全面、系统和深入的一本书,也是技术版本最新的。本书系统讲解了微信公众平台应用开发的流程、方法和技巧,并...
  • 前面几篇文章一直都在说微信公众平台开发准备工作,那么从这篇开始我们就将正式的进入JAVA微信公众平台开发的整个流程,那么这篇我们开始聊聊如何将我们的服务端和微信公众平台对接! (一)接入流程解析 ...
  • 微信开发之入门教程

    2016-01-12 10:55:26
    微信开发也是有了一定的认识。在此,小宝鸽再次无私地分享给大家啦。其实微信开发跟web开发没有多大的区别,只是经过了微信,然后再由浏览器打开。因为经过微信,因此你的web会附加一些微信平台所提供的一些功能,...
  • 微信公众平台PHP开发

    2013-07-12 09:51:55
    最近在做微信公众平台开发,一口气写了二十几个功能,挺有意思的~     今天来分享一下开发经验~ 微信公众平台提供的接口很简单,先看看消息交互流程:     说的通俗一些,用户使用微信发送消息 -> 微信将数据...
  • 本文档基于腾讯公司微信二次开发的相关规范,对微信二次开发的流程、步骤做了相关的说明,方便程序设计和开发人员快速掌握微信公众平台开发技术,便于提高代码的编写效率以及减少出现错误概率。 使用范围 本...
  • 本节书摘来自华章计算机《微信公众平台开发:从...3.4 微信开发调试工具 3.4.1 微信调试器 微信调试器是方倍工作室开发的用于微信公众平台接口开发在线调试的工具,具有Token校验、模拟关注及取消关注、发送文本/...
  • 微信开放平台开发系列文章: 微信开放平台开发第三方授权登陆(一):开发前期准备 微信开放平台开发第三方授权登陆(二):PC网页端 微信开放平台开发第三方授权登陆(三):Android客户端 微信开放平台开发第...
  • 对于刚开始接触第三方平台开发的人员来说,微信开发平台的文档相对比较复杂,现阶段网上博客文章较为杂乱零散,无法提供有效的指导。 通过本达人课的学习,读者将熟悉第三方平台中的授权流程、Token管理、相关功能的...
  • 随着腾讯微信公众平台号的开放,围绕着微信的各种开发和营销如火如荼。很多商家也开始在微信上做文章,想充分利用微信平台4亿多的粉丝群体来进行各种营销和推广。这直接带来了很多公司开始做微信第3方营销平台,而...
  • 微信公众平台开发 微信公众平台开发者 微信公众平台开发模式 签名校验 消息响应作者:方倍工作室原文:http://www.cnblogs.com/txw1958/archive/2013/05/08/weixin-if29-valid-responseMsg.html    一、问题来源...
  • 1、 微信公众平台 ...商户可以在公众平台提交基本资料、业务资料、财务资料申请开通微信支付功能...微信开放平台是商户APP接入微信支付开放接口的申请入口,通过此平台可申请微信APP支付。 平台入口:http://open.weixi
1 2 3 4 5 ... 20
收藏数 19,583
精华内容 7,833