查看原文观看视频:http://www.ibloger.net/article/272.html
官方PHP接入文件注释介绍
- <?php
- /**
- * wechat php test 表明php语句的说明和开始,表示此为php语言
- */
- // 定义 token
- define("TOKEN", "weixin");
- $wechatObj = new wechatCallbackapiTest(); // 实例化当前class类
- $wechatObj->valid(); // $webchatObj变量—>访问类中valid()方法
- class wechatCallbackapiTest // 定义一个类,类名是class后的内容
- {
- public function valid() // 定义一个共有的名为valid的方法
- {
- $echoStr = $_GET["echostr"]; // 从微信用户获取一个随机变量$echoStr
- //验证签名signature , 可选
- if($this->checkSignature()){
- echo $echoStr; // 如果签名相同,输出$echostr变量
- exit;
- }
- }
- public function responseMsg() // 以下是一个公有的responseMsg的方法,是这段代码的核心内容,获得微信用户段发来的信息,不同环境有所不同
- {
- //get post 数据, 可能是由于不同的环境
- $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; // 将信息保存到变量$postStr中,同时解析用户数据
- //提取post数据
- if (!empty($postStr)){ // 如果用户端数据不为空
- /* libxml_disable_entity_loader是防止XML外部实体注入,最好的办法就是自己检查XML的有效性 */
- libxml_disable_entity_loader(true);
- $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); // 将变量$postStr解析并赋予变量$postObj
- $fromUsername = $postObj->FromUserName; // 将用户端的用户名赋予变量$fromUsername
- $toUsername = $postObj->ToUserName; // 将公众号ID赋予变量$toUsername
- $keyword = trim($postObj->Content); // 将发来的文本内容去空格后赋予变量$keyword
- $time = time(); // 将系统时间赋予变量$time
- // 构建XML格式的文本赋予变量$textTp1(ToUserName:微信目标方,FromUserName:微信来远方,CreateTime:系统时间,MsgType:回复微信信息类型,Content:回复微信内容,FuncFlag:是否为星标微信)
- $textTpl = "<xml>
- <ToUserName><![CDATA[%s]]></ToUserName>
- <FromUserName><![CDATA[%s]]></FromUserName>
- <CreateTime>%s</CreateTime>
- <MsgType><![CDATA[%s]]></MsgType>
- <Content><![CDATA[%s]]></Content>
- <FuncFlag>0</FuncFlag>
- </xml>";
- if(!empty( $keyword )) { // 如果用户端发来的消息不是空
- $msgType = "text"; // 回复文本消息为text文本类型
- $contentStr = "欢迎来到 wechat 世界!"; // 这行就是我们进行文本回复的内容,如果要改回复的消息,只要在这里更改就可以
- $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); // 将XML格式中的变量分别赋值,
- echo $resultStr; // 输出回复消息
- }else{
- echo "Input something..."; // 输入内容,此消息不会发送到微信端,只是测试时候使用
- }
- }else {
- echo "";
- exit;
- }
- }
- private function checkSignature() // 建立私有方法验证签名
- {
- // 你必须定义一个自己的TOKEN
- if (!defined("TOKEN")) {
- throw new Exception('TOKEN 未定义!');
- }
- $signature = $_GET["signature"]; // 从用户端获取签名赋予变量$signature
- $timestamp = $_GET["timestamp"]; // 从用户段获取时间赋予变量$timestamp
- $nonce = $_GET["nonce"]; // 从用户段获取随机数赋予变量$snonce
- $token = TOKEN; // 将常量TOKEN值赋予变量$token
- $tmpArr = array($token, $timestamp, $nonce); // 建立数组变量$tmpArr
- sort($tmpArr, SORT_STRING); // 数组排序
- $tmpStr = implode( $tmpArr ); // 字典排序
- $tmpStr = sha1( $tmpStr ); // 加密
- if( $tmpStr == $signature ){ // 判断$tmpStr与$signature变量是否同值
- return true;
- }else{
- return false;
- }
- }
- }
- ?>
微信请求校验类
- package cn.weixin.validationTest;
- import java.security.MessageDigest;
- import java.util.Arrays;
- /**
- * 微信请求校验工具类
- * @author X-rapido
- * @version 1.0
- */
- public class ValidationUtil{
- private static String token="Rapido"; // 用户Token
- /**
- * 验证签名
- */
- public static boolean checkSignauer(String signature,String timestamp,String nonce){
- // 构建成一个字符串数组
- String [] str = new String[]{token,timestamp,nonce};
- Arrays.sort(str); // 排序
- StringBuffer buff = new StringBuffer();
- for (int i = 0; i < str.length; i++) {
- buff.append(str[i]);
- }
- MessageDigest md = null; // 加密类
- String result = null;
- try {
- md = MessageDigest.getInstance("SHA-1"); // 实例加密算法(微信文档中用SHA-1)
- byte[] digest = md.digest(buff.toString().getBytes());
- result = bytesToStr(digest);
- System.out.println("加密以后的字符串:"+result);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return result != null? result.equals(signature.toUpperCase()) : false;
- }
- /**
- * 将字节数组转换为16进制字符串
- * @param byteArray
- * @return
- */
- private static String bytesToStr(byte[] byteArray){
- String strDigest = "";
- for (int i = 0; i < byteArray.length; i++) {
- strDigest += byteToHexStr(byteArray[i]);
- }
- return strDigest;
- }
- /**
- * 将一个字节转换为16进制字符串
- * @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 [] temp = new char[2];
- temp[0] = digit[(mByte>>>4) & 0X0F];
- temp[1] = digit[mByte & 0X0F];
- String s = new String(temp);
- return s;
- }
- }
微信测试接入类
- package cn.weixin.servlet;
- 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;
- import cn.weixin.common.ValidationUtil;
- /**
- * 接收来自微信服务器转发过来的请求[验证消息真实性]
- *
- * @author X-rapido
- *
- */
- public class AccessVerifyServlet extends HttpServlet {
- public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- String signature = request.getParameter("signature"); // 获取微信加密的签名字符串
- String timestamp = request.getParameter("timestamp"); // 时间戳
- String nonce = request.getParameter("nonce"); // 随机数
- String echostr = request.getParameter("echostr"); // 随机字符串
- System.out.println("加密的签名串signatur:"+signature+",时间戳timestamp:"+timestamp+",随机数nonce:"+nonce+",随机字符串echostr:"+echostr);
- PrintWriter out = response.getWriter();
- if(ValidationUtil.checkSignauer(signature, timestamp, nonce)){
- out.print(echostr);
- }
- out.close();
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
- doGet(request, response);
- }
- }
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
- <display-name>weixin</display-name>
- <distributable/>
- <welcome-file-list>
- <welcome-file>index.html</welcome-file>
- <welcome-file>index.htm</welcome-file>
- <welcome-file>index.jsp</welcome-file>
- </welcome-file-list>
- <servlet>
- <description>微信接入验证</description>
- <servlet-name>AccessVerifyServlet</servlet-name>
- <servlet-class>cn.weixin.servlet.AccessVerifyServlet</servlet-class>
- </servlet>
- <servlet-mapping>
- <servlet-name>AccessVerifyServlet</servlet-name>
- <url-pattern>/AccessVerifyServlet</url-pattern>
- </servlet-mapping>
- </web-app>
微信在接入时候,会以get数据请求我的url地址,我的Servlet就会接收数据,并进行签名认证返回接收的随机数,微信服务器接收随机数并进行签名认证,确定后就接入成功!