第三篇:微信公众平台开发Java版之接入开发者

微信开发者接入官方文档 : https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319

一、微信公共号通讯机制

作为开发者,我们需要面对的主要有两个对象:微信服务器和应用程序(网站)服务器。 
当微信用户向你的公众平台发送一条消息,实际上这条消息首先发送到微信服务器,由微信服务器向网站服务器(我们开发的后台服务)发起另外一个请求,网站服务器返回这个请求的结果,再由微信服务器发送到微信客户端。

整个消息通讯流程如下图: 
这里写图片描述

具体请求流程见下图:




二、 外网映射工具(开发调试)

1、 外网映射工具

微信公众平台在访问后台时必须提供能够正确访问的外网地址,因为我们在本地开发,IP:127.0.0.1 ,所以要通过内网穿透,提供给外网的微信公众平台正确访问,微信平台对后台URL的要求有两点:

① 必须能够用公网访问    ② 必须使用80端口

方式:通过免费的映射工具。

(1)natapp  

官网 :https://natapp.cn/

 

(2)ngrok

 

官网:https://www.ngrok.cc/

 

(3)nat123

官网:http://www.nat123.com/


(4)花生壳

花生壳服务网址:价格地址直达地址

使用花生壳外网映射的可以参考这篇博客:http://www.souvc.com/?p=2272   


2、我这里选择的是ngrok外网映射工具  

使用ngrok:

(1)、ngrok下载: 链接:https://pan.baidu.com/s/1PeVRF2lfNoQYro3YJW_7JQ 密码:s7bm


(2)、 进入ngrok安装文件所在的目录执行:ngrok -config ngrok.cfg -subdomain mywx 8080,之后出现如下图说明配置成功。(成功的前提是本地服务已经部署到Tomcat并且正常开启,访问本地服务正常)
    a. ngrok所在目录

  

b、切换到该目录下执行上述命令


c、本地服务映射成到外网成功效果图




二、填写服务器配置信息的介绍


1、登录微信公众平台官网后,进入到公众平台后台管理页面。

选择 公众号基本设置-》基本配置 ,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey。

 

微信公众号配置界面:

 

 

服务器配置:

  URL:是开发者用来接收微信消息和事件 的接口URL。(http://公网地址/项目名称/请求路径

  Token:可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。注意必须为英文或数字,长度为3-32字符,在校验的时候需要用到,随便输入一个字符串就可以了。

  EncodingAESKey:由开发者手动填写或随机生成,将用作消息体加解密密钥。(消息加密密钥由43位字符组成,可随机修改,字符范围为A-Z,a-z,0-9。)

     开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数 
    参数 描述 
    signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 
    timestamp 时间戳 
    nonce 随机数 

   echostr 随机字符串

 


2、编写相应的Controller(采用spring MVC)

package com.thinkgem.jeesite.modules.app.api;

import java.io.IOException;
import java.security.MessageDigest;
import java.util.ArrayList;
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.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 
 * @ClassName: WeiXinController
 * @Description: TODO(对微信请求校验,成为开发者)
 * @author CaoWenCao
 * @date 2018年6月6日 下午2:09:38
 */
@Controller
@RequestMapping(value = "weixin")
public class WeiXinController {

    private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

    @RequestMapping(value = "getWeiXinMethod", method = RequestMethod.GET)
    @ResponseBody
    public void getWeiXinMethod(HttpServletRequest request, HttpServletResponse response) throws IOException {
        boolean validate = validate(request);
        if (validate) {
            response.getWriter().write(request.getParameter("echostr"));
            response.getWriter().close();
        }

    }

    private boolean validate(HttpServletRequest req) throws IOException {
        String signature = req.getParameter("signature");// 微信加密签名
        String timestamp = req.getParameter("timestamp");// 时间戳
        String nonce = req.getParameter("nonce");// 随机数
        List<String> list = new ArrayList<String>();
        list.add("caowencao");
        list.add(timestamp);
        list.add(nonce);
        Collections.sort(list);// 字典排序
        String str = "";
        for (int i = 0; i < list.size(); i++) {
            str += (String) list.get(i);
        }
        if (encode("SHA1", str).equalsIgnoreCase(signature)) {
            return true;
        }
        else {
            return false;
        }
    }

    public static String encode(String algorithm, String str) {
        if (str == null) {
            return null;
        }
        try {
            // Java自带的加密类
            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
            // 转为byte
            messageDigest.update(str.getBytes());
            return getFormattedText(messageDigest.digest());
        }
        catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static String getFormattedText(byte[] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder(len * 2);
        // 把密文转换成十六进制的字符串形式
        for (int j = 0; j < len; j++) {
            buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
            buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
        }
        return buf.toString();
    }
}
3、点击提交按钮,此时验证和调用没问题,已经成功接入开发者模式。



猜你喜欢

转载自blog.csdn.net/thinkingcao/article/details/80596199