微信公众帐号开发_微信公众号绑定微信开发者账号 - CSDN
精华内容
参与话题
  • [025] 微信公众帐号开发教程第1篇-引言

    万次阅读 多人点赞 2013-05-17 19:18:22
    接触微信公众帐号已经有两个多月的时间了,在这期间,除了陆续完善个人公众帐号xiaoqrobot以外,还带领团队为公司开发了两个企业应用:一个是普通类型的公众帐号,另一个是会议类型的公众帐号。经过这3个公众帐号的...

    接触微信公众帐号已经有两个多月的时间了,在这期间,除了陆续完善个人公众帐号xiaoqrobot以外,还带领团队为公司开发了两个企业应用:一个是普通类型的公众帐号,另一个是会议类型的公众帐号。经过这3个公众帐号的开发,对目前微信公众平台开放的api算是比较熟悉了,像文本消息、图文消息、音乐消息、语音消息、位置消息等全部用到过,菜单也使用过。所以,就有了写微信公众帐号开发教程的想法,将学习到的技术经验分享出来,帮助更多需要的朋友,也希望借此认识同行的朋友,共同交流,共同进步!


    下面将对即将推出的微信公众帐号开发系列连载教程做简单的说明。教程主要是面向有一定Java编程基础的朋友,不打算从编程语言开始讲起,一是考虑到自己没有那么多时间和精力(要上班、装修、学车等),二是怕等我把编程语言讲完,微信公众帐号又发生了大变化,这样教程就显得有点过时,没有吸引力了,所以只能是有侧重点的介绍。至于内容方面,大概会涉及到:

    1)前沿知识:微信公众帐号的分类、两种模式各自的特点和区别、开发模式的配置使用等;

    2)API中各类消息的使用(我已经对api进行封装并打成了jar包,到时候会考虑分享出来);

    3)微信公众帐号开发中的小技巧(如换行、通过代码发送表情、屏幕飘雪花、表情的接收识别、在Android和iOS上表现不一致等等);

    4)与业务系统对接的方法(链接、短信等,除了技术讲解还会做一定的分析对比);

    5)微信公众平台上常见功能的开发(如像小黄鸡那样的人机对话、天气预报、精确的定位及百度地图的使用、音乐搜索、语音识别解析等)

    当然,具体写出来的内容肯定不止这些,但一定会包含以上介绍的所有内容。


    我也不知道多久能写完这些内容,当然是越快越好,我会尽全力的。希望正在看博文的你通过微信关注xiaoqrobot或者在博客留言支持,给我动力,谢谢!


    开发xiaoqrobot就是为了学习微信公众帐号开发,将api开放出来的各类消息都体验了。虽然现在看来有点大杂烩的意思,但还是比较实用的,一款生活、娱乐的好帮手,目前已有370多关注者。周边搜索功能定位比较准确(解决了纠偏问题,能精确到十米范围),平时出门在外搜美食、ATM机、厕所、超市等再方便不过了,还提供路线导航;聊天唠嗑功能是我自己开发的,后面的连载教程很多内容都会从中抽取出来,下面是主界面截图,对系列连载教程有所期待的朋友很建议关注体验下,做的不好的地方也请多提意见,除了技术本身外,体验也是我比较重视关注的。


    展开全文
  • 微信公众号开发账号申请与接入

    万次阅读 2018-02-28 00:13:21
    接入微信公众平台开发需要使用微信公众号,由于正式微信公众号...所以,为了帮助开发者快速了解和上手微信公众号开发,熟悉各个接口的调用,微信还提供了微信公众帐号测试号,通过手机微信扫描二维码即可获得测试号。
    接入微信公众平台开发需要使用微信公众号,由于正式微信公众号注册具有一定门槛,普通用户很难申请。所以,为了帮助开发者快速了解和上手微信公众号开发,熟悉各个接口的调用,微信还提供了微信公众帐号测试号,通过手机微信扫描二维码即可获得测试号。
    测试号申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
    当普通微信用户向公众号发送消息或者与微信公众号进行互动触发某些事件时,微信服务器将会把这些消息或者事件以XML数据包格式POST到开发者配置的服务器地址URL上,对于公众号和公众账号测试号的配置方式如下。

    配置微信公众号

    微信公众平台地址:https://mp.weixin.qq.com
    配置步骤:公众平台首页-->开发-->基本配置-->服务器配置-->修改配置。

    配置测试号

    测试号管理地址:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
    对于公众账号测试号,在接口配置信息中对服务器地址URL和令牌Token进行设置,配置规则与正式微信公众号相同。

    验证服务器地址URL

    开发者提交配置信息后,微信服务器将发送GET请求到填写的服务器地址URL上以验证配置的服务器地址URL是否正确并确认开发者的身份,GET请求携带参数如下表所示:
    开发者需在配置的服务器地址URL中对GET请求传入的signature进行校验,以确认此次请求是否来自微信服务器,若确认此次GET请求来自微信服务器,只需原样返回echostr参数内容即可接入成功,否则接入失败。
    加密/校验流程如下:
    1)将token、timestamp、nonce三个参数进行字典序排序;
    2)将三个参数字符串拼接成一个字符串进行sha1加密;
    3)开发者获得加密后的字符串可与signature对比,判断该请求是否来源于微信。
    校验signature的Java示例代码如下。
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    
    import com.pengjunlee.wechat.msg.WeChatEncrypt;
    import com.pengjunlee.wechat.msg.WechatSession;
    
    /**
     * 处理微信消息和事件专用控制器
     */
    @Controller
    @RequestMapping("/wechat")
    public class WeChatController
    {
    
        private static final String token = "pengjunlee";// 公众号管理后台配置的令牌(Token)
    
        /**
         * 验证微信服务器端GET请求 实现一
         * 
         * @param out
         * @param request
         * @param response
         */
        @RequestMapping(value = "/index", method = RequestMethod.GET)
        public void checkSignature(PrintWriter out, HttpServletRequest request, HttpServletResponse response)
        {
    
            String signature = request.getParameter("signature"); // 微信加密签名
            String timestamp = request.getParameter("timestamp"); // 时间戳
            String nonce = request.getParameter("nonce"); // 随机数
            String echostr = request.getParameter("echostr"); // 随机字符串
    
            String[] arr = new String[]
            {
                    token, timestamp, nonce
            };
    
            // 对数组内的token、timestamp、nonce三个元素进行字典序排序
            Arrays.sort(arr);
    
            // 将排序后的token、timestamp、nonce三个字符串按顺序拼接成一个字符串
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < arr.length; i++)
            {
                sb.append(arr[i]);
            }
    
            // 对拼接好的字符串进行SHA-1加密
            String tmpStr = WeChatEncrypt.encrypt(sb.toString(), WeChatEncrypt.SHA_1);
    
            // 将加密后的字符串与signature进行比较
            if (tmpStr.equals(signature))
            {
                out.print(echostr);// 身份验证成功,将echostr字符串内容原样返回
            }
            else
            {
                out.print("");// 身份验证失败,返回空字符串
            }
            out.flush();
            out.close();
        }
    
        /**
         * 验证微信服务器端GET请求 实现二
         * 
         * @param out
         * @param signature
         * @param timestamp
         * @param nonce
         * @param echostr
         * @throws Exception
         */
        @GetMapping(value = "/index2")
        public void checkSignature2(PrintWriter out, @RequestParam(value = "signature", required = true) String signature, @RequestParam String timestamp,
                @RequestParam String nonce, @RequestParam String echostr) throws Exception
        {
            List<String> list = new ArrayList<String>(3)
            {
                private static final long serialVersionUID = 1L;
    
                @Override
                public String toString()
                {
                    return this.get(0) + this.get(1) + this.get(2);
                }
            };
            list.add(token); // 令牌
            list.add(timestamp);// 时间戳
            list.add(nonce);// 随机数
    
            Collections.sort(list); // 排序
            String tmpStr = WeChatEncrypt.encrypt(list.toString(), WeChatEncrypt.SHA_1); // SHA-1加密
            if (signature.equals(tmpStr))
            {
                out.write(echostr); // 身份验证成功,将echostr字符串内容原样返回
            }
            else
            {
                out.write(""); // 身份验证失败,返回空字符串
            }
            out.flush();
            out.close();
        }
    
        /**
         * 接收微信服务器POST过来的各种消息&事件
         * 
         * @param request
         * @param response
         * @throws Exception
         */
        @PostMapping(value = "/index")
        public void interceptMsgAndEvent(HttpServletRequest request, HttpServletResponse response) throws Exception
        {
            // response.setCharacterEncoding("UTF-8");
            response.setContentType("application/xml; charset=UTF-8"); // 设置响应内容的类型和编码字符集
            InputStream in = request.getInputStream();
            PrintWriter out = response.getWriter();
            handleMsgAndEvent(in, out);
        }
    
        /**
         * 处理微信服务器POST过来的各种消息&事件
         * 
         * @param in
         * @param out
         * @throws Exception
         */
        public void handleMsgAndEvent(InputStream in, PrintWriter out) throws Exception
        {
    
            WechatSession session = new WechatSession(in, out);
            session.process(); // 处理微信消息或者事件
            session.close(); // 关闭Session
        }
    }
    
    WeChatEncrypt  加密工具类。
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    
    /**
     * 微信公众号字符串加密工具类
     */
    public class WeChatEncrypt
    {
    
        public static final String MD5 = "MD5";
        public static final String SHA_1 = "SHA-1";
        public static final String SHA_256 = "SHA_256";
    
        /**
         * 使用指定的加密算法对字符串进行加密
         * 
         * @param srcStr
         *            要加密的字符串
         * @param encryptType
         *            MD5\SHA_1\SHA_256
         * @return 加密后的字符串
         */
        public static String encrypt(String srcStr, String encryptType)
        {
            String desStr = "";
            try
            {
                if ((encryptType == null) || ("".equals(encryptType)))
                    encryptType = "MD5";
                MessageDigest md = MessageDigest.getInstance(encryptType);
                md.update(srcStr.getBytes());
                desStr = bytes2Hex(md.digest());
            }
            catch (NoSuchAlgorithmException e)
            {
                return srcStr;
            }
            return desStr;
        }
    
        /**
         * 将字节数组转换为16进制字符串
         * 
         * @param bts
         * @return
         */
        private static String bytes2Hex(byte[] bts)
        {
            String des = "";
            String tmp = null;
            for (int i = 0; i < bts.length; i++)
            {
                tmp = Integer.toHexString(bts[i] & 0xFF);
                if (tmp.length() == 1)
                {
                    des += "0";
                }
                des += tmp;
            }
            return des;
        }
    
        public static void main(String[] args)
        {
            String strSrc = "\u53EF\u4EE5\u52A0\u5BC6\u6C49\u5B57";
            System.out.println("Source String:" + strSrc);
            System.out.println("Encrypted String:");
            System.out.println("Use MD5:" + encrypt(strSrc, null));
            System.out.println("Use MD5:" + encrypt(strSrc, "MD5"));
            System.out.println("Use SHA:" + encrypt(strSrc, "SHA-1"));
            System.out.println("Use SHA-256:" + encrypt(strSrc, "SHA-256"));
        }
    }
    本文项目源码已上传至CSDN,资源地址:http://download.csdn.net/download/pengjunlee/10257857
    展开全文
  • 微信公众号开发——项目搭建

    万次阅读 2018-09-11 15:23:25
    前往微信公众平台(https://mp.weixin.qq.com/)获取开发权限和开发账号,公众号分为好几种,小程序,订阅号,服务号,企业号,个人只能用订阅号,权限比较少(api接口权限); 二 想要自定义模块功能或者是回复...

    一 

    前往微信公众平台(https://mp.weixin.qq.com/)获取开发权限和开发账号,公众号分为好几种,小程序,订阅号,服务号,企业号,个人只能用订阅号,权限比较少(api接口权限);

    想要自定义模块功能或者是回复信息啥的,就得有一个自己的后台来写接口,所以要配置自己的服务器

    基本配置:服务器配置(首页-开发-基本配置-服务器配置)

    进入修改配置,这里的服务器地址必须是外网(没有服务器的小伙伴如果这里分不清。。外网特征就是别人可以通过你的本机ip直接访问到,在简单点就是,你如果使用WiFi连接的网络那就肯定是内网或者说是局域网,查看方式,window键加R键,输入cmd回车,然后输入ipconfig 查看你当前的ip,然后百度本机ip,不一样的话就不是外网,解决办法是使用natapp进行内网穿透或者是用路由器进行端口映射,将服务器的某个端口映射出去,在最后会有详细步骤)而且是80端口,格式为ip/域名+wx(接口名 ,固定,但是前面可以加路由比如ip/home/wx)Token随便写个;

    然后是后台不多说先上代码:

    /// <summary>
    /// 配合微信服务器验证域名或者是ip的可用行或者是获取消息的推送--pxj
    /// </summary>
    [AtSkipAuthorize]
    public void wx()
    {
    	//获取消息推送,或者是事件推送,类型是xml文件流
    	if (Request.RequestType == "POST")
    	{
    
    	}
    	else
    	{
    		#region 验证请求来源是否是微信
    		string signature = Request["signature"].ToString();
    		string timestamp = Request["timestamp"].ToString();
    
    		string nonce = Request["nonce"].ToString();
    		string echostr = Request["echostr"].ToString();
    		string token = "hellowb";
    		List<string> list = new List<string>() { token, timestamp, nonce };
    		list.Sort();
    		string data = string.Join("", list);
    		byte[] temp1 = Encoding.UTF8.GetBytes(data);
    		SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
    		byte[] temp2 = sha.ComputeHash(temp1);
    
    		var hashCode = BitConverter.ToString(temp2);
    		hashCode = hashCode.Replace("-", "").ToLower();
    
    		if (hashCode == signature)
    		{
    			Response.Write(echostr);
    			Response.End();
    		}
    		LogHelper.WriteLog("signature:" + signature + " timestamp:" + timestamp + " nonce:" + nonce + " echostr:" + echostr);
    		#endregion
    	}
    }

    写好后台配置好服务器就可以在微信公众号网站也就是刚才的那个页面点击提交了,点击提交后微信的服务器会向你所配置的服务器80端口的这个接口发送GET请求,验证接口是否正确,如果提交成功,恭喜你可以进入下一个坑了;

    当你在写微信公众号的页面的时候,你有时候会用到上传图片或者打开摄像机等要求,这时候要接入JS_SDK,配置签名等等,这个签名应该算是配置里最难受的一块了。。。

    签名的获取有几个步骤,先是要通过appid和appSecret来获取access_token,然后用access_token来获取jsapi_ticket,代码如下

     //获取access_token
    string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, appSecret);
    var wc = new WebClient();
    string access_tokenRet = wc.DownloadString(url);
    string access_token = JsonHelper.JsonToObj<AccessTokenModel>(access_tokenRet).Access_Token;
    accesstokenstatic = access_token;
    
    //获取jsapi_ticket
    string Jsapi_TicketUrl = string.Format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={0}&type=jsapi", access_token);
    var jsapiRet = wc.DownloadString(Jsapi_TicketUrl);
    string ticket = JsonHelper.JsonToObj<TickModel>(jsapiRet).ticket;
    ticketstatic = ticket;

    然后获取十位的时间戳和自己写的随机字符串和页面传来的url,将jsapi_ticket,url,timestamp(时间戳),nocestr(随机字符串随便写一个就行)sort方法排序,然后根据这几个的顺序进行赋值并用sha1加密如下

    string signaturestring = "jsapi_ticket=" + ticket + "&noncestr=" + nocestr + "&timestamp=" + timestamp + "&url=" + url2;
    byte[] temp1 = Encoding.UTF8.GetBytes(signaturestring);
    
    SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider();
    byte[] temp2 = sha.ComputeHash(temp1);
    var hashCode = BitConverter.ToString(temp2);
    hashCode = hashCode.Replace("-", "").ToLower();

     如此一来全部的都有了,返回这些就行了,如果报错了说url不合法就要取配置以下域名,二级域名也能用;

    四 ,带参二维码的扫描和事件的推送

    当你的公众号涉及到分享二维码给其他人,每一张二维码上还得要有你的信息的时候,需要在公众号的二维码上添加上一个场景值,比如你的用户id,当客户或者是其他用户通过你分享的二维码进入公众号的时候,微信服务器会推送给你一个xml包,其中一个子节点上就存着那个场景值;

    直接上代码--获取部分,

     public void GetQrCode()
     {
    	 string accesstoken = accesstokenstatic;
    	 if (string.IsNullOrEmpty(accesstoken))
    	 {
    		 //先主动取获取以下所需要的变量
    		 getaccesstoken(null, null);
    		 accesstoken = accesstokenstatic;
    		 Timer();
    	 }
    	//使用匿名对象作为post的参数然后再序列化
    	 var datap = new
    	 {
    		 //二维码的有效期(10天)
    		 expire_seconds = 864000,
    		 //类型动态的二维码
    		 action_name = "QR_SCENE",
    		 //信息
    		 action_info = new
    		 {
    			 scene = new {
    				 //自定义参数数值型为scene_id ,字符为scene_str
    				 scene_id = 15552300793
    			 }
    		 }
    	 };
    	 //使用流发送post带参请求
    	 string url = string.Format("https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={0}",accesstoken);
    	 HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
    	 request.Method = "POST";
    	 request.ContentType = "application/json";
    	 byte[] data = Encoding.UTF8.GetBytes(JsonHelper.ModelToJson(datap));
    	 request.ContentLength = data.Length;
    	 using (Stream strea = request.GetRequestStream())
    	 {
    		 strea.Write(data,0,data.Length);
    		 strea.Close();
    	 }
    	 HttpWebResponse respose = (HttpWebResponse)request.GetResponse();
    	 Stream stream = respose.GetResponseStream();
    	 string stringRespose = "";
    	 using (StreamReader sr = new StreamReader(stream, Encoding.UTF8))
    	 {
    		 stringRespose = sr.ReadToEnd();
    	 }
    	 if (string.IsNullOrEmpty(stringRespose))
    	 {
    		 Response.Write("sorry");
    	 }
    	 else { 
    		 //此时已经获取到二维码所使用的ticket
    		 string qrticket = JsonHelper.JsonToObj<QrCoderTicektModel>(stringRespose).ticket; 
    		 //二维码解析后的地址(可以自己转化为二维码)
    		 string qrurl =  JsonHelper.JsonToObj<QrCoderTicektModel>(stringRespose).url; 
    		 Response.Write("hhhhhh");
    		 LogHelper.WriteLog("getsometing:" + stringRespose);
    	 }
     }

    现在是获得了二维码的解析后的url,和获取二维码的ticket;有两种方式可以得到二维码,一种是直接将这个地址url返给前端,前端自己生成,二是后台获取到这个二维码后保存到服务器,前端自己去取;

    获取微信的推送,如刚才所说,扫码的时候会发送一个xml包;

    代码如下

    public void wx()
    {
    	//获取消息推送,或者是事件推送,类型是xml文件流
    	if (Request.RequestType == "POST")
    	{
    		#region 推送
    		//加载xml包,获取推送的内容
    		StreamReader sr = new StreamReader(Request.InputStream);
    		string xmlData = sr.ReadToEnd();
    		LogHelper.WriteLog(xmlData);
    		var doc = new XmlDocument();
    		doc.LoadXml(xmlData);
    		//获取xml包里的消息类型和事件类型,分类处理
    		var msgTypeNode = doc.SelectSingleNode("xml/MsgType");
    		var evenTypeNode = doc.SelectSingleNode("xml/Event");
    		string msgTypeString = msgTypeNode.InnerText;
    		if (evenTypeNode == null)
    		{
    			//此时为普通的消息推送
    		}
    		else
    		{
    			//此时为事件推送
    			string evenTypeString = evenTypeNode.InnerText;
    			//扫描带参的二维码的时候和关注和取关的推送
    			if (evenTypeString == "SCAN" || evenTypeString == "subscribe")
    			{
    				string SaoMaRenOpenId = doc.SelectSingleNode("xml/FromUserName").InnerText;
    				var BeiSaoRenCanShuNode = doc.SelectSingleNode("xml/EventKey");
    				if (BeiSaoRenCanShuNode != null)
    				{
    					string BeiSaoRenCanShuSting = BeiSaoRenCanShuNode.InnerText.Split('_')[1];
    					//已经获取扫码人和被扫人的个人id,下面就是存到数据库做关联就ok了,用到的时候取
    				}
    			}
    
    			//地理位置推送
    			if (evenTypeString == "LOCATION")
    			{
    
    			}
    
    			//点击自定义菜单拉去信息的时候的推送
    			if (evenTypeString == "CLICK")
    			{
    
    			}
    		}
    		#endregion
    	}

    五,

    natapp内网穿透:

    https://natapp.cn/注册,登录,获取自己的隧道,下载客户端,解压,cmd进入客户端的文件夹,natapp.exe -authtoken = "你的autotoken",

    如下则成功了

     

     

    展开全文
  • [037] 微信公众帐号开发教程第13篇-图文消息全攻略

    万次阅读 多人点赞 2013-07-25 22:35:13
    引言及内容概要 已经有几位读者抱怨“柳峰只用到文本消息作为示例,从来不提图文消息,...本篇主要介绍微信公众帐号开发中图文消息的使用,以及图文消息的几种表现形式。标题取名为“图文消息全攻略”,这绝对不是标题

    引言及内容概要

    已经有几位读者抱怨“柳峰只用到文本消息作为示例,从来不提图文消息,都不知道图文消息该如何使用”,好吧,我错了,原本以为把基础API封装完、框架搭建好,再给出一个文本消息的使用示例,大家就能够照猫画虎的,或许是因为我的绘画功底太差,画出的那只猫本来就不像猫吧……

    本篇主要介绍微信公众帐号开发中图文消息的使用,以及图文消息的几种表现形式。标题取名为“图文消息全攻略”,这绝对不是标题党,是想借此机会把大家对图文消息相关的问题、疑虑、障碍全部清除掉。

     

    图文消息的主要参数说明

    通过微信官方的消息接口指南,可以看到对图文消息的参数介绍,如下图所示:

    从图中可以了解到:

    1)图文消息的个数限制为10,也就是图中ArticleCount的值(图文消息的个数,限制在10条以内);

    2)对于多图文消息,第一条图文的图片显示为大图,其他图文的图片显示为小图;

    3)第一条图文的图片大小建议为640*320,其他图文的图片大小建议为80*80;

    好了,了解这些,再结合第4篇文章所讲的消息及消息处理工具的封装,想要回复图文消息给用户也就不是什么难事了。

     

    图文消息的多种表现形式

    下面直接通过代码演示图文消息最主要的五种表现形式的用法,源代码如下:

    package org.liufeng.course.service;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    
    import org.liufeng.course.message.resp.Article;
    import org.liufeng.course.message.resp.NewsMessage;
    import org.liufeng.course.message.resp.TextMessage;
    import org.liufeng.course.util.MessageUtil;
    
    /**
     * 核心服务类
     * 
     * @author liufeng
     * @date 2013-07-25
     */
    public class CoreService {
    	/**
    	 * 处理微信发来的请求
    	 * 
    	 * @param request
    	 * @return
    	 */
    	public static String processRequest(HttpServletRequest request) {
    		String respMessage = null;
    		try {
    			// xml请求解析
    			Map<String, String> requestMap = MessageUtil.parseXml(request);
    
    			// 发送方帐号(open_id)
    			String fromUserName = requestMap.get("FromUserName");
    			// 公众帐号
    			String toUserName = requestMap.get("ToUserName");
    			// 消息类型
    			String msgType = requestMap.get("MsgType");
    
    			// 默认回复此文本消息
    			TextMessage textMessage = new TextMessage();
    			textMessage.setToUserName(fromUserName);
    			textMessage.setFromUserName(toUserName);
    			textMessage.setCreateTime(new Date().getTime());
    			textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
    			textMessage.setFuncFlag(0);
    			// 由于href属性值必须用双引号引起,这与字符串本身的双引号冲突,所以要转义
    			textMessage.setContent("欢迎访问<a href=\"http://blog.csdn.net/lyq8479\">柳峰的博客</a>!");
    			// 将文本消息对象转换成xml字符串
    			respMessage = MessageUtil.textMessageToXml(textMessage);
    
    			// 文本消息
    			if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
    				// 接收用户发送的文本消息内容
    				String content = requestMap.get("Content");
    
    				// 创建图文消息
    				NewsMessage newsMessage = new NewsMessage();
    				newsMessage.setToUserName(fromUserName);
    				newsMessage.setFromUserName(toUserName);
    				newsMessage.setCreateTime(new Date().getTime());
    				newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS);
    				newsMessage.setFuncFlag(0);
    
    				List<Article> articleList = new ArrayList<Article>();
    				// 单图文消息
    				if ("1".equals(content)) {
    					Article article = new Article();
    					article.setTitle("微信公众帐号开发教程Java版");
    					article.setDescription("柳峰,80后,微信公众帐号开发经验4个月。为帮助初学者入门,特推出此系列教程,也希望借此机会认识更多同行!");
    					article.setPicUrl("http://0.xiaoqrobot.duapp.com/images/avatar_liufeng.jpg");
    					article.setUrl("http://blog.csdn.net/lyq8479");
    					articleList.add(article);
    					// 设置图文消息个数
    					newsMessage.setArticleCount(articleList.size());
    					// 设置图文消息包含的图文集合
    					newsMessage.setArticles(articleList);
    					// 将图文消息对象转换成xml字符串
    					respMessage = MessageUtil.newsMessageToXml(newsMessage);
    				}
    				// 单图文消息---不含图片
    				else if ("2".equals(content)) {
    					Article article = new Article();
    					article.setTitle("微信公众帐号开发教程Java版");
    					// 图文消息中可以使用QQ表情、符号表情
    					article.setDescription("柳峰,80后," + emoji(0x1F6B9)
    							+ ",微信公众帐号开发经验4个月。为帮助初学者入门,特推出此系列连载教程,也希望借此机会认识更多同行!\n\n目前已推出教程共12篇,包括接口配置、消息封装、框架搭建、QQ表情发送、符号表情发送等。\n\n后期还计划推出一些实用功能的开发讲解,例如:天气预报、周边搜索、聊天功能等。");
    					// 将图片置为空
    					article.setPicUrl("");
    					article.setUrl("http://blog.csdn.net/lyq8479");
    					articleList.add(article);
    					newsMessage.setArticleCount(articleList.size());
    					newsMessage.setArticles(articleList);
    					respMessage = MessageUtil.newsMessageToXml(newsMessage);
    				}
    				// 多图文消息
    				else if ("3".equals(content)) {
    					Article article1 = new Article();
    					article1.setTitle("微信公众帐号开发教程\n引言");
    					article1.setDescription("");
    					article1.setPicUrl("http://0.xiaoqrobot.duapp.com/images/avatar_liufeng.jpg");
    					article1.setUrl("http://blog.csdn.net/lyq8479/article/details/8937622");
    
    					Article article2 = new Article();
    					article2.setTitle("第2篇\n微信公众帐号的类型");
    					article2.setDescription("");
    					article2.setPicUrl("http://avatar.csdn.net/1/4/A/1_lyq8479.jpg");
    					article2.setUrl("http://blog.csdn.net/lyq8479/article/details/8941577");
    
    					Article article3 = new Article();
    					article3.setTitle("第3篇\n开发模式启用及接口配置");
    					article3.setDescription("");
    					article3.setPicUrl("http://avatar.csdn.net/1/4/A/1_lyq8479.jpg");
    					article3.setUrl("http://blog.csdn.net/lyq8479/article/details/8944988");
    
    					articleList.add(article1);
    					articleList.add(article2);
    					articleList.add(article3);
    					newsMessage.setArticleCount(articleList.size());
    					newsMessage.setArticles(articleList);
    					respMessage = MessageUtil.newsMessageToXml(newsMessage);
    				}
    				// 多图文消息---首条消息不含图片
    				else if ("4".equals(content)) {
    					Article article1 = new Article();
    					article1.setTitle("微信公众帐号开发教程Java版");
    					article1.setDescription("");
    					// 将图片置为空
    					article1.setPicUrl("");
    					article1.setUrl("http://blog.csdn.net/lyq8479");
    
    					Article article2 = new Article();
    					article2.setTitle("第4篇\n消息及消息处理工具的封装");
    					article2.setDescription("");
    					article2.setPicUrl("http://avatar.csdn.net/1/4/A/1_lyq8479.jpg");
    					article2.setUrl("http://blog.csdn.net/lyq8479/article/details/8949088");
    
    					Article article3 = new Article();
    					article3.setTitle("第5篇\n各种消息的接收与响应");
    					article3.setDescription("");
    					article3.setPicUrl("http://avatar.csdn.net/1/4/A/1_lyq8479.jpg");
    					article3.setUrl("http://blog.csdn.net/lyq8479/article/details/8952173");
    
    					Article article4 = new Article();
    					article4.setTitle("第6篇\n文本消息的内容长度限制揭秘");
    					article4.setDescription("");
    					article4.setPicUrl("http://avatar.csdn.net/1/4/A/1_lyq8479.jpg");
    					article4.setUrl("http://blog.csdn.net/lyq8479/article/details/8967824");
    
    					articleList.add(article1);
    					articleList.add(article2);
    					articleList.add(article3);
    					articleList.add(article4);
    					newsMessage.setArticleCount(articleList.size());
    					newsMessage.setArticles(articleList);
    					respMessage = MessageUtil.newsMessageToXml(newsMessage);
    				}
    				// 多图文消息---最后一条消息不含图片
    				else if ("5".equals(content)) {
    					Article article1 = new Article();
    					article1.setTitle("第7篇\n文本消息中换行符的使用");
    					article1.setDescription("");
    					article1.setPicUrl("http://0.xiaoqrobot.duapp.com/images/avatar_liufeng.jpg");
    					article1.setUrl("http://blog.csdn.net/lyq8479/article/details/9141467");
    
    					Article article2 = new Article();
    					article2.setTitle("第8篇\n文本消息中使用网页超链接");
    					article2.setDescription("");
    					article2.setPicUrl("http://avatar.csdn.net/1/4/A/1_lyq8479.jpg");
    					article2.setUrl("http://blog.csdn.net/lyq8479/article/details/9157455");
    
    					Article article3 = new Article();
    					article3.setTitle("如果觉得文章对你有所帮助,请通过博客留言或关注微信公众帐号xiaoqrobot来支持柳峰!");
    					article3.setDescription("");
    					// 将图片置为空
    					article3.setPicUrl("");
    					article3.setUrl("http://blog.csdn.net/lyq8479");
    
    					articleList.add(article1);
    					articleList.add(article2);
    					articleList.add(article3);
    					newsMessage.setArticleCount(articleList.size());
    					newsMessage.setArticles(articleList);
    					respMessage = MessageUtil.newsMessageToXml(newsMessage);
    				}
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return respMessage;
    	}
    
    	/**
    	 * emoji表情转换(hex -> utf-16)
    	 * 
    	 * @param hexEmoji
    	 * @return
    	 */
    	public static String emoji(int hexEmoji) {
    		return String.valueOf(Character.toChars(hexEmoji));
    	}
    }

    如果不明白CoreService类放在什么位置,该如何使用,请查看本系列教程的第5篇。上面代码实现的功能是当用户发送数字1-5时,分别回复五种不同表现形式的图文消息给用户,如下:

    a)用户发送1,回复单图文消息。参考代码68~81行,运行效果如下:

     

    b)用户发送2,回复单图文消息---不含图片。参考代码82~96行,运行效果如下:

    说明:图文消息的标题、描述是可以包含QQ表情、符号表情的。

     

    c)用户发送3,回复多图文消息。参考代码97~123行,运行效果如下:

    说明:对于多图文消息,描述不会被显示,可以在标题使用换行符,使得显示更加美观。

     

    d)用户发送4,回复多图文消息---首条消息不含图片。参考代码124~158行,运行效果如下:

     

    e)用户发送5,回复多图文消息---最后一条消息不含图片。参考代码159~186行,运行效果如下:

    可以看出,图文消息有着丰富的内容及多样化的表现形式,希望大家能够根据各自的特点及实际使用需要,合理地运用。

     

    最后,根据实践经验,我对图文消息做一个使用总结:

    1)一定要给图文消息的Url属性赋值。不管是单图文,还是多图文,或者是不含图片的图文,都有可能会被用户点击。如果Url为空,用户点击后将会打开一个空白页面,这给用户的体验是非常差的;

    2)只有单图文的描述才会显示,多图文的描述不会被显示

    3)图文消息的标题、描述中可以使用QQ表情和符号表情。合理地运用表情符号,会使得消息更加生动;

    4)图文消息的标题、描述中可以使用换行符。合理地使用换行符,会使得内容结构更加清晰;

    5)图文消息的标题、描述中不支持超文本链接(html的<a>标签)。不只是技术上实现不了,就连逻辑上也说不通,因为一条图文消息的任何位置被点击,都将调用微信内置的浏览器打开Url,如果标题、描述里再放几个超链接,不知道点击该打开哪个页面。真搞不懂为什么有好几个同学都在问这个问题,难道设计成多图文不好吗?

    6)图文消息的链接、图片链接可以使用外部域名下的资源如本例中:柳峰的头像、博文的链接,都是指向CSDN网站的资源。在网上,甚至是微信官方交流群里,认为图文消息的Url、PicUrl不可以使用外链的大有人在,不知道这谣言从哪开始的,实践是检验真理的唯一标准!

    7)使用指定大小的图片。第一条图文的图片大小建议为640*320,其他图文的图片大小建议为80*80。如果使用的图片太大,加载慢,而且耗流量;如果使用的图片太小,显示后会被拉伸,失真了很难看。

    8)每条图文消息的图文建议控制在1-4条。这样在绝大多数终端上一屏能够显示完,用户扫一眼就能大概了解消息的主要内容,这样最有可能促使用户去点击并阅读。

     

    如果觉得文章对你有所帮助,请通过留言或关注微信公众帐号xiaoqrobot支持柳峰!

    转帖请注明本文出自柳峰的博客(http://blog.csdn.net/lyq8479),请尊重他人的辛勤劳动成果,谢谢!

     

    展开全文
  • 微信公众号开发-超级简单

    万次阅读 2020-05-06 17:05:12
    【图片模糊的双击图片,就清晰了】 ... 这个功能就是别人给公众号发什么消息,就返回指定内容 ... 收到消息回复:当你不是输入关键词时,自动发送当前消息,如果输入的是关键词,就返回关键词所指定的内容 ...
  • 微信公众号后台开发总结

    万次阅读 2018-03-19 17:24:10
    微信公众号后台开发总结一、项目简介当前需要做一个公众号后台,前期需要实现的功能有:(1) 在用户关注公众号时便获取用户的信息同时还要将用户信息存入数据库。(2) 在用户给公众号发送消息时,后台能够对消息...
  • 微信公众号开发教程(一) 验证接入

    万次阅读 多人点赞 2018-06-22 14:22:35
    微信公众号开发教程(一)验证接入本篇文章主要介绍了微信公众号开发接入详细流程,希望对刚接触公众号开发的同学有所帮助,有兴趣的同学可多多关注叩丁狼公众号,后续会更新不同的公众号小案例。公众号的分类我们平常...
  • 微信公众号开发测试帐号

    万次阅读 2018-01-10 10:33:01
    扫描关注后登录 ...填写JS接口安全域名 ,设置JS接口安全域后,通过关注该测试号,开发者即可在该域名下调用微信开放的JS接口,请阅读微信JSSDK开发文档。 注意:不知道啥原因,用自己的帐号申请测试
  • Java开发微信公众号(一)——微信开发环境搭建

    万次阅读 多人点赞 2017-12-10 16:32:22
    准备工作最近学习微信公众平台的开发,在申请一个微信公众号的时候,发现如果不是公司或组织只能申请订阅号(并且是个人的),而且不能使用微信提供的高级接口,所以如果想要使用公众平台的高级接口的话,申请一个...
  • 微信公众平台、微信开放平台的关系背景简介微信公众平台能干什么?微信开放平台(open平台)能干什么? 背景 做微信相关开发的时候,要登录很多账号,而且不同的功能要在这两个账号之间切换来切换去,很烦;所以今天...
  • PHP实现微信公众平台开发-基础篇

    万次阅读 2017-12-20 21:28:09
    第1章 微信公众账号及申请流程微信三角色关系微信公众账号: 充当的是自媒体角色 微信应用: 平台角色 微信用户: 普通用户 对微信应用而言: 微信应用给微信公众账号和微信用户提供了信息交互,获取资讯的一个...
  • 微信公众平台开发教程

    千次阅读 2014-01-29 16:47:02
    专题导读:微信公众平台是腾讯公司在微信的基础上新增的功能模块,通过这一平台,个人和企业都可以打造一个微信的公众号,并实现和特定群体的文字、图片、语音的全方位沟通、互动。2013年8月5日,微信公众平台进行...
  • 微信公众平台使用教程-多客服

    千人学习 2018-10-22 21:38:05
    微信公众平台使用教程之多客服是子恒老师推出的微信使用课程,目的是为了后面微信多客服的开发打下基础,因为只有你熟悉了微信公众号多客服的使用,在开发时,才能够知道里面用到的业务场景。欢迎反馈:微信/QQ:...
  • 微信公众平台完整开发教程

    万次阅读 2015-07-31 11:33:21
    还能通过公众账号来获取各种资源……如今的微信就是在日中天的状态(最新估值已达 600 亿),公众平台带来的影响有目共睹,所以很多人都有自己的公众号,想充分利用却无处下手,所以我们在这里给大家提供一下微信...
  • 微信公众号系列之测试号使用

    万次阅读 2019-11-10 21:31:12
    微信公众平台认证之前,我们可以先申请一个测试的公众号来进行测试,这对开发人员来说还是有很大好处的! 微信公众平台提供了测试账号,在公众账号没有审核之前,也是可以进行开发的。进入后台->开发者工具-...
  •   1.开发语言使用Java  2.使用微信接口测试账号进行本地测试  3.使用natapp(原ngrok)将本地地址映射到外网...最近学习微信公众平台的开发,在申请一个微信公众号的时候,发现如果不是公司或组织只能申请订...
  • 参照博客[027] 微信公众帐号开发教程第3篇-开发模式启用及接口配置 启用公共平台开发者模式并进行接口配置 加密/校验流程如下: 1. 将token、timestamp、nonce三个参数进行字典序排序 2. 将三个参数字符串拼接成...
  • 微信开发平台功能思维导图

    千次阅读 2013-07-30 18:13:29
    单位要开发公众账号,抽时间看了一下
  • 微信小游戏开发零基础教程(一)-CocosCreator

    万次阅读 多人点赞 2018-12-19 10:58:48
    微信小游戏零基础教程(一)-CocosCreator最终效果预览准备工作创建工程测试第一个场景 ...去 微信公众平台 注册一个账号,记得选择账号用途 小程序 -&amp;amp;gt;注册地址 创建工程 打开安装好的 CocosCre...
  • 微信公众号二次开发可以做哪些功能?

    千次阅读 多人点赞 2019-01-16 08:44:37
    这是众多使用微信公众平台的商家企业需要深入思考的问题,微信公众平台自带的很多功能,但难以满足所有企业的不同特定化的需求,所以企业需要通过微信公共平台二次开发来实现更多功能需求,使得微信公众平台更好的为...
1 2 3 4 5 ... 20
收藏数 19,307
精华内容 7,722
关键字:

微信公众帐号开发