请记住,你是否拥有完整的微信公众号权限!
    请记住,你是否拥有完整的微信公众号权限!
    请记住,你是否拥有完整的微信公众号权限!

    这是一个血淋淋的教训,自己开发完了。然后数据不及预期。从周五周六晚上排查 一共10个小时。

    票据接入方案JAVA版本

    1. package com.murphyyi.wechat.manger;
    2. import cn.hutool.http.HttpUtil;
    3. import com.alibaba.fastjson.JSON;
    4. import com.murphyyi.wechat.bean.vo.WechatTicketVO;
    5. import com.murphyyi.wechat.bean.vo.WechatTokenVO;
    6. import org.springframework.data.redis.core.RedisTemplate;
    7. import org.springframework.stereotype.Service;
    8. import javax.annotation.Resource;
    9. import java.util.HashMap;
    10. import java.util.Map;
    11. import java.util.concurrent.TimeUnit;
    12. import static com.murphyyi.wechat.utils.RandomString.SHA1;
    13. import static com.murphyyi.wechat.utils.RandomString.getRandomStringByLength;
    14. @Service
    15. public class WechatConfig {
    16. @Resource
    17. RedisTemplate<Object, Object> redisTemplate;
    18. public Map<String, Object> jsAPI(String appId,String appSecret,String url){
    19. String noncestr = getRandomStringByLength(32);
    20. String jsapiTicket = null;
    21. try {
    22. jsapiTicket = getJsapiTicket(appId,appSecret);
    23. } catch (InterruptedException e) {
    24. e.printStackTrace();
    25. }
    26. String timestamp = String.valueOf(System.currentTimeMillis()).substring(0,10);
    27. String str = "jsapi_ticket="+jsapiTicket+"&noncestr="+noncestr+"&timestamp="+timestamp+"&url="+url;
    28. Map<String, Object> map = new HashMap<>();
    29. map.put("appId",appId);
    30. map.put("timestamp",timestamp);
    31. map.put("nonceStr",noncestr);
    32. map.put("signature",SHA1(str));
    33. map.put("jsticket",jsapiTicket);
    34. map.put("url",url);
    35. return map;
    36. }
    37. private String getJsapiTicket(String appId,String appSecret) throws InterruptedException {
    38. Object obj =redisTemplate.opsForValue().get(appId+appSecret+"TICKET");
    39. String ticket = null;
    40. if(obj!=null){
    41. ticket = obj.toString();
    42. }
    43. while (null == ticket){
    44. Map<String, Object> data = new HashMap<>();
    45. data.put("access_token",getAccessToken(appId,appSecret));
    46. data.put("type","jsapi");
    47. String result = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/ticket/getticket",data);
    48. WechatTicketVO wechatTicketVO = JSON.parseObject(result, WechatTicketVO.class);
    49. if(wechatTicketVO.getTicket()!=null){
    50. redisTemplate.opsForValue().set(appId+appSecret+"TICKET", wechatTicketVO.getTicket(), 7200, TimeUnit.SECONDS);
    51. break;
    52. }
    53. Thread.sleep(3000);
    54. }
    55. return ticket;
    56. }
    57. private String getAccessToken(String appId,String appSecret) throws InterruptedException {
    58. Object obj =redisTemplate.opsForValue().get(appId+appSecret+"TOKEN");
    59. String token = null;
    60. if(obj!=null){
    61. token = obj.toString();
    62. }
    63. while (token==null){
    64. Map<String, Object> data = new HashMap<>();
    65. data.put("grant_type","client_credential");
    66. data.put("appid",appId);
    67. data.put("secret",appSecret);
    68. String result = HttpUtil.get("https://api.weixin.qq.com/cgi-bin/token", data);
    69. WechatTokenVO wechatTokenVO = JSON.parseObject(result, WechatTokenVO.class);
    70. if(wechatTokenVO.getAccess_token()!=null) {
    71. token = wechatTokenVO.getAccess_token();
    72. redisTemplate.opsForValue().set(appId + appSecret + "TOKEN", wechatTokenVO.getAccess_token(), 7200, TimeUnit.SECONDS);
    73. break;
    74. }
    75. Thread.sleep(3000);
    76. }
    77. return token;
    78. }
    79. }

    SHA1加密

    1. package com.murphyyi.wechat.utils;
    2. import java.security.MessageDigest;
    3. import java.security.NoSuchAlgorithmException;
    4. import java.util.Random;
    5. public class RandomString {
    6. //可以指定字符串的某个位置是什么范围的值
    7. public static String getRandomStringByLength(int length){
    8. Random random=new Random();
    9. StringBuffer sb=new StringBuffer();
    10. for(int i=0;i<length;i++){
    11. int number=random.nextInt(3);
    12. long result=0;
    13. switch(number){
    14. case 0:
    15. result=Math.round(Math.random()*25+65);
    16. sb.append(String.valueOf((char)result));
    17. break;
    18. case 1:
    19. result=Math.round(Math.random()*25+97);
    20. sb.append(String.valueOf((char)result));
    21. break;
    22. case 2:
    23. sb.append(String.valueOf(new Random().nextInt(10)));
    24. break;
    25. }
    26. }
    27. return sb.toString();
    28. }
    29. public static String SHA1(String decript) {
    30. try {
    31. MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");
    32. digest.update(decript.getBytes());
    33. byte messageDigest[] = digest.digest();
    34. // Create Hex String
    35. StringBuffer hexString = new StringBuffer();
    36. // 字节数组转换为 十六进制 数
    37. for (byte b : messageDigest) {
    38. String shaHex = Integer.toHexString(b & 0xFF);
    39. if (shaHex.length() < 2) {
    40. hexString.append(0);
    41. }
    42. hexString.append(shaHex);
    43. }
    44. return hexString.toString();
    45. } catch (NoSuchAlgorithmException e) {
    46. e.printStackTrace();
    47. }
    48. return "";
    49. }
    50. }

    VO

    1. package com.murphyyi.wechat.bean.vo;
    2. import lombok.AllArgsConstructor;
    3. import lombok.Data;
    4. import lombok.NoArgsConstructor;
    5. @Data
    6. @AllArgsConstructor
    7. @NoArgsConstructor
    8. public class WechatTicketVO {
    9. Integer errcode;
    10. String errmsg;
    11. String ticket;
    12. Integer expirs_in;
    13. }
    14. package com.murphyyi.wechat.bean.vo;
    15. import lombok.AllArgsConstructor;
    16. import lombok.Data;
    17. import lombok.NoArgsConstructor;
    18. @Data
    19. @AllArgsConstructor
    20. @NoArgsConstructor
    21. public class WechatTokenVO {
    22. Integer errcode;
    23. String errmsg;
    24. String access_token;
    25. Integer expirs_in;
    26. }

    Golang方案待完成