2018-06-21 09:23:36 huchangjiang0 阅读数 6502
  • 微信公众号开发8-营销开发-微信开发php

    微信公众平台开发之营销开发是子恒老师《微信公众平台开发》视频教程的第8部。详细讲解了用php开发微信,对微信公众平台中的营销功能开发。内容包含获取微信短网址,生成推广二维码,生成推广海报等等。欢迎反馈,微信/QQ:68183131

    11411 人正在学习 去看看 秦子恒

微信公众号开发绝大部分与移动端开发相同。不过相比移动端,微信浏览器的内核就一种,对兼容性的要求更低一些。

安卓微信浏览器的内核属于魔改版的webkit内核。

ios微信浏览器的内核兼容性处理更接近safari浏览器。

绝大部分兼容性参照谷歌浏览器就行

微信开发中与移动端不同的就是可以借助微信调用很多手机的硬件,通过微信封装的js调用一些微信的接口。

微信分享

微信允许用户将页面分享给其他用户或者朋友圈,或者qq。不过最常用的用户分享功能是分享给朋友与朋友圈。因为大多微信开发都涉及到微信登陆的功能,这导致页面在其他浏览器打不开。

微信分享主要通过微信的jssdk中的分享接口来实现的。微信的jssdk的权限注入我在之前的文章内已经有所讲解,这里就不多说了。

微信在引入js文件并且调用wx.config接口注入权限后,然后通过wx.ready接口去读取接口。主要是因为注入权限为异步的,而wx.ready接口就像wx.config接口的回调函数。

wx.onMenuShareAppMessage({
    title: '', // 分享标题
    desc: '', // 分享描述
    link: '', // 分享链接,该链接域名必须与当前企业的可信域名一致
    imgUrl: '', // 分享图标
    type: '', // 分享类型,music、video或link,不填默认为link
    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
    success: function () {
        // 用户确认分享后执行的回调函数
    },
    cancel: function () {
        // 用户取消分享后执行的回调函数
    }

})

微信分享给好友的接口为onMenuShareAppMessage。值得一提的是这个定义的是微信点击右上角分享给朋友的功能,微信不允许自定义分享的按钮。这里设置过是单击右上角分享的内容

title是分享的标题

desc描述

link分享打开的链接,在分享给好友后打开会在链接里加一个from参数

在success里面是用户分享成功的回调函数,可以在里面添加一些业务逻辑,比如说分享加积分功能。

cancel是用户取消了分享的回调

wx.onMenuShareTimeline({
    title: '', // 分享标题
    link: '', // 分享链接
    imgUrl: '', // 分享图标
    success: function () {
        // 用户确认分享后执行的回调函数
    },
    cancel: function () {
        // 用户取消分享后执行的回调函数
    }
});
分享到朋友圈的接口跟转发的接口差不多,就是不能分享音频与视频。
2018-02-03 09:43:54 yji534123343 阅读数 913
  • 微信公众号开发8-营销开发-微信开发php

    微信公众平台开发之营销开发是子恒老师《微信公众平台开发》视频教程的第8部。详细讲解了用php开发微信,对微信公众平台中的营销功能开发。内容包含获取微信短网址,生成推广二维码,生成推广海报等等。欢迎反馈,微信/QQ:68183131

    11411 人正在学习 去看看 秦子恒
一、微信开发的整体介绍
开放平台:https://open.weixin.qq.com/
公众平台:https://mp.weixin.qq.com/
1、微信开发的种类
①移动应用开发
支持微信的分享、收藏、支付三大功能,原生开发的人员去使用的开发类别
②网站应用开发
网站支持使用微信账号进行注册和登录,从而来实现:提高用户的留存率,方便不同账号的统一(结合unionId)
③公众账号开发


④公众账号第三方平台
优势在于免繁琐设置,方便小白用户去使用。


2、公众账号开发
①服务号
主要偏向于给用户提供查询服务(招商银行、麦当劳。。)
显示在好友列表,每个月只能群发4条消息


②订阅号
主要偏向于给用户提供资讯(朝闻天下、Web前端。。)
显示在订阅号文件夹内,每天都可以群发1条消息


③小程序
2017年1月9号 (2007年1月9号 推出iphone)
基于微信的平台,ui提供了很多组件,js提供了很多接口


(微信官方的小程序:小程序示例,包含了微信官方封装好的组件、以及封装好的接口)


目标:万物互联 (IOT),  二维码
开放范围:(不包含个人)
http://www.wxapp-union.com/forum.php?mod=viewthread&tid=495


https://mp.weixin.qq.com/debug/wxadoc/dev/index.html


数据存储和服务器:
两种解决方案 ①腾讯云(不到100) ②godaddy


④企业号
主要是建立起 企业与人的关系,提供信息、和企业相关的定制功能


温馨提示:
1)如果想简单的发送消息,达到宣传效果,建议可选择订阅号;
2)如果想进行商品销售,进行商品售卖,建议可申请服务号;
3)如果想用来管理内部企业员工、团队,对内使用,可申请企业号。
4)订阅号可通过微信认证资质审核通过后有一次升级为服务号的入口,升级成功后类型不可再变。
5)服务号不可变更成订阅号。


3、九大类高级接口


语音识别接口
客服接口
OAuth2.0 网页授权接口
生成带参数的二维码接口
获取用户地理位置接口
获取用户基本信息接口
获取关注者列表接口
用户分组接口
上传下载多媒体文件接口


+ 微信支付
(十大类接口的使用,必须是认证过的服务号和订阅号才能使用)




4、正式环境的搭建
(公众账号-》订阅号)


购买自己的域名(万网、dnsPod、godaddy)
购买申请主机空间(新浪云、阿里云、腾讯云、大米云、godaddy、aws)
注册订阅号
登录到订阅号管理接口、服务器的配置、调用10大类接口


5、测试环境的搭建
(公众账号-》订阅号)


主机空间(新浪云)
注册订阅号
登录到订阅号管理接口、服务器的配置、调用10大类接口


6、注册订阅号
①填写邮箱、密码
②到邮箱中激活账号
③选择类型
④登记信息(个人、组织、媒体、企业。。)
⑤填写公众号的信息(名称、介绍、头像)






二、个人订阅号(jssdk)


1、实现功能:统计页面被访问的次数


分析:
①存储需要持久保存的数据
数据库、文件系统、内存中:fileSystem
②读写过程
读:file_get_contents($fileUrl);
写:file_put_contents($fileUrl,$content);


需要apache启动


2、新浪云storage


通过bucket管理我们的文件,如何访问?
saestor:// testbucket/count.txt




3、jsSDK的使用步骤
①绑定域名
②引入js文件
③注入接口(将使用接口的名称,写在config方法中jsAPIList这个数组中)
④在ready中调用接口
⑤在error中处理失败的异常情况






