一 首先实现内网穿透,公众号需要连接我们的服务器,内外无法访问,所以先实现自己的内网可以测试时连接外网,下载natapp,选择windows,顺便下载config,ini 配置文件。注册好购买免费的隧道 然后将token写入配置文件中,操作很简单,windows中需要加入环境变量,因为我直接放到D盘的natapp文件夹中,所以路劲为D:\natapp即可,双击.exe 就能启动   http://phxgaj.natappfree.cc -> 127.0.0.1:90  通过前面的网址phxgaj.natappfree.cc 访问就能连接我们自己的内网环境了。

二 自然是注册微信公众号了,注册的时候要瞪大眼睛了,微信公众平台 微信开发平台 服务号订阅号小程序一定要分清楚,一个邮箱只能注册一个功能,所以要慎重选,我注册的是 微信公众平台的 服务号,适合公司使用

三 公众号接入,在开发者配置中,写进这个方法,我用的是springmvc,所以要写到这个指定的路径

   import java.io.IOException;5 import java.io.UnsupportedEncodingException;6 import java.security.MessageDigest;7 import java.security.NoSuchAlgorithmException;8 import java.util.Arrays;9 import java.util.Map; 10 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 13 14 import org.slf4j.Logger; 15 import org.slf4j.LoggerFactory; 16 import org.springframework.beans.BeansException; 17 import org.springframework.context.ApplicationContext; 18 import org.springframework.context.ApplicationContextAware; 19 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Controller; 21 import org.springframework.web.bind.annotation.RequestMapping; 22 import org.springframework.web.bind.annotation.RequestMethod; 23 24 import com.alibaba.fastjson.JSON; 25 import com.alibaba.fastjson.JSONObject; 26 import com.fuyin.mp.entity.AccessToken; 27 import com.fuyin.mp.utils.GetMenuJson; 28 import com.fuyin.mp.utils.MessageHandlerUtil; 29 import com.fuyin.mp.utils.NetWorkHelper; 30 import com.fuyin.mp.utils.WxaApi; 31 @Controller 32 @RequestMapping("wxconnect.action") 33 public class WxBase { 34 private static final Logger logger = LoggerFactory.getLogger(WxBase.class); 35 /* 36 * 自定义token, 用作生成签名,从而验证安全性 37 * */ 38 private final String TOKEN = WxaApi.TOKEN; 39 /** 40 * 检验签名 41 * @param req 42 * @param res 43 */ 44 @RequestMapping(method = RequestMethod.GET) 45 public void wxconnect(HttpServletRequest req,HttpServletResponse res){ 46 logger.debug("-----开始校验签名-----"); 47 /** 48 * 接收微信服务器发送请求时传递过来的参数 49 */ 50 String signature = req.getParameter("signature"); 51 String timestamp = req.getParameter("timestamp"); 52 String nonce = req.getParameter("nonce"); //随机数 53 String echostr = req.getParameter("echostr");//随机字符串 54 55 /** 56 * 将token、timestamp、nonce三个参数进行字典序排序 57 * 并拼接为一个字符串 58 */ 59 String sortStr = sort(TOKEN,timestamp,nonce); 60 /** 61 * 字符串进行shal加密 62 */ 63 String mySignature = shal(sortStr); 64 /** 65 * 校验微信服务器传递过来的签名 和 加密后的字符串是否一致, 若一致则签名通过 66 */ 67 if(!"".equals(signature) && !"".equals(mySignature) && signature.equals(mySignature)){ 68 try { 69 logger.debug("-----签名校验通过-----"); 70  res.getWriter().write(echostr); 71 } catch (IOException e) { 72 // TODO Auto-generated catch block 73  e.printStackTrace(); 74  } 75 }else { 76 logger.debug("-----校验签名失败-----"); 77  } 78  } 79 @RequestMapping(method = RequestMethod.POST) 80 protected void doPost(HttpServletRequest request, HttpServletResponse response) { 81 // TODO 接收、处理、响应由微信服务器转发的用户发送给公众帐号的消息 82 // 将请求、响应的编码均设置为UTF-8(防止中文乱码) 83 try { 84 request.setCharacterEncoding("UTF-8"); 85 response.setCharacterEncoding("UTF-8"); 86 System.out.println("请求进入"); 87 String result = ""; 88 try { 89 Map<String,String> map = MessageHandlerUtil.parseXml(request); 90 System.out.println("开始构造消息"); 91 result = MessageHandlerUtil.buildResponseMessage(map, "你好"); 92  System.out.println(result); 93 if(result.equals("")){ 94 result = "未正确响应"; 95  } 96 } catch (Exception e) { 97  e.printStackTrace(); 98 System.out.println("发生异常:"+ e.getMessage()); 99  } 100  response.getWriter().write(result); 101 } catch (UnsupportedEncodingException e) { 102 // TODO Auto-generated catch block 103  e.printStackTrace(); 104 } catch (IOException e) { 105 // TODO Auto-generated catch block 106  e.printStackTrace(); 107  } 108  } 109 110 /** 111 * 参数排序 112 * @param token 113 * @param timestamp 114 * @param nonce 115 * @return 116 */ 117 public String sort(String token, String timestamp, String nonce) { 118 String[] strArray = {token, timestamp, nonce}; 119  Arrays.sort(strArray); 120 StringBuilder sb = new StringBuilder(); 121 for (String str : strArray) { 122  sb.append(str); 123  } 124 return sb.toString(); 125  } 126 127 /** 128 * 字符串进行shal加密 129 * @param str 130 * @return 131 */ 132 public String shal(String str){ 133 try { 134 MessageDigest digest = MessageDigest.getInstance("SHA-1"); 135  digest.update(str.getBytes()); 136 byte messageDigest[] = digest.digest(); 137 138 StringBuffer hexString = new StringBuffer(); 139 // 字节数组转换为 十六进制 数 140 for (int i = 0; i < messageDigest.length; i++) { 141 String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); 142 if (shaHex.length() < 2) { 143 hexString.append(0); 144  } 145  hexString.append(shaHex); 146  } 147 return hexString.toString(); 148 149 } catch (NoSuchAlgorithmException e) { 150  e.printStackTrace(); 151  } 152 return ""; 153  } 154 }

WxApi 这个是工具类,因为测试用的穿透所以一直要改Ip,干脆提取出来修改方便,上面代码是接入微信服务。

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.stereotype.Component; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.fuyin.mp.entity.AccessToken; import com.fuyin.mp.utils.GetMenuJson; import com.fuyin.mp.utils.NetWorkHelper; import com.fuyin.mp.utils.WxaApi; /** * 线程 自动获得token * @author Administrator * */ @Controller public class AccessTokenInit implements ApplicationContextAware{ private static final Logger logger = LoggerFactory.getLogger(AccessTokenInit.class); @Override public void setApplicationContext(ApplicationContext arg0) throws BeansException { new Thread(new Runnable() { @Override public void run() { while (true) { try { //获取accessToken System.out.println("开始获取TOKEN"); WxaApi.accessToken = getAccessToken(WxaApi.appID, WxaApi.appsecret); //获取成功 if ( WxaApi.accessToken== null) { //获取失败 Thread.sleep(1000 * 3); //获取的access_token为空 休眠3秒 } else { //获取到access_token 休眠7000秒,大约2个小时左右 Thread.sleep(7000 * 1000); //Thread.sleep(10 * 1000);//10秒钟获取一次  } } catch (Exception e) { System.out.println("发生异常:" + e.getMessage()); e.printStackTrace(); try { Thread.sleep(1000 * 10); //发生异常休眠1秒 } catch (Exception e1) { } } } } }).start(); } /** * 获取access_token * * @return AccessToken */ private AccessToken getAccessToken(String appId, String appSecret) { NetWorkHelper netHelper = new NetWorkHelper(); String Url=WxaApi.GetTokenApi.replace("APPID", appId).replaceAll("APPSECRET", appSecret);; //此请求为https的get请求,返回的数据格式为{"access_token":"ACCESS_TOKEN","expires_in":7200} String result = netHelper.getHttpsResponse(Url, "",null); System.out.println("获取到的access_token="+result); //使用FastJson将Json字符串解析成Json对象 JSONObject json = JSON.parseObject(result); AccessToken token = new AccessToken(); token.setAccessToken(json.getString("access_token")); token.setExpiresin(json.getInteger("expires_in")); return token; } }

这是一个springmvc启动以后就会启动的线程,用来自动获取token

工具类 用来发送https请求

  1 import javax.net.ssl.*;2 import java.io.BufferedReader;3 import java.io.InputStream;4 import java.io.InputStreamReader;5 import java.io.OutputStream;6 import java.io.UnsupportedEncodingException; 7 import java.net.URL; 8 import java.net.URLEncoder; 9 import java.security.cert.CertificateException; 10 import java.security.cert.X509Certificate; 11 12 /** 13 * 访问网络用到的工具类 14 */ 15 public class NetWorkHelper { 16 17 /** 18 * 发起Https请求 19 * @param reqUrl 请求的URL地址 20 * @param requestMethod 21 * @return 响应后的字符串 22 */ 23 public String getHttpsResponse(String reqUrl, String requestMethod,String outputStr) { 24  URL url; 25  InputStream is; 26 String resultData = ""; 27 try { 28 url = new URL(reqUrl); 29 HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); 30 TrustManager[] tm = {xtm}; 31 32 SSLContext ctx = SSLContext.getInstance("TLS"); 33 ctx.init(null, tm, null); 34  con.setSSLSocketFactory(ctx.getSocketFactory()); 35 con.setHostnameVerifier(new HostnameVerifier() { 36  @Override 37 public boolean verify(String arg0, SSLSession arg1) { 38 return true; 39  } 40  }); 41 42 43 con.setDoInput(true); //允许输入流,即允许下载 44 45 //在android中必须将此项设置为false 46 con.setDoOutput(true); //允许输出流,即允许上传 47 con.setUseCaches(false); //不使用缓冲 48 if (null != requestMethod && !requestMethod.equals("")) { 49 con.setRequestMethod(requestMethod); //使用指定的方式 50 } else { 51 con.setRequestMethod("GET"); //使用get请求 52  } 53 con.setRequestProperty("content-type", 54 "application/x-www-form-urlencoded"); 55 // 当outputStr不为null时向输出流写数据 56 if (null != outputStr) { 57 OutputStream outputStream = con.getOutputStream(); 58 // 注意编码格式 59 outputStream.write(outputStr.getBytes("UTF-8")); 60  outputStream.close(); 61  } 62 is = con.getInputStream(); //获取输入流,此时才真正建立链接 63 InputStreamReader isr = new InputStreamReader(is); 64 BufferedReader bufferReader = new BufferedReader(isr); 65  String inputLine; 66 while ((inputLine = bufferReader.readLine()) != null) { 67 resultData += inputLine + "\n"; 68  } 69 // System.out.println(resultData); 70 71 } catch (Exception e) { 72  e.printStackTrace(); 73  } 74 return resultData; 75  } 76 77 X509TrustManager xtm = new X509TrustManager() { 78  @Override 79 public X509Certificate[] getAcceptedIssuers() { 80 return null; 81  } 82 83  @Override 84 public void checkServerTrusted(X509Certificate[] arg0, String arg1) 85 throws CertificateException { 86 87  } 88 89  @Override 90 public void checkClientTrusted(X509Certificate[] arg0, String arg1) 91 throws CertificateException { 92 93  } 94  }; 95 /** 96 * 对URL地址进行EnCode处理 97 * @param url 98 * @return 99 */ 100 public static String urlEnCode(String url) 101  { 102 String enCodedUrl = ""; 103 104 try 105  { 106 enCodedUrl = URLEncoder.encode(url, "utf-8"); 107  } 108 catch (UnsupportedEncodingException e) 109  { 110 // TODO Auto-generated catch block 111  e.printStackTrace(); 112 System.out.println("转码失败!"); 113  } 114 115 return enCodedUrl; 116  } 117 }

线程启动可能会获取两次token是因为springmvc把项目的Bean扫描了两次,可以把applicationContext.xml配置成只扫描mapper,其他不扫,由springmvc.xml去扫面serveice 和controller,因为我这样还是失败了,所以把线程的类也定义成controller,这样用前面的方法只会扫描一次

转载于:https://www.cnblogs.com/chaoswu/p/10174615.html

微信公众号开发-接入相关推荐

  1. 网络架构、云平台和微信公众号开发接入--基于嵌入式工程师的视觉

    云与后端相关的技术似乎并不属于嵌入式和物联智能硬件开发工程师的范畴,但是嵌入式开发工程师有必要认识成熟的网络架构和相关的云技术,以拓展自己在系统架构方面的视野.大数据分析是物联网背后的核心价值,物联智 ...

  2. 微信公众号开发接入,利用微信公众平台申请测试号进行本地开发

    一.前言 随着微信的普遍,年轻一代逐渐从QQ转到微信的使用.界面简洁,功能强大,男女老少皆宜是微信的特点,也正是靠着这一特点,从而使得微信在国内成为了社交软件的巨头.因此在微信端里就衍生了很多的产品需 ...

  3. 微信公众号开发教程(一) 验证接入

    作者:陈惠,叩丁狼教育高级讲师.原创文章,转载请注明出处. 微信公众号开发教程(一)验证接入 本篇文章主要介绍了微信公众号开发接入详细流程,希望对刚接触公众号开发的同学有所帮助,有兴趣的同学可多多关注 ...

  4. 微信公众号开发之服务器接入指南之Java版本

    微信公众号开发的官方文档: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319 其中我们开发好的服务器,在配置到 ...

  5. C#微信公众号开发系列教程二(新手接入指南)

    此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可直接跳过,也欢迎大神吐槽. 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教 ...

  6. 微信公众号自动回复html,[.NET] 简单接入微信公众号开发:实现自动回复

    简单接入微信公众号开发:实现自动回复 一.前提 先申请微信公众号的授权,找到或配置几个关键的信息(开发者ID.开发者密码.IP白名单.令牌和消息加解密密钥等). 二.基本配置信息解读 开发者ID:固定 ...

  7. nodejs微信公众号开发第一步(接入指南)--wechat模块

    用模块接入微信就非常简单了.只用配置好参数,逻辑大神都写好了,站在巨人的肩膀上的感觉就是不错 本文测试用的是微信测试号. -- express生成项目框架 express命令行创建项目 :点击这里, ...

  8. 微信公众号开发 - 配置表设计以及接入公众号接口开发

    微信公众号开发文章目录 1.微信公众号开发 - 环境搭建 2.微信公众号开发 - 配置表设计以及接入公众号接口开发 3.微信公众号开发 - token获取(保证同一时间段内只请求一次) 4.微信公众号 ...

  9. 如何接入微信公众号开发?底层原理是什么?

    要接入微信公众号开发,您需要完成以下几个步骤: 注册微信公众平台账号:首先,您需要在微信公众平台上注册一个账号,并创建一个公众号.在注册过程中,您需要提供相关的身份信息和认证材料,以便微信审核和认证您 ...

最新文章

  1. 利用BP神经网络教计算机识别语音特征信号(代码部分SS)
  2. 一段经典的js命名空间创建和链式调用代码
  3. Android——Handler总结
  4. 【Linux网络编程】TCP
  5. 张霖峰:AV1和VVC的格局将在2023年后明朗
  6. FreeBSD从零开始---安装后配置(三)
  7. Redis可以做哪些事儿?
  8. ZetCode Ruby 教程
  9. 学习vim: 配置python相关插件
  10. Linux系统管理初步(六)设置计划任务
  11. adblock插件_为WordPress创建一个反AdBlock插件
  12. WSL登录失败:未授权用户再次计算机上的请求登录类型
  13. 【C++】栈~~(很详细哦)
  14. 简历项目描述过程详解
  15. html js滚轮事件,Js滚轮事件
  16. 【水滴石穿】mobx-todos
  17. XMPP协议实现原理介绍
  18. AMI POST Code含义
  19. 华硕安装linux windows7,windows+centos7双系统安装
  20. 《28天玩转TensorFlow2》第10天:TensorFlow2项目实战—基于迭代的风格迁移

热门文章

  1. 物联网网关linux带串口,物联网网关|串口转HTTP GET协议
  2. 实验7-3-5 输出大写英文字母 (15分)
  3. python理论知识选择题_python基础知识练习题(一)
  4. 数学建论文模标准模板
  5. 嵌入式linux开发业内各个常用开源项目git仓库地址大全
  6. [Spark]PySpark入门学习教程---例子RDD与DataFrame
  7. [深度学习]CNN--卷积神经网络中用1*1 卷积有什么作用
  8. 图像卷积与滤波知识点整理(1)
  9. 八、梯度下降法和拟牛顿法
  10. XManager:xshell显示图形化界面