微信作为移动互联网的第一张门票,是我们理解和连接世界的一条很好的路径,是我们在移动互联网时代的ID。而微信公众号可以建立起一对多的较强的服务与用户之间的连接,公众号分为订阅号、服务号、企业号三种,提供不同的侧重点:订阅号每天推送,服务号一个月能推送一次。我在业余时间开发了一个微信公众号JavaDeveloper,实现的功能包括历史上的今天、发送来QQ表情返回原来的QQ表情、搜索歌曲、翻译、人脸识别、机器人聊天、天气预报(机器人自己实现了)、周边搜索。。。。本微信号只是我的学习之作,没有进行系统的设计,微信公众号的开发首先需要定位,还要找到好的宣传渠道。

本文总结我的微信开发历程,主要包括微信的开发步骤、调用第三方的Webservice、设计模式的运用,是一个挺综合的项目,与其说是微信公众号开发,倒不如说JavaWeb开发。

微信公众号可以提供给关注这个公众号的用户的功能完全由这个公众号的后台服务器完成。公众号与用户之间发送的消息和公众号与服务器之间的通信消息都是XML格式,可以看做微信的服务器调用公众号的服务器的Webservice,后者作为前者的客户端。
        由于通信格式XML的平台独立化,公众号的服务器可以使普通的Web服务器,不限编程语言、平台等一切Webservice的优点都具备。微信好像推荐使用PHP,其例程都是PHP的,但是由于我对Java比较熟悉,所以选择了Java作为开发语言。实际上微信公众号的开发就是普通的Web开发,别无二至。我们既可以使用最基础的Servlet,也可以使用SSH等一切Web开发的技术,这里我选择最简单的Servlet。
        微信公众号的开发首先必须提供一个公网上可以访问的地址,以作为通信校验和微信服务器与你的服务器之间的通信。通信校验使用GET方式,发送给你的字符串你可以校验请求来自微信服务器;你必须返回其规定的字符串以校验握手。

非常详细的步骤我就不贴出了,详见柳峰博客、高洛峰微信开发视频教程。

有一个测试地址,输入你的公网服务器地址,发送你的消息就能获取到你的服务器地址的消息,就想在手机上玩微信一样,还能看见具体的XML信息,这个网址应该知道微信的服务器地址和发送的协议,模拟手机的微信给微信服务器发送信息,得到之后通过Ajax刷新。http://open.binguo.me/Tester,其实你自己写一个都行。只要知道 了与微信服务器之间的通信协议。

微信公众号有个至关重要的地方,别人怎么会加你关注你,一定是你的内容信息是别人需要的,随手就能加你。你的微信公众号随手就能加你二维码出现在很多地方。个人微信ID做成二维码,别人扫描后直接加好友。

/**
     *
     *    确认请求来自微信服务器
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //每次请求都会带上这几个除了echostr的字符串,所以在post的时候也可以利用他们验证请求来自微信
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
        // 随机字符串
        String echostr = request.getParameter("echostr");

PrintWriter out = response.getWriter();
        // 通过检验signature 对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
        if (Signature.checkSignature(signature, timestamp, nonce)) {
            out.print(echostr);
        }else {
            out.print("你不是微信服务器,请自重!!");
        }
        out.close();
        out = null;
    }
    
    
    /**
* 请求校验工具类
*
 * @author 熊诗言
 * @date 2015-09-05
 */
 public class Signature {
     // 与接口配置信息中的Token 要一致
     private static String token = "xiongshiyan";

/**
     * 验证签名
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
     public static boolean checkSignature(String signature, String timestamp,String nonce) {
         String[] arr = new String[] { token, timestamp, nonce };
         // 将token、timestamp、nonce 三个参数进行字典序排序
         Arrays.sort(arr);
         StringBuilder content = new StringBuilder();
         for (int i = 0; i < arr.length; i++) {
             content.append(arr[i]);
         }
         MessageDigest md = null;
         String tmpStr = null;
         try {
             md = MessageDigest.getInstance("SHA-1");
         // 将三个参数字符串拼接成一个字符串进行sha1 加密
             byte[] digest = md.digest(content.toString().getBytes());
             tmpStr = byte2Str(digest);
         } catch (NoSuchAlgorithmException e) {
             e.printStackTrace();
         }
        
         content = null;
         // 将sha1 加密后的字符串可与signature 对比,标识该请求来源于微信
         return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
     }

/**
    * 将字节数组转换为十六进制字符串
    *
    * @param byteArray
    * @return
    */
    private static String byte2Str(byte[] byteArray) {
        String strDigest = "";
        for (int i = 0; i < byteArray.length; i++) {
            strDigest += byte2HexStr(byteArray[i]);
        }
        return strDigest;
    }

/**
    * 将字节转换为十六进制字符串
    *
    * @param mByte
    * @return
    */
    private static String byte2HexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];
        
        String s = new String(tempArr);
        return s;
    }
}