sample.zip有4个文件,
前两个文件都是用来存储数据的,jssdk.php进行网络请求以及数据的读写操作,sample.php文件主要完成接口的注入和调用


jssdk.php封装了2个方法get_php_file、set_php_file,如果部署在服务端,写文件会出现权限拒绝的问题。
①将存储文件 放到新浪云的bucket中
②修改读写文件的路径为 saestor://bucketName/**.php




require subscribe 需要订阅测试账号。




三、版本控制工具(git)


1、版本控制
记录一个或者多个文件内容变化,以便于未来查询指定的版本信息。


svn 集中式/git  分布式
①防止代码的丢失
②团队协作
③版本还原
④更好的管理代码


2、git介绍
用于代码的版本控制,使用方式:命令行/图形化


git(分布式版本控制工具)与github(托管开源项目的网站,托管项目的方式采用的是git)


3、自己使用git将项目上传到github


①申请github的账号 
https://github.com/
注册账号,在选择计划的时候选择continue,在编辑经验时选择skip跳过。
②去邮件激活账号
③start project 只需要指定repository的名称,点击create去创建。


④安装git
一路next,最后点击install安装 取消所有的勾选就可以了。
⑤启动git
到所有程序中,找到git,找到gitbash,点击启动


⑥基础命令
ls (list) 查看当前目录下的文件
clear 清除当前的屏幕信息
pwd (print the work directory)显示当前目录
mkdir web1609 在当前的路径中创建一个叫做web1609的目录
cd web1609 (change directory)
touch a.txt 创建一个叫做a.txt的一个文件


通过电脑中的文件系统找到文件,写上了hello git.


git的用法


git init 初始化仓库
git status 查看仓库的状态
git add a.txt 将a.txt添加到代码仓库
git commit -m '第一次提交'     添加到缓存区


配置上传到github上的用户信息:
git config --global user.name "web1609best"
git config --global user.email "web1609@vip.163.com"


设置完账号之后,重新提交到缓存区:
git commit -m '第一次提交'     添加到缓存区


将本地的代码设置它推送到github上的地址:
git remote add origin https://github.com/web1609best/web1609.git


将当前目录的git仓库推送到github对应的origin地址的master分支
git push origin master

















2016-08-19 11:54:23 u013203396 阅读数 370
  • 微信公众号开发8-营销开发-微信开发php

    微信公众平台开发之营销开发是子恒老师《微信公众平台开发》视频教程的第8部。详细讲解了用php开发微信,对微信公众平台中的营销功能开发。内容包含获取微信短网址,生成推广二维码,生成推广海报等等。欢迎反馈,微信/QQ:68183131

    11411 人正在学习 去看看 秦子恒

    微信,是近些年来非常流行的一种网络交流手段,它是腾讯公司继QQ之后又一力推的软件,现在几乎人人都在使用微信,并且使用微信也更加的安全稳定,可以提供更多的功能,而我们今天索要说的就是有关于微信开发的功能的相关介绍还有知识,那么我们就一起来看看微信开发功能都有哪些吧。

常见的微信开发功能都有什么

    1)二维码功能

    可以为任何一段文字和网址生成二维码,当然由于微信的空前火爆,所以很多人把二维码就和微信连接起来了。其实除了微信,你的网站也是可以拥有二维码的。

    2)微信公众帐号的拥有

    公众帐号分为服务号和订阅号两种,服务号需要用到公司的信息去注册,所以个人是注册不了的,而订阅号是每个人都可以用自己的身份证去注册的,所以我们一个企业可以拥有多个订阅号

    3)自定义菜单

    最早一批的订阅号由于拿到了微信的内测资格,所以目前是有一批订阅号拥有自定义菜单功能的,而现在想要拥有此功能,只能申请服务号。

    4)微网站

    微网站原则上来讲是在微信里面打开的,和微信建立连接的网站,程序员通过调用微信的API来实现和微信的连接。大多数经过微信开发的服务号都拥有自己的微网站,微网站的具体形式多种多样。

    而订阅号由于其不能自定义菜单,所以一般是通过发图片消息来引导进入微网站。 微网站可以为企业展示动态信息,服务信息,产品信息,互动论坛等等等等,几乎互联网上一切形式的网站都可以在微信上体现。

    5)微商城

    微商城无非就是把微网站做成一个电子商城,让用户可以在网站里下单,购买。但是这里面涉及到一个支付问题,虽然微信有微支付功能,但是目前为止还没有面向大众开放,我们一般是采用支付宝和网银在线等在线支付接口来解决支付问题。

    6)微论坛

    论坛只不过是想让用户在网站里进行互动,其和微网站的区别主要在于形式上的不同。

    7)信息收集

    当第三方程序和微信的接口对接之后,第三方程序就可以收集到微信用户所发送的一切消息,根据这样的功能,我们可以分析出对我们有价值的信息以便进行用户的管理

    8)自动回复

    未经过开发的帐号可以设置200条自动回复消息,但是必须是全匹配,如:你好,您好,这两个单词需要全写上才会全匹配,而经过开发的帐号是无数量限制的,而且自动回复也可以根据用户发送的信息频率变的更智能。

    现在最为火爆的微信开发的功能当属扫描二维码了,大多数的商业活动都会采用扫描二维码的方式来进行的,那么除了二维码的开发活动,还有自动回复啊,微店啊,微信公众号啊,还有微商城等等一系列的开发功能,随着时间的增长,所开发出来的微信功能也越来越健全了。


2017-09-23 07:31:24 towtotow 阅读数 880
  • 微信公众号开发8-营销开发-微信开发php

    微信公众平台开发之营销开发是子恒老师《微信公众平台开发》视频教程的第8部。详细讲解了用php开发微信,对微信公众平台中的营销功能开发。内容包含获取微信短网址,生成推广二维码,生成推广海报等等。欢迎反馈,微信/QQ:68183131

    11411 人正在学习 去看看 秦子恒

虽然子恒老师已经出品了100多部微信公众号开发的视频教程,

但也不可能把微信所有的api开发接口讲完,

因为微信每过一段时间,

就会推出新的api接口,

你可以实现更多新功能,

还有可能微信把一些接口进行修改或者取消。


13kanwendang.jpg


作为一个优秀的微信开发人员,

你必须学会看微信的开发文档。


这一点对大部分刚接触公众号开发的人来说,

感觉到很难,

因为开发环境的原因,

或者文档说明不够详细,


子恒老师在这一节微信开发视频教程中告诉你怎么看公众号开发文档…

怎么看微信公众号开发文档视频教程在线观看

http://edu.csdn.net/course/detail/2586/40531

