微信硬件蓝牙开发教程之公众平台接入应用项目

2018年05月17日 08:36 | 89次浏览 | 分类: 微信硬件蓝牙开发教程03版 作者原创 版权保护

其实公众平台开发文档已经说的很明白了,也有接入指南,不过案例是php的,地址https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319,在这里呢,我用java程序做个案例,供大家参考学习。

一、接入指南

接入概述

接入微信公众平台开发,开发者需要按照如下步骤完成:

1、填写服务器配置

2、验证服务器地址的有效性

3、依据接口文档实现业务逻辑

下面详细介绍这3个步骤。


第一步:填写服务器配置

登录微信公众平台官网后,在公众平台官网的开发-基本设置页面,勾选协议成为开发者,点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey,其中URL是开发者用来接收微信消息和事件的接口URL。Token可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。EncodingAESKey由开发者手动填写或随机生成,将用作消息体加解密密钥。


同时,开发者可选择消息加解密方式:明文模式、兼容模式和安全模式。模式的选择与服务器配置在提交后都会立即生效,请开发者谨慎填写及选择。加解密方式的默认状态为明文模式,选择兼容模式和安全模式需要提前配置好相关加解密代码,详情请参考消息体签名及加解密部分的文档

笔者注:很多初学的读者还是不理解这个URL 和Token ,例如我们的服务器IP100.156.168.101,我们的java项目为weChat,然后新建一个servlet为WeChatServlet,那么我们在这里填写的url为http://100.156.168.101/weChat/weChatServlet。当然controller方法也可以的,token的值是下面代码中的"weixintest",要保持一致。

第二步:验证消息的确来自微信服务器

开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

参数 描述

signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。

timestamp 时间戳

nonce 随机数

echostr 随机字符串

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:

1)将token、timestamp、nonce三个参数进行字典序排序

2)将三个参数字符串拼接成一个字符串进行sha1加密 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信

检验signature的java示例代码:一定要支持get请求

/**
	 * 确认请求来自微信服务器
	 */
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		logger.info("确认请求来自微信服务器");
		
		// 微信加密签名
		String signature = request.getParameter("signature");
		logger.info("微信加密签名-----------------------"+signature);
		// 时间戳
		String timestamp = request.getParameter("timestamp");
		
		// 随机数
		String nonce = request.getParameter("nonce");
		
		// 随机字符串
		String echostr = request.getParameter("echostr");
		
		
		PrintWriter out = response.getWriter();
		// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
		if (SignUtil.checkSignature("weixintest", signature, timestamp, nonce)) {
			
			out.print(echostr);
			//System.out.println("这是:"+echostr);
		}
		out.close();
		out = null;
	}

注意上述代码中的"weixintest"这个值,会在公众平台上配置

SignUtil代码如下:

/**
* 请求校验工具类  www.vxzsk.com
*/
public class SignUtil {
		
	/**
	* 验证签名
	* 
	* @param signature
	* @param timestamp
	* @param nonce
	* @return
	*/
	public static boolean checkSignature(String token, 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 = byteToStr(digest);
		} catch (NoSuchAlgorithmException e) {
		e.printStackTrace();
		}
		content = null;
		// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
		return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
	}
	/**
	* 将字节数组转换为十六进制字符串	
	* @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];
		String s = new String(tempArr);
		return s;
	}
	
}


二、接入实战

新建一个web Project项目 名字叫weChat

然后新建一个servlet类 名字叫 WeChatServlet

Web.xml的servlet配置

1
2
3
4
5
6
7
8
9
10
<servlet>
    <description>This is the description of my J2EE component</description>
    <display-name>This is the display name of my J2EE component</display-name>
    <servlet-name>WeChatServlet</servlet-name>
    <servlet-class>com.test.WeChatServlet</servlet-class>
  </servlet>
<servlet-mapping>
    <servlet-name>WeChatServlet</servlet-name>
    <url-pattern>/weChatServlet</url-pattern>
  </servlet-mapping>

WeChatServlet代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package com.test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * 核心请求处理类
 */
public class WeChatServlet extends HttpServlet {
    private static final long serialVersionUID = 1508798736675904038L;
    /**
     * 确认请求来自微信服务器
     */
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 微信加密签名
        String signature = request.getParameter("signature");
        System.out.println("微信加密签名signature:-----------------------"+signature);
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        System.out.println("时间戳timestamp:-----------------------"+timestamp);
        // 随机数
        String nonce = request.getParameter("nonce");
        System.out.println("随机数nonce:-----------------------"+nonce);
        // 随机字符串
        String echostr = request.getParameter("echostr");
        System.out.println("随机字符串echostr:-----------------------"+echostr);
        //System.out.println("token-----------------------:"+token);
         
        PrintWriter out = response.getWriter();
        // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
        if (SignUtil.checkSignature("weixinTest", signature, timestamp, nonce)) {
            out.print(echostr);
            //System.out.println("这是:"+echostr);
        }
        out.close();
        out = null;
    }
/**
     * 处理微信服务器发来的消息
     */
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
}}

在这里 有个验签的工具类SignUtil其中第一个参数就是我们刚才所说的Token “weixinTest”,工具类代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package com.test;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* 请求校验工具
*/
public class SignUtil {
        /**
    * 验证签名
    
    * @param signature
    * @param timestamp
    * @param nonce
    * @return
    */
    public static boolean checkSignature(String token, 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 = byteToStr(digest);
        catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
        }
        content = null;
        // 将sha1加密后的字符串可与signature对比,标识该请求来源于微 ?
        return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
    }
    /**
    * 将字节数组转换为十六进制字符 ?
    * @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];
        String s = new String(tempArr);
        return s;
    }
    public static void main(String[] args) {
        }}

代码写完了接下来就是把项目部署到linux服务器上,打开FTP工具,登录服务器把编译后的项目上传到服务器tomat的webapps下

打开xshell,登录服务器,如果tomcat启动,停止tomcat,然后重新启动,启动命令为:

1
2
# cd /usr/local/apache-tomcat-7.0.2/bin
#./startup.sh

查看项目运行日志:

1
#tail –f /usr/local/apache-tomcat-7.0.2/logs/catalina.out

刚才我们在servlet中四个参数的输出打印,由于现在还未配置URL和token 所以并未有打印。

接下来我们配置URL和token

进入公众平台管理中心点击左下角 开发-基本配置—服务器配置,输入URL和token

由于我的服务器地址为100.156.168.101(域名也可以) 读者可根据自己服务器更换成自己的ip地址 URL: http://100.156.168.101/weChat/weChatServlet  token:weixinTest  在这里提醒下我们的weChatServlet中验签第一个参数为token的值“weixinTest”, EncodingAESKey点击后面随机生成按钮即可,消息加密方式选择明文模式,点击提交(保证项目已经运行的情况下不然会失败)。

然后我们查看xshell打印输出日志会发现服务器已经有我们的输出了

好了到现在我们接入微信就算已经成功了,如果提交提示失败,有可能如下几个原因:

1,URL配置不正确

2,servlet代码不正确

3,servlet代码中的token值和微信配置的不一致

4,项目并未运行在80端口

5,检验signature的工具类代码不正确。

6,服务器的tomcat未启动(我在这里用的tomcat 你也可以用其它web容器

7,servlet请求路径错误


此文章本站原创,地址 http://www.vxzsk.com/1783.html   转载请注明出处!谢谢!

感觉本站内容不错,读后有收获?小额赞助,鼓励网站分享出更好的教程