微信开发学习总结(二)——微信开发入门

上一篇《微信开发学习总结(一)—微信开发环境搭建》我们已经完成了微信开发的准备工作,准备工作完成之后,就要开始步入正题了。
一、微信公众平台的基本原理
  在开始做之前,先简单介绍了微信公众平台的基本原理。
  微信服务器就相当于一个转发服务器,终端(手机、Pad等)发起请求至微信服务器,微信服务器然后将请求转发给我们的应用服务器。应用服务器处理完毕后,将响应数据回发给微信服务器,微信服务器再将具体响应信息回复到微信App终端。
  通信协议为:HTTP
  数据传输格式为:XML
  具体的流程如下图所示:
  这里写图片描述

这里写图片描述
我们需要做的事情,就是对微信服务器转发的HTTP请求做出响应。具体的请求内容,我们按照特定的XML格式去解析,处理完毕后,也要按照特定的XML格式返回

二、微信公众号接入
  在微信公众平台开发者文档上,关于公众号接入这一节内容在接入指南上写的比较详细的,文档中说接入公众号需要3个步骤,分别是:
  1、填写服务器配置
  2、验证服务器地址的有效性
  3、依据接口文档实现业务逻辑

  其实,第3步已经不能算做公众号接入的步骤,而是接入之后,开发人员可以根据微信公众号提供的接口所能做的一些开发。

  第1步中服务器配置包含服务器地址(URL)、Token和EncodingAESKey。

  服务器地址即公众号后台提供业务逻辑的入口地址,目前只支持80端口,之后包括接入验证以及任何其它的操作的请求(例如消息的发送、菜单管理、素材管理等)都要从这个地址进入。接入验证和其它请求的区别就是,接入验证时是get请求,其它时候是post请求;
  Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性);
  EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。本例中全部以未加密的明文消息方式,不涉及此配置项。
  第2步,验证服务器地址的有效性,当点击“提交”按钮后,微信服务器将发送一个http的get请求到刚刚填写的服务器地址,并且携带四个参数:
  这里写图片描述
接到请求后,我们需要做如下三步,若确认此次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,否则接入失败。
  1. 将token、timestamp、nonce三个参数进行字典序排序
  2. 将三个参数字符串拼接成一个字符串进行sha1加密
  3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
下面咱们用javaweb项目来演示下流程:
这里写图片描述

编写一个servlevt,在其中的doGet方法中定义校验方法,具体代码如下:

package com.onion.servlet;

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.onion.message.WxMessageUtil;
import com.onion.service.AccessTokenService;
import com.onion.service.UserInfoService;
import com.onion.thread.UserInfoThread;
import com.onion.xml.MessageHandlerUtil;

/**
 * Onion 
 * 使用@WebServlet注解配置WxServlet,urlPatterns属性指明了WxServlet的访问路径
 * 
 * 配置微信的路径
 */
@WebServlet(urlPatterns="/WxServlet",loadOnStartup=1)
public class WxServlet extends BaseServlet {

    private Logger logger = LoggerFactory.getLogger(WxServlet.class);

    /**
     * Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
     * 比如这里我将Token设置为Onion
     */
    private final String TOKEN = "Onion";

    private final String charset = "UTF-8";



    @Override
    public void init() throws ServletException {
        super.init();
        System.out.println("开始初始化");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("开始校验签名");
        /**
         * 接收微信服务器发送请求时传递过来的4个参数
         */
        String signature = request.getParameter("signature");//微信加密签名signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
        String timestamp = request.getParameter("timestamp");//时间戳
        String nonce = request.getParameter("nonce");//随机数
        String echostr = request.getParameter("echostr");//随机字符串
        //1)将token、timestamp、nonce三个参数进行字典序排序
        //2)将三个参数字符串拼接成一个字符串进行sha1加密
        // 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
        //排序
        String sortString = sort(TOKEN, timestamp, nonce);
        //加密
        String mySignature = sha1(sortString);
        //校验签名
        if (mySignature != null && mySignature != "" && mySignature.equals(signature)) {
            System.out.println("签名校验通过。");
            //如果检验成功输出echostr,微信服务器接收到此输出,才会确认检验完成。
            //response.getWriter().println(echostr);
            response.getWriter().write(echostr);
        } else {
            System.out.println("签名校验失败.");
        }

    }

    /**
     * 排序方法
     *
     * @param token
     * @param timestamp
     * @param nonce
     * @return
     */
    public String sort(String token, String timestamp, String nonce) {
        String[] strArray = {token, timestamp, nonce};
        if(token != null && timestamp != null && nonce != null ){
            Arrays.sort(strArray);
        }
        StringBuilder sb = new StringBuilder();
        for (String str : strArray) {
            sb.append(str);
        }

        return sb.toString();
    }

    /**
     * 将字符串进行sha1加密
     *
     * @param str 需要加密的字符串
     * @return 加密后的内容
     */
    public String sha1(String str) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-1");
            digest.update(str.getBytes());
            byte messageDigest[] = digest.digest();
            // Create Hex String
            StringBuffer hexString = new StringBuffer();
            // 字节数组转换为 十六进制 数
            for (int i = 0; i < messageDigest.length; i++) {
                String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);
                if (shaHex.length() < 2) {
                    hexString.append(0);
                }
                hexString.append(shaHex);
            }
            return hexString.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
}

我这里用的Servlet3.0,使用Servlet3.0的好处就是可以直接使用@WebServlet注解映射Servlet的访问路径,不再需要在web.xml文件中进行配置.
如果大家在使用Servlet3.0遇到问题,可以看下我的这边博客@WebServlet——Servlet3.0新特性。本人在该博客中记录了解决问题的办法。
将项目使用tomcat7插件运行,启动项目,然后用花生壳将本地80端口映射到外网如下图所示:
 测试是否可以通过http://h17742910b.imwork.net地址正常访问。
如果能正常访问,说明我们的项目可以被外网访问了;
这里写图片描述
  进入微信测试公众号管理界面,在接口配置信息中填入映射的外网地址和token,如下图所示:
  这里写图片描述

点击提交按钮,页面会提示配置成功,
这里写图片描述

如果配置不成功,可以使用调试模式跟踪下代码。
配置成功后,我们会在我们的IDE控制台中看到输出:如下所示
这里写图片描述
到此,我们的公众号应用已经能够和微信服务器正常通信了,也就是说我们的公众号已经接入到微信公众平台了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值