2018-05-29 00:12:27 qq_36501591 阅读数 97
  • 微信公众号开发8-营销开发-微信开发php

    微信公众平台开发之营销开发是子恒老师《微信公众平台开发》视频教程的第8部。详细讲解了用php开发微信,对微信公众平台中的营销功能开发。内容包含获取微信短网址,生成推广二维码,生成推广海报等等。欢迎反馈,微信/QQ:68183131

    11411 人正在学习 去看看 秦子恒

在上篇微信开发学习总结(二)——微信开发入门我们介绍了微信公众平台的基本原理,如何接入微信公众号,如何保持access_token的长期有效性以及进行了简单的文本消息测试,本篇再来具体细说一如何实现微信公众号的最基本功能:普通消息的接收和回复。

一、微信公众平台消息管理接口介绍

  要实现微信公众号的普通消息的接收和回复,我们需要先熟悉微信公众平台API中消息接口部分,点此进入,点击后将进入到【消息管理】部分,如下图所示:

  

  对于普通消息的接收和回复我们只需要关注上图中的"接收消息——接收普通消息"和"发送消息——被动回复消息"

1.1、消息接收

  先来说说接收消息, 当普通微信用户向公众账号发消息时,微信服务器会先接收到用户发送的消息,然后将用户消息按照指定的XML格式组装好数据,最后POST消息的XML数据包到开发者填写的URL上。

  接收到的普通消息的消息类型目前有以下几种:

  1 文本消息
  2 图片消息
  3 语音消息
  4 视频消息
  5 小视频消息
  6 地理位置消息
  7 链接消息

  每一种消息类型都有其指定的XML数据格式,这7种消息的xml格式请到官方文档查看,有具体的格式定义和属性说明。格式很简单,基本共有属性包括ToUserName、FromUserName、CreateTime、MsgType、MsgId,并且每种类型有自己特殊的属性。

  接收消息的过程其实就是获取post请求的这个xml,然后对这个xml进行分析的过程。post请求的入口还是之前提到的微信公众号接入的那个地址,整个公众号的所有请求都会走这个入口,只是接入时是get请求,其它情况下是post请求。

1.2、消息回复

  微信服务器在将用户的消息发给公众号的开发者服务器地址后,会等待开发者服务器回复响应消息。微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。

  假如服务器无法保证在五秒内处理并回复,必须做出下述回复,这样微信服务器才不会对此作任何处理,并且不会发起重试(这种情况下,可以使用客服消息接口进行异步回复),否则,将出现严重的错误提示。详见下面说明:

  1、(推荐方式)直接回复success
  2、直接回复空串(指字节长度为0的空字符串,而不是XML结构体中content字段的内容为空)

 一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示“该公众号暂时无法提供服务,请稍后再试”:

  1、开发者在5秒内未回复任何内容
  2、开发者回复了异常数据,比如JSON数据等

  另外,请注意,回复图片等多媒体消息时需要预先通过素材管理接口上传临时素材到微信服务器,可以使用素材管理中的临时素材,也可以使用永久素材。

  消息回复目前支持回复文本、图片、图文、语音、视频、音乐,每一种类型的消息都有特定的XML数据格式。这几种回复消息的xml数据格式请参考官方文档,有具体的格式定义和属性说明。格式很简单,基本共有属性包括ToUserName、FromUserName、CreateTime、MsgType并且每种类型有自己特殊的属性。

 二、微信公众号的普通消息的接收和回复

2.1、接收消息

  接收消息和被动回复消息这两个动作是不分家的,这本来就是一个交互场景,一般情况就是公众号通过分析接收到的消息,会给出对应的回复。

  之前说过了,接收消息的过程其实就是获取微信服务器通过post请求的发送给我们公众号服务器的xml数据,然后我们的公众号服务器再对这个xml进行解析处理的过程。为了方便解析XML数据,我们借助于dom4j,dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,是用来读写XML文件的。针对微信服务器发来的xml请求数据,我们写一个parseXml方法来处理,parseXml方法的代码如下:

复制代码
 1  /**
 2      * 解析微信发来的请求(XML)
 3      *
 4      * @param request 封装了请求信息的HttpServletRequest对象
 5      * @return map 解析结果
 6      * @throws Exception
 7      */
 8     public static Map<String, String> parseXml(HttpServletRequest request) throws Exception {
 9         // 将解析结果存储在HashMap中
10         Map<String, String> map = new HashMap<String, String>();
11         // 从request中取得输入流
12         InputStream inputStream = request.getInputStream();
13         // 读取输入流
14         SAXReader reader = new SAXReader();
15         Document document = reader.read(inputStream);
16         // 得到xml根元素
17         Element root = document.getRootElement();
18         // 得到根元素的所有子节点
19         List<Element> elementList = root.elements();
20 
21         // 遍历所有子节点
22         for (Element e : elementList) {
23             System.out.println(e.getName() + "|" + e.getText());
24             map.put(e.getName(), e.getText());
25         }
26 
27         // 释放资源
28         inputStream.close();
29         inputStream = null;
30         return map;
31     }
复制代码

  然后在处理微信请求的入口servlet的doPost方法中调用parseXml方法即可,调用代码如下:

复制代码
 1  /**
 2      * 处理微信服务器发来的消息
 3      */
 4     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
 5         // TODO 接收、处理、响应由微信服务器转发的用户发送给公众帐号的消息
 6         // 将请求、响应的编码均设置为UTF-8(防止中文乱码)
 7         request.setCharacterEncoding("UTF-8");
 8         response.setCharacterEncoding("UTF-8");
 9         System.out.println("请求进入");
10         String responseMessage;
11         try {
12             //解析微信发来的请求,将解析后的结果封装成Map返回
13             Map<String,String> map = MessageHandlerUtil.parseXml(request);
14             System.out.println("开始构造响应消息");
15             responseMessage = MessageHandlerUtil.buildResponseMessage(map);
16             System.out.println(responseMessage);
17             if(responseMessage.equals("")){
18                 responseMessage ="未正确响应";
19             }
20         } catch (Exception e) {
21             e.printStackTrace();
22             System.out.println("发生异常:"+ e.getMessage());
23             responseMessage ="未正确响应";
24         }
25         //发送响应消息
26         response.getWriter().println(responseMessage);
27     }
复制代码

  这样我们就完成了消息的接收,消息接收之后,我们就要根据消息类型进行响应了,写一个根据消息类型构造返回消息的方法,代码如下:

