事后巴菲特 發表於 2020-8-20 17:32:00

Spring Boot 微信公众号开发(一)

<h2 id="一接入概述">一、接入概述</h2>
<p>进行微信公众号开发,进行服务器配置是必不可少的,通过配置,公众号粉丝与公众号交互的消息将发送至开发者服务器,开发者对消息进行处理,例如:配置后,用户关注公众号或取关时,消息将发送至开发者配置的URL上,开发者即可根据事件类型进行处理,并且,开发者可获取用户openid、unionid,给粉丝发送模板消息等。</p>
<p>接入微信公众平台开发,开发者需要按照如下步骤完成:</p>
<p>1、填写服务器配置</p>
<p>2、验证服务器地址的有效性</p>
<p>3、依据接口文档实现业务逻辑</p>
<h2 id="二实现">二、实现</h2>
<h3 id="1配置">1、配置</h3>
<p><strong>1.配置入口:微信公众号官网 -&gt; 基本配置</strong><br>
<img src="https://img2020.cnblogs.com/blog/1694537/202008/1694537-20200820173307737-219402896.png" alt="" loading="lazy"></p>
<p><strong>2.点击修改配置</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1694537/202008/1694537-20200820173323168-1120463896.png" alt="" loading="lazy"></p>
<p><strong>3.填写参数</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1694537/202008/1694537-20200820173341941-675052927.png" alt="" loading="lazy"></p>
<h3 id="2代码">2、代码</h3>
<p><strong>1.工具类</strong>,校验token工具类,此处的token要和服务器配置里的token保持一致:</p>
<pre><code class="language-java">

/**
* @author yh
* @date 2020/8/20 16:05
* @description: token验证工具类
*/
public class SignUtil {
    //与服务器保持一致
    private static String token = "*********";

   /**
    * @author: yh
    * @description: 校验签名
    * @date: 2020/8/20
    * @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
    * @param timestamp 时间戳
    * @param nonce 随机数
    * @return boolean
    **/
    public static boolean checkSignature(String signature,String timestamp,String nonce){
      String checkText = null;
      if (null != signature) {
            //对ToKen,timestamp,nonce 按字典排序
            String[] paramArr = new String[]{token,timestamp,nonce};
            Arrays.sort(paramArr);
            //将排序后的结果拼成一个字符串
            String content = paramArr.concat(paramArr).concat(paramArr);

            try {
                MessageDigest md = MessageDigest.getInstance("SHA-1");
                //对接后的字符串进行sha1加密
                byte[] digest = md.digest(content.toString().getBytes());

                checkText = byteToStr(digest);
            } catch (NoSuchAlgorithmException e){
                e.printStackTrace();
            }
      }
      //将加密后的字符串与signature进行对比
      return checkText != null ? checkText.equals(signature.toUpperCase()) : false;
    }

    /**
   * @author: yh
   * @description: 将字节数组转化我16进制字符串
   * @date: 2020/8/20
   * @param byteArrays 字符数组
   * @return java.lang.String
   **/
    private static String byteToStr(byte[] byteArrays){
      String str = "";
      for (int i = 0; i &lt; byteArrays.length; i++) {
            str += byteToHexStr(byteArrays);
      }
      return str;
    }

   /**
    * @author: yh
    * @description: 将字节转化为十六进制字符串
    * @date: 2020/8/20
    * @param myByte 字节
    * @return java.lang.String
    **/
    private static String byteToHexStr(byte myByte) {
      char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
      char[] tampArr = new char;
      tampArr = Digit[(myByte &gt;&gt;&gt; 4) &amp; 0X0F];
      tampArr = Digit;
      String str = new String(tampArr);
      return str;
    }

}

</code></pre>
<p><strong>2.接口路径</strong></p>
<p>api包</p>
<pre><code class="language-java">
/**
* @author yh
* @date 2020/8/20 16:13
* @description:
*/
@RequestMapping("/WeChatApi")
public interface WeChatApi {
    /**
   * @author: yh
   * @description: token验证
   * @date: 2020/8/20
   * @param request
   * @return void
   **/
    @GetMapping("/checkToken")
    String checkToken(HttpServletRequest request);
}

</code></pre>
<p>controller:</p>
<pre><code class="language-java">
/**
* @author yh
* @date 2020/8/20 16:15
* @description:
*/
@RestController
@Slf4j
public class WeChatController implements WeChatApi {
    /**
   * @author: yh
   * @description:
   * @date: 2020/8/20
   * @param request
   * @return void
   **/
    @Override
    public String checkToken(HttpServletRequest request) {
      String signature = request.getParameter("signature");
      String timestamp = request.getParameter("timestamp");
      String nonce = request.getParameter("nonce");
      String echostr = request.getParameter("echostr");
      log.info("signature[{}], timestamp[{}], nonce[{}], echostr[{}]", signature, timestamp, nonce, echostr);
      if(SignUtil.checkSignature(signature, timestamp, nonce)){
            log.info("数据源为微信后台,将echostr[{}]返回!", echostr);
            return echostr;
      }
      return "";
    }
}

</code></pre>
<p><strong>3.提交</strong></p>
<p>点击配置图中的·<strong>提交</strong>·按钮,并测试</p>
<h3 id="3常见问题">3、常见问题</h3>
<p>​    最常见的问题就是提示token验证失败了,token验证失败可能是接口访问不到,也可能是接口内代码校验失败,注意检查<strong>token</strong>与代码中是否一致。如果代码确认无误,只需保证接口可以访问到就可以了,所以可以先在浏览器中输入URL,看服务器是否可以打印日志。</p><br><br>
来源:https://www.cnblogs.com/yyanghang/p/13536363.html
頁: [1]
查看完整版本: Spring Boot 微信公众号开发(一)