微信服务器的每次请求都是POST方式。发送来XML的数据,你也返回XML的数据。
    /**
     *
     *    处理微信服务器的请求
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // TODO 消息的接收、处理、响应
        //将请求、响应的编码均设置为UTF-8(防止中文乱码)
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        response.setContentType("text/xml;charset=utf-8");

// 调用核心业务类接收消息、处理消息
        String respMessage = WeiXinService.processRequest3(request);

// 响应消息
        PrintWriter out = response.getWriter();
        out.print(respMessage);
        out.close();
    }

微信公众号开发(一):搭建开发环境相关推荐

  1. 微信公众号网页在本地开发模式下如何使用正式环境的域名来调试

    微信公众号网页在本地开发模式下如何使用正式环境的域名来调试? 鄙人之前也不知道,网上搜了一下,看到的几篇文章都是要使用代理,有用Nginx的,还有自己写代理的.主要是按照步骤做了并不行.于是自己折腾了 ...

  2. 公众号分享页面php,微信公众号网页分享功能开发的示例代码

    现在每天都可以看到很多微信分享的链接上面有网站或者商家的自定义的分享标题,和分享链接的描述及分享出去的图像,例如下面的分享出去的链接: 上面这个是微信的js-SDK页面分享给微信好友在聊天列表中显示的 ...

  3. 微信公众号的二次开发(二 自定义菜单的创建)

    在上篇<微信公众号的二次开发(一)>我们介绍了微信订阅号的一些坑, 以及微信公众平台开发的一些基本配置.下面我们继续介绍如何通过用户关注等行为.获取用户的openid. 自定义微信公众号菜 ...

  4. 如何判断微信公众号是否二次开发(一)

    微信公众号是否二次开发,即微信公众号是否使用了公众平台开发接口(其中主要如:自定义菜单接口.配置第三方开发服务器接口.调用外部链接等). 接下来介绍如何用手机直观的去判断微信公众号是否二次开发,主要从 ...

  5. 微信公众号的二次开发(三、接收事件推送获取用户信息)

    在上篇<微信公众号的二次开发(二 自定义菜单的创建)>中我们介绍了自定义菜单的创建.本篇文章将介绍如何通过接收事件推送来获取用户信息.首先我们阅读官方文档: 根据官方文档的介绍 微信公众号 ...

  6. 微信公众号消息推送开发(模板消息):点击推送消息跳转到网页或者小程序(三)

    需求场景: 点击推送的消息后跳转到小程序中的某个页面,或者跳转到某一个网页上,例如有这样一个需求,在商城平台购买产品后,需要通过公众号给用户推送订单详细并且点击消息可以看到对应的订单详情.以下我将在微 ...

  7. 微信公众号抓取 所需环境及部分业务代码(基于windows 系统 和 安卓手机)①

    微信公众号抓取所需环境(基于windows 系统 和 安卓手机) 手机 2.Java 环境 3,安卓环境 4.appium 5.anyprxy 6.python环境7.nodejs PC环境搭建: J ...

  8. 微信公众号商城怎么搭建和如何运营

    现在智能手机已经普及到每一个人,微信作为频繁使用的APP之一,拥有大量的用户群体,这可以给创业者带来巨大的商机.那么没有经验的人怎么搭建微信公众号商场,该如何搭建,从那里开始,怎么运营微信公众号商城. ...

  9. 阿里云+python+flask+ngnix零基础从零开始搭建微信公众号进行后台AI开发全套教程

    目录 一.微信公众号开发基础 1.1 与公众号的消息会话 1.2 与公众号内的网页交互 1.2 搭建开发者环境 1.2.1 配置nginx环境 1.2.2 云服务器与微信服务器建立连接 1.2.2.1 ...

  10. 微信公众号抢票系统开发笔记

    本次组队小作业的开发项目是微信公众号的抢票系统.我负责的是管理员的一些后台操作以及公众号内通过点击按钮.回复文字可以实现的一些票务功能的后端开发. 以下是我在开发过程中遇到的问题.解决方法. 前期准备 ...

最新文章

  1. 华为云服务器 大文件,云服务器上传大文件
  2. 通过MySQL存储原理来分析排序和锁
  3. Thread的run()与start()的区别
  4. cmd mysql utf8_MySQL中UTF8编码的数据在cmd下乱码
  5. mysql 创建用户命令-grant
  6. matlab绘制数字滤波器的幅频响应曲线
  7. Windows7安装VC2015-2019_redist.x64提示“设置失败0xc8000222-未指定的错误”
  8. Python 实现电信天翼网关光猫自动重启
  9. BZOJ2286: [Sdoi2011]消耗战 虚树
  10. android edittext删除文本框,Android EditText 文本框实现搜索和清空效果
  11. 2.11 header footer hgroup address元素
  12. 苹果vs剪辑下载_秒简iPhone上的一款免费手机视频剪辑软件,支持导入视频或图片...
  13. 如何编写好的用户手册?
  14. NFC模块化设计方案
  15. Keil同时安装C51与ARM环境
  16. php奥运金牌排序代码,Excel | 用奥运奖牌榜学习排序排名
  17. Phpyun人才系统6.4_6.5零工市场开源代码小程序上架步骤更新流程
  18. Android性能优化:定性和定位Android图形性能问题——以后台录屏进程为例
  19. android的sdk和adt,ADT和Android SDK的安装
  20. 41 | MySQL快速复制数据到一张表中(本篇躺平一下,了解即可)

热门文章

  1. 蓝桥杯单片机省赛第三届初赛试题 自动售水机
  2. stm32学习(二)STM32F103ZET6内部资源讲解
  3. ZLMediaKit
  4. prometheus 添加 login 登录认证界面(nginx + flask 实现)
  5. 关于redhat5.4的最新QT SDK的安装后无法编译运行的解决办法(我弄了好几天亲测好用)
  6. BAPI_GOODSMVT_CREATE MIGO采购订单IQC质检退回到供应商 124 实例
  7. 《不抱怨的世界》之我的抱怨
  8. 计算机乘法怎么操作函数,计算机word乘积函数
  9. 这几天折腾spark的kafka的低阶API createDirectStream的一些总结。
  10. 世界各国当前时间js代码