复制代码
 1 /**
 2      * 根据消息类型构造返回消息
 3      * @param map 封装了解析结果的Map
 4      * @return responseMessage(响应消息)
 5      */
 6     public static String buildResponseMessage(Map map) {
 7         //响应消息
 8         String responseMessage = "";
 9         //得到消息类型
10         String msgType = map.get("MsgType").toString();
11         System.out.println("MsgType:" + msgType);
12         //消息类型
13         MessageType messageEnumType = MessageType.valueOf(MessageType.class, msgType.toUpperCase());
14         switch (messageEnumType) {
15             case TEXT:
16                 //处理文本消息
17                 responseMessage = handleTextMessage(map);
18                 break;
19             case IMAGE:
20                 //处理图片消息
21                 responseMessage = handleImageMessage(map);
22                 break;
23             case VOICE:
24                 //处理语音消息
25                 responseMessage = handleVoiceMessage(map);
26                 break;
27             case VIDEO:
28                 //处理视频消息
29                 responseMessage = handleVideoMessage(map);
30                 break;
31             case SHORTVIDEO:
32                 //处理小视频消息
33                 responseMessage = handleSmallVideoMessage(map);
34                 break;
35             case LOCATION:
36                 //处理位置消息
37                 responseMessage = handleLocationMessage(map);
38                 break;
39             case LINK:
40                 //处理链接消息
41                 responseMessage = handleLinkMessage(map);
42                 break;
43             case EVENT:
44                 //处理事件消息,用户在关注与取消关注公众号时,微信会向我们的公众号服务器发送事件消息,开发者接收到事件消息后就可以给用户下发欢迎消息
45                 responseMessage = handleEventMessage(map);
46             default:
47                 break;
48         }
49         //返回响应消息
50         return responseMessage;
51     }
复制代码

  这样我们就完成了根据消息类型进行响应了,在处理微信请求的入口servlet的doPost方法中调用buildResponseMessage方法即可,doPost方法的完整代码在上面已经贴出来了.buildResponseMessage方法中使用到了一个MessageType类,这是一个消息类型枚举类,MessageType类的代码如下:

复制代码
 1 /**
 2  * 接收到的消息类型
 3  */
 4 public enum MessageType {
 5     TEXT,//文本消息
 6     IMAGE,//图片消息
 7     VOICE,//语音消息
 8     VIDEO,//视频消息
 9     SHORTVIDEO,//小视频消息
10     LOCATION,//地理位置消息
11     LINK,//链接消息
12     EVENT//事件消息
13 }
复制代码

2.2、回复消息

  下面我基于这样一个业务场景来演示构造回复的消息,接收到文本消息"文本",回复文本消息;接收到“图片”,回复图片消息;接收到“语音”,回复语音消息;接收到“视频”,回复视频消息;接收到“音乐”,回复音乐消息;接收到“图文”,回复图文消息。下面具体说明各种消息的构建,只贴出核心代码,一些辅助代码类请自行下载项目代码参考.

2.2.1、回复文本消息

  接收的文本消息的XML数据格式如下:

复制代码
1 <xml>
2  <ToUserName><![CDATA[toUser]]></ToUserName>
3  <FromUserName><![CDATA[fromUser]]></FromUserName> 
4  <CreateTime>1348831860</CreateTime>
5  <MsgType><![CDATA[text]]></MsgType>
6  <Content><![CDATA[this is a test]]></Content>
7  <MsgId>1234567890123456</MsgId>
8 </xml>
复制代码

  回复的文本消息的XML数据格式如下:

复制代码
1 <xml>
2 <ToUserName><![CDATA[发消息的人,即订阅者]]></ToUserName>
3 <FromUserName><![CDATA[微信公众号本身]]></FromUserName>
4 <CreateTime>消息创建时间(整形)</CreateTime>
5 <MsgType><![CDATA[text]]></MsgType>
6 <Content><![CDATA[消息内容]]></Content>
7 </xml>
复制代码

  其中接收消息格式中的ToUserName便是回复消息的FromUserName,接收消息格式中的FromUserName便是回复消息的ToUserName。CreateTime为消息发送的时间戳。MsgType为消息类型,文本为text。Content为消息内容。具体每一种类型消息的回复,就是构造此种类型的xml格式内容,格式大同小异,只是音乐、视频、语音、图文格式相对于文本消息构造的xml内容稍微复杂一点。

  写一个构建文本消息的方法,代码如下:

复制代码
 1  /**
 2      * 构造文本消息
 3      * @param map 封装了解析结果的Map
 4      * @param content 文本消息内容
 5      * @return 文本消息XML字符串
 6      */
 7     private static String buildTextMessage(Map<String, String> map, String content) {
 8         //发送方帐号
 9         String fromUserName = map.get("FromUserName");
10         // 开发者微信号
11         String toUserName = map.get("ToUserName");
12         /**
13          * 文本消息XML数据格式
14          * <xml>
15          <ToUserName><![CDATA[toUser]]></ToUserName>
16          <FromUserName><![CDATA[fromUser]]></FromUserName>
17          <CreateTime>1348831860</CreateTime>
18          <MsgType><![CDATA[text]]></MsgType>
19          <Content><![CDATA[this is a test]]></Content>
20          <MsgId>1234567890123456</MsgId>
21          </xml>
22          */
23         return String.format(
24                 "<xml>" +
25                         "<ToUserName><![CDATA[%s]]></ToUserName>" +
26                         "<FromUserName><![CDATA[%s]]></FromUserName>" +
27                         "<CreateTime>%s</CreateTime>" +
28                         "<MsgType><![CDATA[text]]></MsgType>" +
29                         "<Content><![CDATA[%s]]></Content>" +
30                         "</xml>",
31                 fromUserName, toUserName, getMessageCreateTime(), content);
32     }
复制代码

  2.2.2、回复图片消息

  写一个构建图片消息的方法,代码如下:

复制代码
 1  /**
 2      * 构造图片消息
 3      * @param map 封装了解析结果的Map
 4      * @param mediaId 通过素材管理接口上传多媒体文件得到的id
 5      * @return 图片消息XML字符串
 6      */
 7     private static String buildImageMessage(Map<String, String> map, String mediaId) {
 8         //发送方帐号
 9         String fromUserName = map.get("FromUserName");
10         // 开发者微信号
11         String toUserName = map.get("ToUserName");
12         /**
13          * 图片消息XML数据格式
14          *<xml>
15          <ToUserName><![CDATA[toUser]]></ToUserName>
16          <FromUserName><![CDATA[fromUser]]></FromUserName>
17          <CreateTime>12345678</CreateTime>
18          <MsgType><![CDATA[image]]></MsgType>
19          <Image>
20          <MediaId><![CDATA[media_id]]></MediaId>
21          </Image>
22          </xml>
23          */
24         return String.format(
25                 "<xml>" +
26                         "<ToUserName><![CDATA[%s]]></ToUserName>" +
27                         "<FromUserName><![CDATA[%s]]></FromUserName>" +
28                         "<CreateTime>%s</CreateTime>" +
29                         "<MsgType><![CDATA[image]]></MsgType>" +
30                         "<Image>" +
31                         "   <MediaId><![CDATA[%s]]></MediaId>" +
32                         "</Image>" +
33                         "</xml>",
34                 fromUserName, toUserName, getMessageCreateTime(), mediaId);
35     }
复制代码

  2.2.3、回复音乐消息

  写一个构建音乐消息的方法,代码如下:

