【转】微信公众平台开发之模板消息(java) -凯发k8网页登录

——欢迎访问rogerfan的博客,常来《java——咖啡馆》坐坐,喝杯浓香的咖啡,彼此探讨一下java技术,交流工作经验,分享java带来的快乐!本网站部分转载文章,如果有凯发k8网页登录的版权问题请与我联系。

      由于柳峰老师的新书还没有出来,网上也没有过多介绍基于java语言的开发微信公众平台模板消息的例子,因此有了本文。由于个人表达能力和编程能力有限,请多多包涵。本文仅介绍拥有模板消息权限的微信公众账号开发。

      本文分为以下两部分:

      1.开发模板消息sdk

      2.构造模板消息并发送

      首先看一下模板消息接口文档:

      模版消息

        为了保证用户不受到骚扰,在开发者出现需要主动提醒、通知用户时,才允许开发者在公众平台网站中模板消息库中选择模板,选择后获得模板id,再根据模板id向用户主动推送提醒、通知消息。


        模板消息调用时主要需要模板id和模板中各参数的赋值内容。请注意:

        1.模板中参数内容必须以".data"结尾,否则视为保留字;

        2.模板保留符号"{{ }}"

        具体调用方法

        第一步:获取模板id

        通过在模板消息功能的模板库中使用需要的模板,可以获得模板id。

        第二步:请求接口

        请注意,url置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。

        post请求

        请求包为一个json:

        {
        "touser":"openid",
        "template_id":"ngqipbwh8bufcssecmogfxcv14j0tqlepbo27izeyty",
        "url":"http://weixin.qq.com/download",
        "topcolor":"#ff0000",
        "data":{
        "user": {
        "value":"黄先生",
        "color":"#173177"
        },
        "date":{
        "value":"06月07日 19时24分",
        "color":"#173177"
        },
        "cardnumber":{
        "value":"0426",
        "color":"#173177"
        },
        "type":{
        "value":"消费",
        "color":"#173177"
        },
        "money":{
        "value":"人民币260.00元",
        "color":"#173177"
        },
        "deadtime":{
        "value":"06月07日19时24分",
        "color":"#173177"
        },
        "left":{
        "value":"6504.09",
        "color":"#173177"
        }
        }
        }

        发送效果图:

         


        事件推送

        在模版消息发送任务完成后,微信服务器会将是否送达成功作为通知,发送到开发者中心中填写的服务器配置地址中。

        1、送达成功时,推送的xml如下:

        <xml>
        <tousername>gh_7f083739789a]]>tousername>
        <fromusername>oia2tjuegtnoex76qejqnrcurxg8]]&g;
        1395658920
        ]]>msgtype>
        <event>templatesendjobfinish]]>event>
        <msgid>200163836msgid>
        <status>success]]>status>
        xml>

        2、送达由于用户拒收(用户设置拒绝接收公众号消息)而失败时,推送的xml如下:

        <xml>
        <tousername>gh_7f083739789a]]>tousername>
        <fromusername>oia2tjuegtnoex76qejqnrcurxg8]]>fromusername>
        <createtime>1395658984createtime>
        <msgtype>event]]>msgtype>
        <event>templatesendjobfinish]]>event>
        <msgid>200163840msgid>
        <status>failed:user block]]>status>
        xml>

        3、送达由于其他原因失败时,推送的xml如下:

        <xml>
        <tousername>gh_7f083739789a]]>tousername>
        <fromusername>oia2tjuegtnoex76qejqnrcurxg8]]>fromusername>
        <createtime>1395658984createtime>
        <msgtype>event]]>msgtype>
        <event>templatesendjobfinish]]>event>
        <msgid>200163840msgid>
        <status>failed: system failed]]>status>
        xml>

        返回码说明

        在调用模板消息接口后,会返回json数据包。正常时的返回json数据包示例:

        {
        "errcode":0,
        "errmsg":"ok",
        "msgid":200228332
        }

        错误时的返回json数据,形式类似,错误码请见本页下方返回码说明。


        返回码 说明
        -1 系统繁忙
        0 请求成功
        40001 验证失败
        40002 不合法的凭证类型
        40003 不合法的openid
        40004 不合法的媒体文件类型
        40005 不合法的文件类型
        40006 不合法的文件大小
        40007 不合法的媒体文件id
        40008 不合法的消息类型
        40009 不合法的图片文件大小
        40010 不合法的语音文件大小
        40011 不合法的视频文件大小
        40012 不合法的缩略图文件大小
        40013 不合法的appid
        41001 缺少access_token参数
        41002 缺少appid参数
        41003 缺少refresh_token参数
        41004 缺少secret参数
        41005 缺少多媒体文件数据
        41006 access_token超时
        42001 需要get请求
        43002 需要post请求
        43003 需要https请求
        44001 多媒体文件为空
        44002 post的数据包为空
        44003 图文消息内容为空
        45001 多媒体文件大小超过限制
        45002 消息内容超过限制
        45003 标题字段超过限制
        45004 描述字段超过限制
        45005 链接字段超过限制
        45006 图片链接字段超过限制
        45007 语音播放时间超过限制
        45008 图文消息超过限制
        45009 接口调用超过限制
        46001 不存在媒体数据
        47001 解析json/xml内容错误

        模板消息的定义如下:

        模板消息也是使用access_token作为授权来发送。但是请大家注意:这里的access_token与网页授权的access_token完全不是一回事。可不要拿网页授权的access_token当作参数传递。

        获取模板消息access_token:

        string appid = "xxxxxxxxxxxxx"; //公众账号的唯一标识

        string appsecret="xxxxxxxxxxx"; //公众账号的密钥

        token token = commonutil.gettoken(appid, appsecret);

        string access_token = token.getaccesstoken();

        #commonutil工具类具体代码:

         

        import java.io.bufferedreader;
        import java.io.inputstream;
        import java.io.inputstreamreader;
        import java.io.outputstream;
        import java.io.unsupportedencodingexception;
        import java.net.connectexception;
        import java.net.url;

        import javax.net.ssl.httpsurlconnection;
        import javax.net.ssl.sslcontext;
        import javax.net.ssl.sslsocketfactory;
        import javax.net.ssl.trustmanager;

        import net.sf.json.jsonexception;
        import net.sf.json.jsonobject;

        import org.slf4j.logger;
        import org.slf4j.loggerfactory;

        /**
         * 通用工具类
         * 
         * 
        @author liufeng
         
        */

        public class commonutil {
            
            
        private static logger log = loggerfactory.getlogger(commonutil.class);
            
            
        // 凭证获取(get)
            public final static string token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=appid&secret=appsecret";
            
            
        /**
             * 发送 https 请求
             * 
             * 
        @param requesturl 请求地址
             * 
        @param requestmethod 请求方式(get、post)
             * 
        @param outputstr 提交的数据
             * 
        @return jsonobject(通过 jsonobject.get(key) 的方式获取 json 对象的属性值)
             
        */

            
        public static jsonobject httpsrequest(string requesturl, string requestmethod, string outputstr) {
                
                jsonobject jsonobject 
        = null;
                
                
        try {
                    
        // 创建 sslcontext 对象,并使用我们指定的信任管理器初始化
                    trustmanager[] tm = new myx509trustmanager() };
                    sslcontext sslcontext 
        = sslcontext.getinstance("ssl""sunjsse");
                    sslcontext.init(
        null, tm, new java.security.securerandom());
                    
        // 从上述 sslcontext 对象中得到 sslsocketfactory 对象
                    sslsocketfactory ssf = sslcontext.getsocketfactory();
                    
                    url url 
        = new ;
                    httpsurlconnection conn 
        = (httpsurlconnection) url.openconnection();
                    conn.setsslsocketfactory(ssf);
                    
                    conn.setdooutput(
        true);
                    conn.setdoinput(
        true);
                    conn.setusecaches(
        false);
                    
                    
        // 设置请求方式(get/post)
                    conn.setrequestmethod(requestmethod);
                    
                    
        // 当 outputstr 不为 null 时,向输出流写数据
                    if (null != outputstr) {
                        outputstream outputstream 
        = conn.getoutputstream();
                        
                        
        // 注意编码格式
                        outputstream.write(outputstr.getbytes("utf-8"));
                        outputstream.close();
                    }

                    
                    
        // 从输入流读取返回内容
                    inputstream inputstream = conn.getinputstream();
                    inputstreamreader inputstreamreader 
        = new inputstreamreader(inputstream, "utf-8");
                    bufferedreader bufferedreader 
        = new bufferedreader(inputstreamreader);
                    string str 
        = null;
                    stringbuffer buffer 
        = new stringbuffer();
                    
                    
        while ((str = bufferedreader.readline()) != null{
                        buffer.append(str);
                    }

                    
                    
        // 释放资源
                    bufferedreader.close();
                    inputstreamreader.close();
                    inputstream.close();
                    inputstream 
        = null;
                    conn.disconnect();
                    jsonobject 
        = jsonobject.fromobject(buffer.tostring());
                }
         catch (connectexception ce) {
                    log.error(
        " 连接超时:{}", ce);
                }
         catch (exception e) {
                    log.error(
        "https 请求异常:{}", e);
                }

                
                
        return jsonobject;
            }


            
        /**
             * 获取接口访问凭证
             * 
             * 
        @param appid 凭证
             * 
        @param appsecret 密钥
             * 
        @return
             
        */

            
        public static token gettoken(string appid, string appsecret) {
                token token 
        = null;
                string requesturl 
        = token_url.replace("appid", appid).replace("appsecret", appsecret);
                
        // 发起get请求获取凭证
                jsonobject jsonobject = httpsrequest(requesturl, "get"null);

                
        if (null != jsonobject) {
                    
        try {
                        token 
        = new token();
                        token.setaccesstoken(jsonobject.getstring(
        "access_token"));
                        token.setexpiresin(jsonobject.getint(
        "expires_in"));
                    }
         catch (jsonexception e) {
                        token 
        = null;
                        
        // 获取token失败
                        log.error("获取token失败 errcode:{} errmsg:{}", jsonobject.getint("errcode"), jsonobject.getstring("errmsg"));
                    }

                }

                
        return token;
            }

            
            
        /**
             * url编码(utf-8)
             * 
             * 
        @param source
             * 
        @return
             
        */

            
        public static string urlencodeutf8(string source) {
                string result 
        = source;
                
        try {
                    result 
        = java.net.urlencoder.encode(source, "utf-8");
                }
         catch (unsupportedencodingexception e) {
                    e.printstacktrace();
                }

                
        return result;
            }

            
            
        /**
             * 根据内容类型判断文件扩展名
             * 
             * 
        @param contenttype 内容类型
             * 
        @return
             
        */

            
        public static string getfileext(string contenttype) {
                string fileext 
        = "";
                
        if ("image/jpeg".equals(contenttype))
                    fileext 
        = ".jpg";
                
        else if ("audio/mpeg".equals(contenttype))
                    fileext 
        = ".mp3";
                
        else if ("audio/amr".equals(contenttype))
                    fileext 
        = ".amr";
                
        else if ("video/mp4".equals(contenttype))
                    fileext 
        = ".mp4";
                
        else if ("video/mpeg4".equals(contenttype))
                    fileext 
        = ".mp4";
                
        return fileext;
            }

            
        }


        #token实体类具体代码:


        /**
         * 凭证实体类
         * 
         * 
        @author liufeng
         
        */

        public class token {

            
        // 接口访问凭证
            private string accesstoken;
            
        // 凭证有效期,单位:秒
            private int expiresin;
            
            
        public string getaccesstoken() {
                
        return accesstoken;
            }

            
        public void setaccesstoken(string accesstoken) {
                
        this.accesstoken = accesstoken;
            }

            
        public int getexpiresin() {
                
        return expiresin;
            }

            
        public void setexpiresin(int expiresin) {
                
        this.expiresin = expiresin;
            }

            
        }

         


        至此,我们获得了模板消息的access_token。将它作为参数传递到模板消息接口文档中post请求的access_token。

        //得到构造好的模板消息请求地址

        我们以一个餐饮行业的收到新订单通知的模板为例,模板详情如下:

        模版消息


          • 模板id

            yto2xaty0vtrbge4jwwnl-zdc992fddguhmubomnka0
            开发者调用模板消息接口时需提供模板id

          • 标题收到新订单通知
          • 行业餐饮 - 餐饮
          • 详细内容
            {{first.data}}
            日期:{{day.data}} 
            订单编号:{{orderid.data}}
            订单类型:{{ordertype.data}}
            联系人:{{customername.data}} 
            联系电话:{{customerphone.data}} 
            {{remark.data}}
            在发送时,需要将内容中的参数({{.data}}内为参数)赋值替换为需要的信息
          • 内容示例
            收到一个新的订单,确认接受请回复0,拒绝请回复1。
            日期:2014-10-10 
            订单编号:1002
            订单类型:订位 
            联系人:陈丑丑 
            联系电话:13222222222
            订单金额:100.00元
            付款状态:已微信支付  
            请及时处理您的订单。 
            
          • 按照上述条件,我们的消息体构造如下:
          • {"data":{"customername":{"color":"#173177","value":"陈丑丑"},"customerphone":{"color":"#173177","value":"13222222222"},"day":{"color":"#173177","value":"15时06分"},"first":{"color":"#173177","value":"收到一个新的订单"},"orderid":{"color":"#173177","value":"1002"},"ordertype":{"color":"#173177","value":"订位"},"remark":{"color":"#173177","value":"请及时处理您的订单"}},"template_id":"yto2xaty0vtrbge4jwwnl-zdc992fddguhmubomnka0","topcolor":"#173177","touser":"orsrot9qbgo6dc-f3il_mf52epli","url":"http://weixin.qq.com/download"}
          • 该消息体为一个json。具体封装如下:
            1/**
            2 * 餐饮行业收到新订单通知模板消息实体类
            3 * @author xjw
            4 *
            5 */

            6public class neworderstemplate {
            7    private string touser; //用户openid
            8    
            9    private string template_id; //模板消息id
           10    
           11    private string url; //url置空,则在发送后,点击模板消息会进入一个空白页面(ios),或无法点击(android)。
           12    
           13    private string topcolor; //标题颜色
           14    
           15    private data data; //详细内容
           16
           17    public string gettouser() {
           18        return touser;
           19    }

           20
           21    public void settouser(string touser) {
           22        this.touser = touser;
           23    }

           24
           25    public string gettemplate_id() {
           26        return template_id;
           27    }

           28
           29    public void settemplate_id(string templateid) {
           30        template_id = templateid;
           31    }

           32
           33    public string get {
           34        return url;
           35    }

           36
           37    public void set {
           38        this.url = url;
           39    }

           40
           41    public string gettopcolor() {
           42        return topcolor;
           43    }

           44
           45    public void settopcolor(string topcolor) {
           46        this.topcolor = topcolor;
           47    }

           48
           49    public data getdata() {
           50        return data;
           51    }

           52
           53    public void setdata(data data) {
           54        this.data = data;
           55    }

           56}

           57
           58/**
           59 * "餐饮行业收到新订单通知"模板消息详细内容实体类
           60 * @author xjw
           61 *
           62 */

           63public class data {
           64    private data_first first;
           65    
           66    private data_day day; //日期
           67    
           68    private data_orderid orderid; //订单编号
           69    
           70    private data_ordertype ordertype; //订单类型
           71    
           72    private data_customername customername; //联系人
           73    
           74    private data_customerphone customerphone; //联系电话
           75    
           76    private data_remark remark;
           77
           78    public data_first getfirst() {
           79        return first;
           80    }

           81
           82    public void setfirst(data_first first) {
           83        this.first = first;
           84    }

           85
           86    
           87
           88    public data_day getday() {
           89        return day;
           90    }

           91
           92    public void setday(data_day day) {
           93        day = day;
           94    }

           95
           96    public data_orderid getorderid() {
           97        return orderid;
           98    }

           99
          100    public void setorderid(data_orderid orderid) {
          101        this.orderid = orderid;
          102    }

          103
          104    public data_ordertype getordertype() {
          105        return ordertype;
          106    }

          107
          108    public void setordertype(data_ordertype ordertype) {
          109        this.ordertype = ordertype;
          110    }

          111
          112    public data_customername getcustomername() {
          113        return customername;
          114    }

          115
          116    public void setcustomername(data_customername customername) {
          117        this.customername = customername;
          118    }

          119
          120    public data_customerphone getcustomerphone() {
          121        return customerphone;
          122    }

          123
          124    public void setcustomerphone(data_customerphone customerphone) {
          125        this.customerphone = customerphone;
          126    }

          127
          128    public data_remark getremark() {
          129        return remark;
          130    }

          131
          132    public void setremark(data_remark remark) {
          133        this.remark = remark;
          134    }

          135}

          136/**
          137 * first
          138 * @author xjw
          139 *
          140 */

          141public class data_first {
          142    private string value;
          143    
          144    private string color;
          145
          146    public string getvalue() {
          147        return value;
          148    }

          149
          150    public void setvalue(string value) {
          151        this.value = value;
          152    }

          153
          154    public string getcolor() {
          155        return color;
          156    }

          157
          158    public void setcolor(string color) {
          159        this.color = color;
          160    }

          161    
          162    
          163}

          164
          165/**
          166 * 日期
          167 * @author xjw
          168 *
          169 */

          170public class data_day {
          171    
          172    private string value;
          173    
          174    private string color;
          175
          176    public string getvalue() {
          177        return value;
          178    }

          179
          180    public void setvalue(string value) {
          181        this.value = value;
          182    }

          183
          184    public string getcolor() {
          185        return color;
          186    }

          187
          188    public void setcolor(string color) {
          189        this.color = color;
          190    }

          191    
          192    
          193}

          194
          195
          196
          197
          198/**
          199 * 订单标号
          200 * @author xjw
          201 *
          202 */

          203public class data_orderid {
          204
          205    private string value;
          206    
          207    private string color;
          208
          209    public string getvalue() {
          210        return value;
          211    }

          212
          213    public void setvalue(string value) {
          214        this.value = value;
          215    }

          216
          217    public string getcolor() {
          218        return color;
          219    }

          220
          221    public void setcolor(string color) {
          222        this.color = color;
          223    }

          224  
          225}

          226
          227/**
          228 * 订单类型
          229 * @author xjw
          230 *
          231 */

          232public class data_ordertype {
          233
          234    private string value;
          235    
          236    private string color;
          237
          238    public string getvalue() {
          239        return value;
          240    }

          241
          242    public void setvalue(string value) {
          243        this.value = value;
          244    }

          245
          246    public string getcolor() {
          247        return color;
          248    }

          249
          250    public void setcolor(string color) {
          251        this.color = color;
          252    }

          253    
          254    
          255}

          256
          257/**
          258 * 联系人
          259 * @author xjw
          260 *
          261 */

          262public class data_customername {
          263
          264    private string value;
          265    
          266    private string color;
          267
          268
          269    public string getvalue() {
          270        return value;
          271    }

          272
          273    public void setvalue(string value) {
          274        this.value = value;
          275    }

          276
          277    public string getcolor() {
          278        return color;
          279    }

          280
          281    public void setcolor(string color) {
          282        this.color = color;
          283    }

          284    
          285    
          286}

          287
          288/**
          289 * 联系电话
          290 * @author xjw
          291 *
          292 */

          293public class data_customerphone {
          294
          295    private string value;
          296    
          297    private string color;
          298
          299
          300    public string getvalue() {
          301        return value;
          302    }

          303
          304    public void setvalue(string value) {
          305        this.value = value;
          306    }

          307
          308    public string getcolor() {
          309        return color;
          310    }

          311
          312    public void setcolor(string color) {
          313        this.color = color;
          314    }

          315    
          316    
          317}

          318
          319/**
          320 * remark
          321 * @author xjw
          322 *
          323 */

          324public class data_remark {
          325    
          326    private string value;
          327    
          328    private string color;
          329
          330
          331    public string getvalue() {
          332        return value;
          333    }

          334
          335    public void setvalue(string value) {
          336        this.value = value;
          337    }

          338
          339    public string getcolor() {
          340        return color;
          341    }

          342
          343    public void setcolor(string color) {
          344        this.color = color;
          345    }

          346    
          347    
          348}

          349
          350/**
          351     * 发送模板消息
          352     * appid 公众账号的唯一标识
          353     * appsecret 公众账号的密钥
          354     * openid 用户标识
          355     */

          356    public void send_template_message(string appid, string appsecret, string openid) {
          357
          358
          359        token token = commonutil.gettoken(appid, appsecret);
          360        string access_token = token.getaccesstoken();
          361        string url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="access_token;
          362
          363
          364        neworderstemplate temp = new neworderstemplate();
          365        data data = new data();
          366        data_first first = new data_first();
          367        data_day day = new data_day();
          368        data_orderid orderid = new data_orderid();
          369        data_ordertype ordertype = new data_ordertype();
          370        data_customername customername = new data_customername();
          371        data_customerphone customerphone = new data_customerphone();
          372        data_remark remark = new data_remark();
          373
          374
          375        first.setvalue("收到一个新的订单");
          376        first.setcolor("#173177");
          377        day.setvalue("14时56分");
          378        day.setcolor("#173177");
          379        orderid.setvalue("1002");
          380        orderid.setcolor("#173177");
          381        ordertype.setvalue("订位");
          382        ordertype.setcolor("#173177");
          383        customername.setvalue("陈丑丑");
          384        customername.setcolor("#173177");
          385        customerphone.setvalue("13222222222");
          386        customerphone.setcolor("#173177");
          387        remark.setvalue("请及时处理您的订单");
          388        remark.setcolor("#173177");
          389
          390
          391        data.setfirst(first);
          392        data.setday(day);
          393        data.setorderid(orderid);
          394        data.setordertype(ordertype);
          395        data.setcustomername(customername);
          396        data.setcustomerphone(customerphone);
          397        data.setremark(remark);
          398        temp.settouser(openid);
          399        temp.settemplate_id("yto2xaty0vtrbge4jwwnl-zdc992fddguhmubomnka0");
          400        temp.set;
          401        temp.settopcolor("#173177");
          402        temp.setdata(data);
          403        
          404        string jsonstring = jsonobject.fromobject(temp).tostring().replace("day""day");
          405        jsonobject jsonobject = weixinutil.httprequest(url, "post", jsonstring);
          406        system.out.println(jsonobject);
          407        int result = 0;
          408        if (null != jsonobject) {  
          409             if (0 != jsonobject.getint("errcode")) {  
          410                 result = jsonobject.getint("errcode");  
          411                  log.error("错误 errcode:{} errmsg:{}", jsonobject.getint("errcode"), jsonobject.getstring("errmsg"));  
          412             }
            
          413         }

          414        log.info("模板消息发送结果:"result);
          415    }

          416
          417


          weixinutil工具类在柳峰老师的博客里有源码。。。。。

          实现效果如下:

          如果小伙伴们觉得有什么问题可以提出,大家共同学习。

          posted on 2016-09-23 17:02 rogerfan 阅读(771) 评论(0)  编辑  收藏 所属分类: 【开源技术】
          网站地图