Java 微信公众平台开发(一)——开发模式启用及接口配置

这里开发语言使用的是java,推荐使用认证过的微信公众号或者是微信公众平台测试账号。测试账号登录申请请访问:http://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

一、开发环境的搭建

这里提供两种开发环境:
一是开发测试环境:

  1. 使用本地加算计作为服务器,安装好开发环境
  2. 通过内网穿透代理到外网上去,内网穿透可以使用花生壳等内网穿透工具。这里教大家一种免费的内网穿透工具:https://www.ngrok.cc

二是正式的运行部署环境:

  1. 购买云服务器,搭建好运行环境
  2. 备案审核通过的域名
  3. nginx服务器

二、查看服务器配置信息的介绍

登录微信公众平台官网后,进入到公众平台后台管理页面。
选择 公众号基本设置-》基本配置 ,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey。
微信公众号配置信息:
这里写图片描述
微信公众部分接口权限需要认证之后才能开通,开发阶段建议实现用微信公众平台测试账号。

测试账号配置信息:
这里写图片描述

可以看到需要的参数:

  1. URL:是开发者用来接收微信消息和事件 的接口URL。(必须以http://开头,目前支持80端口)
  2. Token:可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。注意必须为英文或数字,长度为3-32字符。
  3. EncodingAESKey:由开发者手动填写或随机生成,将用作消息体加解密密钥。(消息加密密钥由43位字符组成,可随机修改,字符范围为A-Z,a-z,0-9。)
    同时,开发者可选择消息加解密方式:明文模式、兼容模式和安全模式:
  4. 明文模式:不使用消息体加解密功能,安全系数较低
  5. 兼容模式:明文、密文将共存,方便开发者调试和维护
  6. 安全模式:消息包为纯密文,需要开发者加密和解密,安全系数高

三、服务器开发

查看微信公众号开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432
在入门指引查看验证消息需要的参数,开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

参数          描述
signature   微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp  
            参数、nonce参数。
timestamp   时间戳
nonce       随机数
echostr     随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
下面就可以进行开发了:
首先创建一个web工程,博主使用的是SpringBoot框架,大家随意。
springboot项目启动类

package cc.feefox.wechat;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

控制类

package cc.feefox.wechat.main;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;

/**
 * 
 * @Package: cc.feefox.wechat.main 
 * @author: cc   
 * @date: 2018年8月18日 下午12:17:55
 */
public class BaseController {

    protected static final String _CSRF_RANDOM_TOKEN = "_CSRF_RANDOM_TOKEN";

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private HttpServletResponse response;


    public HttpServletRequest getRequest() {
        return request;
    }

    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    public HttpServletResponse getResponse() {
        return response;
    }

    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }

}
package cc.feefox.wechat.main;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import cc.feefox.wechat.common.util.SignatureUtil;

/**
 * 微信消息入口
 * 
 * @Package: cc.feefox.wechat.main
 * @author: cc
 * @date: 2018年8月18日 下午12:18:39
 */
@RestController
@RequestMapping("/wechat")
public class WeChatController extends BaseController {

    private static final Logger logger = LoggerFactory.getLogger(WeChatController.class);

    /**
     * 校验信息是否是从微信服务器发出,处理消息
     * 
     * @param request
     * @param out
     * @throws IOException
     */
    @RequestMapping(value = "/handler", method = { RequestMethod.GET, RequestMethod.POST })
    public void processPost() throws Exception {

        this.getRequest().setCharacterEncoding("UTF-8");
        this.getResponse().setCharacterEncoding("UTF-8");

        logger.info("开始校验信息是否是从微信服务器发出");

        // 签名
        String signature = this.getRequest().getParameter("signature");
        // 时间戳
        String timestamp = this.getRequest().getParameter("timestamp");
        // 随机数
        String nonce = this.getRequest().getParameter("nonce");
        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败

        if (SignatureUtil.checkSignature(signature, timestamp, nonce)) {
            // 随机字符串
            String echostr = this.getRequest().getParameter("echostr");
            logger.debug("接入成功,echostr {}", echostr);
            this.getResponse().getWriter().write(echostr);
        }
    }
}

签名验证

package cc.feefox.wechat.common.util;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import cc.feefox.wechat.common.constant.WechatConstant;

/**
 * 校验签名工具类
 * @Package: cc.feefox.wechat.common.util 
 * @author: cc   
 * @date: 2018年8月18日 下午12:17:19
 */
public class SignatureUtil {

    // 此处的token即为微信接口配置填写的签名
    private static final String TOKEN = "weixin";

    /**
     * 验证签名
     * @param signature
     * @param timestamp
     * @param nonce
     * @return
     */
    public static boolean checkSignature(String signature, String timestamp, String nonce) {

        // 1.将token、timestamp、nonce三个参数进行字典序排序
        String[] arr = new String[] { TOKEN, timestamp, nonce };
        Arrays.sort(arr);

        // 2. 将三个参数字符串拼接成一个字符串进行sha1加密
        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 = byteToStr(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }

        content = null;
        // 3.将sha1加密后的字符串可与signature对比,标识该请求来源于微信
        Boolean asd = tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
        return asd;
    }

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

    /**
     * 将字节转换为十六进制字符串
     * 
     * @param mByte
     * @return
     */
    private static String byteToHexStr(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];
        return new String(tempArr);
    }

}

三、接口配置

这里写图片描述
URL: http://域名:80/wechat/handler 或者是https://域名:443/wechat/handler
TOKEN:weixin 与SignatureUtil类中定义的TOKEN常量一致。

启动服务点击提交

如有错漏请指出,欢迎加群 581817132
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值