复制代码
 1  /**
 2      * 构造音乐消息
 3      * @param map 封装了解析结果的Map
 4      * @param music 封装好的音乐消息内容
 5      * @return 音乐消息XML字符串
 6      */
 7     private static String buildMusicMessage(Map<String, String> map, Music music) {
 8         //发送方帐号
 9         String fromUserName = map.get("FromUserName");
10         // 开发者微信号
11         String toUserName = map.get("ToUserName");
12         /**
13          * 音乐消息XML数据格式
14          *<xml>
15          <ToUserName><![CDATA[toUser]]></ToUserName>
16          <FromUserName><![CDATA[fromUser]]></FromUserName>
17          <CreateTime>12345678</CreateTime>
18          <MsgType><![CDATA[music]]></MsgType>
19          <Music>
20          <Title><![CDATA[TITLE]]></Title>
21          <Description><![CDATA[DESCRIPTION]]></Description>
22          <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
23          <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
24          <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
25          </Music>
26          </xml>
27          */
28         return String.format(
29                 "<xml>" +
30                         "<ToUserName><![CDATA[%s]]></ToUserName>" +
31                         "<FromUserName><![CDATA[%s]]></FromUserName>" +
32                         "<CreateTime>%s</CreateTime>" +
33                         "<MsgType><![CDATA[music]]></MsgType>" +
34                         "<Music>" +
35                         "   <Title><![CDATA[%s]]></Title>" +
36                         "   <Description><![CDATA[%s]]></Description>" +
37                         "   <MusicUrl><![CDATA[%s]]></MusicUrl>" +
38                         "   <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>" +
39                         "</Music>" +
40                         "</xml>",
41                 fromUserName, toUserName, getMessageCreateTime(), music.title, music.description, music.musicUrl, music.hqMusicUrl);
42     }
复制代码

  2.2.4、回复视频消息

  写一个构建视频消息的方法,代码如下:

复制代码
 1  /**
 2      * 构造视频消息
 3      * @param map 封装了解析结果的Map
 4      * @param video 封装好的视频消息内容
 5      * @return 视频消息XML字符串
 6      */
 7     private static String buildVideoMessage(Map<String, String> map, Video video) {
 8         //发送方帐号
 9         String fromUserName = map.get("FromUserName");
10         // 开发者微信号
11         String toUserName = map.get("ToUserName");
12         /**
13          * 音乐消息XML数据格式
14          *<xml>
15          <ToUserName><![CDATA[toUser]]></ToUserName>
16          <FromUserName><![CDATA[fromUser]]></FromUserName>
17          <CreateTime>12345678</CreateTime>
18          <MsgType><![CDATA[video]]></MsgType>
19          <Video>
20          <MediaId><![CDATA[media_id]]></MediaId>
21          <Title><![CDATA[title]]></Title>
22          <Description><![CDATA[description]]></Description>
23          </Video>
24          </xml>
25          */
26         return String.format(
27                 "<xml>" +
28                         "<ToUserName><![CDATA[%s]]></ToUserName>" +
29                         "<FromUserName><![CDATA[%s]]></FromUserName>" +
30                         "<CreateTime>%s</CreateTime>" +
31                         "<MsgType><![CDATA[video]]></MsgType>" +
32                         "<Video>" +
33                         "   <MediaId><![CDATA[%s]]></MediaId>" +
34                         "   <Title><![CDATA[%s]]></Title>" +
35                         "   <Description><![CDATA[%s]]></Description>" +
36                         "</Video>" +
37                         "</xml>",
38                 fromUserName, toUserName, getMessageCreateTime(), video.mediaId, video.title, video.description);
39     }
复制代码

  2.2.5、回复语音消息

  写一个构建语音消息的方法,代码如下:

复制代码
 1  /**
 2      * 构造语音消息
 3      * @param map 封装了解析结果的Map
 4      * @param mediaId 通过素材管理接口上传多媒体文件得到的id
 5      * @return 语音消息XML字符串
 6      */
 7     private static String buildVoiceMessage(Map<String, String> map, String mediaId) {
 8         //发送方帐号
 9         String fromUserName = map.get("FromUserName");
10         // 开发者微信号
11         String toUserName = map.get("ToUserName");
12         /**
13          * 语音消息XML数据格式
14          *<xml>
15          <ToUserName><![CDATA[toUser]]></ToUserName>
16          <FromUserName><![CDATA[fromUser]]></FromUserName>
17          <CreateTime>12345678</CreateTime>
18          <MsgType><![CDATA[voice]]></MsgType>
19          <Voice>
20          <MediaId><![CDATA[media_id]]></MediaId>
21          </Voice>
22          </xml>
23          */
24         return String.format(
25                 "<xml>" +
26                         "<ToUserName><![CDATA[%s]]></ToUserName>" +
27                         "<FromUserName><![CDATA[%s]]></FromUserName>" +
28                         "<CreateTime>%s</CreateTime>" +
29                         "<MsgType><![CDATA[voice]]></MsgType>" +
30                         "<Voice>" +
31                         "   <MediaId><![CDATA[%s]]></MediaId>" +
32                         "</Voice>" +
33                         "</xml>",
34                 fromUserName, toUserName, getMessageCreateTime(), mediaId);
35     }
复制代码

  2.2.6、回复图文消息

  写一个构建图文消息的方法,代码如下:

复制代码
 1   /**
 2      * 构造图文消息
 3      * @param map 封装了解析结果的Map
 4      * @return 图文消息XML字符串
 5      */
 6     private static String buildNewsMessage(Map<String, String> map) {
 7         String fromUserName = map.get("FromUserName");
 8         // 开发者微信号
 9         String toUserName = map.get("ToUserName");
10         NewsItem item = new NewsItem();
11         item.Title = "微信开发学习总结(一)——微信开发环境搭建";
12         item.Description = "工欲善其事,必先利其器。要做微信公众号开发,那么要先准备好两样必不可少的东西:\n" +
13                 "\n" +
14                 "  1、要有一个用来测试的公众号。\n" +
15                 "\n" +
16                 "  2、用来调式代码的开发环境";
17         item.PicUrl = "http://images2015.cnblogs.com/blog/289233/201601/289233-20160121164317343-2145023644.png";
18         item.Url = "http://www.cnblogs.com/xdp-gacl/p/5149171.html";
19         String itemContent1 = buildSingleItem(item);
20 
21         NewsItem item2 = new NewsItem();
22         item2.Title = "微信开发学习总结(二)——微信开发入门";
23         item2.Description = "微信服务器就相当于一个转发服务器,终端(手机、Pad等)发起请求至微信服务器,微信服务器然后将请求转发给我们的应用服务器。应用服务器处理完毕后,将响应数据回发给微信服务器,微信服务器再将具体响应信息回复到微信App终端。";
24         item2.PicUrl = "";
25         item2.Url = "http://www.cnblogs.com/xdp-gacl/p/5151857.html";
26         String itemContent2 = buildSingleItem(item2);
27 
28 
29         String content = String.format("<xml>\n" +
30                 "<ToUserName><![CDATA[%s]]></ToUserName>\n" +
31                 "<FromUserName><![CDATA[%s]]></FromUserName>\n" +
32                 "<CreateTime>%s</CreateTime>\n" +
33                 "<MsgType><![CDATA[news]]></MsgType>\n" +
34                 "<ArticleCount>%s</ArticleCount>\n" +
35                 "<Articles>\n" + "%s" +
36                 "</Articles>\n" +
37                 "</xml> ", fromUserName, toUserName, getMessageCreateTime(), 2, itemContent1 + itemContent2);
38         return content;
39 
40     }
41 
42     /**
43      * 生成图文消息的一条记录
44      *
45      * @param item
46      * @return
47      */
48     private static String buildSingleItem(NewsItem item) {
49         String itemContent = String.format("<item>\n" +
50                 "<Title><![CDATA[%s]]></Title> \n" +
51                 "<Description><![CDATA[%s]]></Description>\n" +
52                 "<PicUrl><![CDATA[%s]]></PicUrl>\n" +
53                 "<Url><![CDATA[%s]]></Url>\n" +
54                 "</item>", item.Title, item.Description, item.PicUrl, item.Url);
55         return itemContent;
56     }
复制代码

  根据上述提到的消息回复业务场景,我们可以写一个handleTextMessage方法来作为构造各种回复消息的处理入口,代码如下:

复制代码
 1  /**
 2      * 接收到文本消息后处理
 3      * @param map 封装了解析结果的Map
 4      * @return
 5      */
 6     private static String handleTextMessage(Map<String, String> map) {
 7         //响应消息
 8         String responseMessage;
 9         // 消息内容
10         String content = map.get("Content");
11         switch (content) {
12             case "文本":
13                 String msgText = "孤傲苍狼又要开始写博客总结了,欢迎朋友们访问我在博客园上面写的博客\n" +
14                         "<a href=\"http://www.cnblogs.com/xdp-gacl\">孤傲苍狼的博客</a>";
15                 responseMessage = buildTextMessage(map, msgText);
16                 break;
17             case "图片":
18                 //通过素材管理接口上传图片时得到的media_id
19                 String imgMediaId = "dSQCiEHYB-pgi7ib5KpeoFlqpg09J31H28rex6xKgwWrln3HY0BTsoxnRV-xC_SQ";
20                 responseMessage = buildImageMessage(map, imgMediaId);
21                 break;
22             case "语音":
23                 //通过素材管理接口上传语音文件时得到的media_id
24                 String voiceMediaId = "h3ul0TnwaRPut6Tl1Xlf0kk_9aUqtQvfM5Oq21unoWqJrwks505pkMGMbHnCHBBZ";
25                 responseMessage = buildVoiceMessage(map,voiceMediaId);
26                 break;
27             case "图文":
28                 responseMessage = buildNewsMessage(map);
29                 break;
30             case "音乐":
31                 Music music = new Music();
32                 music.title = "赵丽颖、许志安 - 乱世俱灭";
33                 music.description = "电视剧《蜀山战纪》插曲";
34                 music.musicUrl = "http://gacl.ngrok.natapp.cn/music/music.mp3";
35                 music.hqMusicUrl = "http://gacl.ngrok.natapp.cn/music/music.mp3";
36                 responseMessage = buildMusicMessage(map, music);
37                 break;
38             case "视频":
39                 Video video = new Video();
40                 video.mediaId = "GqmIGpLu41rtwaY7WCVtJAL3ZbslzKiuLEXfWIKYDnHXGObH1CBH71xtgrGwyCa3";
41                 video.title = "小苹果";
42                 video.description = "小苹果搞笑视频";
43                 responseMessage = buildVideoMessage(map, video);
44                 break;
45             default:
46                 responseMessage = buildWelcomeTextMessage(map);
47                 break;
48 
49         }
50         //返回响应消息
51         return responseMessage;
52     }
复制代码

  到此,回复想消息的相关处理代码就编写完成了,将项目部署到Tomcat服务器进行测试,记得使用Ngrok将内网的服务器映射到外网,否则无法使用微信测试,如下:

  

  关于Ngrok的使用方式之前的《微信开发学习总结(一)——微信开发环境搭建》博客中已经介绍过了,这里就不再重复讲解了,没了解过Ngrok的朋友可以去看看《微信开发学习总结(一)——微信开发环境搭建》这篇博客.

  使用微信进行消息回复测试,测试效果如下:

  


  

  可以看到,每一种消息都正常响应了.

  这里需要说一下图片,语音,视频的回复消息构造,这三种消息构造时的都需要一个mediaId,而这个mediaId通过素材管理接口上传多媒体文件得到的,为了构造图片,语音,视频的这几种回复消息,我事先准备好了测试素材,如下图所示:

  

  然后通过微信公众号平台提供的素材管理接口将图片,语音,视频上传到微信服务器上,上传成功后,微信服务器会给我们返回一个mediaId,用于标识上传成功的多媒体素材,上传素材的工具类代码如下:

复制代码
  1 package me.gacl.wx.util;
  2 
  3 import com.alibaba.fastjson.JSON;
  4 import com.alibaba.fastjson.JSONException;
  5 import com.alibaba.fastjson.JSONObject;
  6 import org.apache.commons.httpclient.HttpClient;
  7 import org.apache.commons.httpclient.HttpException;
  8 import org.apache.commons.httpclient.methods.PostMethod;
  9 import org.apache.commons.httpclient.methods.multipart.FilePart;
 10 import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
 11 import org.apache.commons.httpclient.methods.multipart.Part;
 12 import org.apache.commons.httpclient.methods.multipart.StringPart;
 13 import org.apache.commons.httpclient.protocol.Protocol;
 14 import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
 15 import org.apache.http.HttpStatus;
 16 
 17 import javax.net.ssl.*;
 18 import java.io.*;
 19 import java.net.HttpURLConnection;
 20 import java.net.URL;
 21 import java.security.cert.CertificateException;
 22 import java.security.cert.X509Certificate;
 23 
 24 /**
 25  * Created by allen on 2016/1/29.
 26  */
 27 public class WeChatApiUtil {
 28     // token 接口(GET)
 29     private static final String ACCESS_TOKEN = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";
 30     // 素材上传(POST)https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
 31     private static final String UPLOAD_MEDIA = "https://api.weixin.qq.com/cgi-bin/media/upload";
 32     // 素材下载:不支持视频文件的下载(GET)
 33     private static final String DOWNLOAD_MEDIA = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=%s&media_id=%s";
 34 
 35     public static String getTokenUrl(String appId, String appSecret) {
 36         return String.format(ACCESS_TOKEN, appId, appSecret);
 37     }
 38 
 39     public static String getDownloadUrl(String token, String mediaId) {
 40         return String.format(DOWNLOAD_MEDIA, token, mediaId);
 41     }
 42 
 43     /**
 44      * 通用接口获取Token凭证
 45      *
 46      * @param appId
 47      * @param appSecret
 48      * @return
 49      */
 50     public static String getToken(String appId, String appSecret) {
 51         if (appId == null || appSecret == null) {
 52             return null;
 53         }
 54 
 55         String token = null;
 56         String tockenUrl = WeChatApiUtil.getTokenUrl(appId, appSecret);
 57         String response = httpsRequestToString(tockenUrl, "GET", null);
 58         JSONObject jsonObject = JSON.parseObject(response);
 59         if (null != jsonObject) {
 60             try {
 61                 token = jsonObject.getString("access_token");
 62             } catch (JSONException e) {
 63                 token = null;// 获取token失败
 64             }
 65         }
 66         return token;
 67     }
 68 
 69     /**
 70      * 微信服务器素材上传
 71      *
 72      * @param file  表单名称media
 73      * @param token access_token
 74      * @param type  type只支持四种类型素材(video/image/voice/thumb)
 75      */
 76     public static JSONObject uploadMedia(File file, String token, String type) {
 77         if (file == null || token == null || type == null) {
 78             return null;
 79         }
 80 
 81         if (!file.exists()) {
 82             System.out.println("上传文件不存在,请检查!");
 83             return null;
 84         }
 85 
 86         String url = UPLOAD_MEDIA;
 87         JSONObject jsonObject = null;
 88         PostMethod post = new PostMethod(url);
 89         post.setRequestHeader("Connection", "Keep-Alive");
 90         post.setRequestHeader("Cache-Control", "no-cache");
 91         FilePart media;
 92         HttpClient httpClient = new HttpClient();
 93         //信任任何类型的证书
 94         Protocol myhttps = new Protocol("https", new SSLProtocolSocketFactory(), 443);
 95         Protocol.registerProtocol("https", myhttps);
 96 
 97         try {
 98             media = new FilePart("media", file);
 99             Part[] parts = new Part[]{new StringPart("access_token", token),
100                     new StringPart("type", type), media};
101             MultipartRequestEntity entity = new MultipartRequestEntity(parts,
102                     post.getParams());
103             post.setRequestEntity(entity);
104             int status = httpClient.executeMethod(post);
105             if (status == HttpStatus.SC_OK) {
106                 String text = post.getResponseBodyAsString();
107                 jsonObject = JSONObject.parseObject(text);
108             } else {
109                 System.out.println("upload Media failure status is:" + status);
110             }
111         } catch (FileNotFoundException e) {
112             e.printStackTrace();
113         } catch (HttpException e) {
114             e.printStackTrace();
115         } catch (IOException e) {
116             e.printStackTrace();
117         }
118         return jsonObject;
119     }
120 
121     /**
122      * 多媒体下载接口
123      *
124      * @param fileName 素材存储文件路径
125      * @param token    认证token
126      * @param mediaId  素材ID(对应上传后获取到的ID)
127      * @return 素材文件
128      * @comment 不支持视频文件的下载
129      */
130     public static File downloadMedia(String fileName, String token,
131                                      String mediaId) {
132         String url = getDownloadUrl(token, mediaId);
133         return httpRequestToFile(fileName, url, "GET", null);
134     }
135 
136     /**
137      * 多媒体下载接口
138      *
139      * @param fileName 素材存储文件路径
140      * @param mediaId  素材ID(对应上传后获取到的ID)
141      * @return 素材文件
142      * @comment 不支持视频文件的下载
143      */
144     public static File downloadMedia(String fileName, String mediaId) {
145         String appId = "wxbe4d433e857e8bb1";
146         String appSecret = "ccbc82d560876711027b3d43a6f2ebda";
147         String token = WeChatApiUtil.getToken(appId, appSecret);
148         return downloadMedia(fileName,token,mediaId);
149     }
150 
151     /**
152      * 以http方式发送请求,并将请求响应内容输出到文件
153      *
154      * @param path   请求路径
155      * @param method 请求方法
156      * @param body   请求数据
157      * @return 返回响应的存储到文件
158      */
159     public static File httpRequestToFile(String fileName, String path, String method, String body) {
160         if (fileName == null || path == null || method == null) {
161             return null;
162         }
163 
164         File file = null;
165         HttpURLConnection conn = null;
166         InputStream inputStream = null;
167         FileOutputStream fileOut = null;
168         try {
169             URL url = new URL(path);
170             conn = (HttpURLConnection) url.openConnection();
171             conn.setDoOutput(true);
172             conn.setDoInput(true);
173             conn.setUseCaches(false);
174             conn.setRequestMethod(method);
175             if (null != body) {
176                 OutputStream outputStream = conn.getOutputStream();
177                 outputStream.write(body.getBytes("UTF-8"));
178                 outputStream.close();
179             }
180 
181             inputStream = conn.getInputStream();
182             if (inputStream != null) {
183                 file = new File(fileName);
184             } else {
185                 return file;
186             }
187 
188             //写入到文件
189             fileOut = new FileOutputStream(file);
190             if (fileOut != null) {
191                 int c = inputStream.read();
192                 while (c != -1) {
193                     fileOut.write(c);
194                     c = inputStream.read();
195                 }
196             }
197         } catch (Exception e) {
198         } finally {
199             if (conn != null) {
200                 conn.disconnect();
201             }
202 
203             /*
204              * 必须关闭文件流
205              * 否则JDK运行时,文件被占用其他进程无法访问
206              */
207             try {
208                 inputStream.close();
209                 fileOut.close();
210             } catch (IOException execption) {
211             }
212         }
213         return file;
214     }
215 
216     /**
217      * 上传素材
218      * @param filePath 媒体文件路径(绝对路径)
219      * @param type 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)
220      * @return
221      */
222     public static JSONObject uploadMedia(String filePath,String type){
223         File f = new File(filePath); // 获取本地文件
224         String appId = "wxbe4d433e857e8bb1";
225         String appSecret = "ccbc82d560876711027b3d43a6f2ebda";
226         String token = WeChatApiUtil.getToken(appId, appSecret);
227         JSONObject jsonObject = uploadMedia(f, token, type);
228         return jsonObject;
229     }
230 
231     /**
232      * 发送请求以https方式发送请求并将请求响应内容以String方式返回
233      *
234      * @param path   请求路径
235      * @param method 请求方法
236      * @param body   请求数据体
237      * @return 请求响应内容转换成字符串信息
238      */
239     public static String httpsRequestToString(String path, String method, String body) {
240         if (path == null || method == null) {
241             return null;
242         }
243 
244         String response = null;
245         InputStream inputStream = null;
246         InputStreamReader inputStreamReader = null;
247         BufferedReader bufferedReader = null;
248         HttpsURLConnection conn = null;
249         try {
250             TrustManager[] tm = {new JEEWeiXinX509TrustManager()};
251             SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
252             sslContext.init(null, tm, new java.security.SecureRandom());
253             SSLSocketFactory ssf = sslContext.getSocketFactory();
254             System.out.println(path);
255             URL url = new URL(path);
256             conn = (HttpsURLConnection) url.openConnection();
257             conn.setSSLSocketFactory(ssf);
258 
259             conn.setDoOutput(true);
260             conn.setDoInput(true);
261             conn.setUseCaches(false);
262             conn.setRequestMethod(method);
263             if (null != body) {
264                 OutputStream outputStream = conn.getOutputStream();
265                 outputStream.write(body.getBytes("UTF-8"));
266                 outputStream.close();
267             }
268 
269             inputStream = conn.getInputStream();
270             inputStreamReader = new InputStreamReader(inputStream, "UTF-8");
271             bufferedReader = new BufferedReader(inputStreamReader);
272             String str = null;
273             StringBuffer buffer = new StringBuffer();
274             while ((str = bufferedReader.readLine()) != null) {
275                 buffer.append(str);
276             }
277 
278             response = buffer.toString();
279         } catch (Exception e) {
280 
281         } finally {
282             if (conn != null) {
283                 conn.disconnect();
284             }
285             try {
286                 bufferedReader.close();
287                 inputStreamReader.close();
288                 inputStream.close();
289             } catch (IOException execption) {
290 
291             }
292         }
293         return response;
294     }
295 
296     public static void main(String[] args) throws Exception{
297         //媒体文件路径
298         String filePath = "D:/JavaSoftwareDevelopeFolder/IntelliJ IDEA_Workspace/WxStudy/web/media/image/我.jpg";
299         //String filePath = "D:/JavaSoftwareDevelopeFolder/IntelliJ IDEA_Workspace/WxStudy/web/media/voice/voice.mp3";
300         //String filePath = "D:\\JavaSoftwareDevelopeFolder\\IntelliJ IDEA_Workspace\\WxStudy\\web\\media\\video\\小苹果.mp4";
301         //媒体文件类型
302         String type = "image";
303         //String type = "voice";
304         //String type = "video";
305         JSONObject uploadResult = uploadMedia(filePath, type);
306         //{"media_id":"dSQCiEHYB-pgi7ib5KpeoFlqpg09J31H28rex6xKgwWrln3HY0BTsoxnRV-xC_SQ","created_at":1455520569,"type":"image"}
307         System.out.println(uploadResult.toString());
308 
309         //下载刚刚上传的图片以id命名
310         String media_id = uploadResult.getString("media_id");
311         File file = downloadMedia("D:/" + media_id + ".png", media_id);
312         System.out.println(file.getName());
313 
314     }
315 }
316 
317 class JEEWeiXinX509TrustManager implements X509TrustManager {
318     public void checkClientTrusted(X509Certificate[] chain, String authType)
319             throws CertificateException {
320     }
321 
322     public void checkServerTrusted(X509Certificate[] chain, String authType)
323             throws CertificateException {
324     }
325 
326     public X509Certificate[] getAcceptedIssuers() {
327         return null;
328     }
329 }
复制代码

  在工具类写一个main方法测试素材上传和下载,代码如下:

复制代码
 1 public static void main(String[] args) throws Exception{
 2         //媒体文件路径
 3         String filePath = "D:/JavaSoftwareDevelopeFolder/IntelliJ IDEA_Workspace/WxStudy/web/media/image/我.jpg";
 4         //String filePath = "D:/JavaSoftwareDevelopeFolder/IntelliJ IDEA_Workspace/WxStudy/web/media/voice/voice.mp3";
 5         //String filePath = "D:\\JavaSoftwareDevelopeFolder\\IntelliJ IDEA_Workspace\\WxStudy\\web\\media\\video\\小苹果.mp4";
 6         //媒体文件类型
 7         String type = "image";
 8         //String type = "voice";
 9         //String type = "video";
10         JSONObject uploadResult = uploadMedia(filePath, type);
11         //{"media_id":"dSQCiEHYB-pgi7ib5KpeoFlqpg09J31H28rex6xKgwWrln3HY0BTsoxnRV-xC_SQ","created_at":1455520569,"type":"image"}
12         System.out.println(uploadResult.toString());
13 
14         //下载刚刚上传的图片以id命名
15         String media_id = uploadResult.getString("media_id");
16         File file = downloadMedia("D:/" + media_id + ".png", media_id);
17         System.out.println(file.getName());
18 
19     }
复制代码

  运行结果如下:

  

   可以看到,素材上传成功后,微信服务器就会返回一个media_id,用于标识上传后的文件.有了这个media_id后,我们就可以构建我们想要的图片,语音,视频回复消息了.

  下面再说一下音乐的回复消息的构造,音乐素材也是我事先在服务器上准备了一个music.mp3音乐文件,并且保证可以正常使用外网访问,如下所示:

  

  然后将MusicUrlHQMusicUrl的地址指向了服务器上的music.mp3文件的访问地址,如下:

1 Music music = new Music();
2 music.title = "赵丽颖、许志安 - 乱世俱灭";
3 music.description = "电视剧《蜀山战纪》插曲";
4 music.musicUrl = "http://gacl.ngrok.natapp.cn/media/music/music.mp3";
5 music.hqMusicUrl = "http://gacl.ngrok.natapp.cn/media/music/music.mp3";
6 responseMessage = buildMusicMessage(map, music);

  这样就可以正常构造音乐回复消息了.

  以上就是关于微信公众号的普通消息的接收和回复的全部内容了,希望对大家有帮助,写得不好的地方也欢迎园友们指正,千里之行,始于足下,我们对微信开发又有了进一步的了解了,本篇博客对应的项目代码下载

微信开发介绍

阅读数 179

没有更多推荐了,返回首页