微信公众号开发-接入

一 首先实现内网穿透,公众号需要连接我们的服务器,内外无法访问,所以先实现自己的内网可以测试时连接外网,下载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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/248778.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vue 项目上线优化

上线项目的优化 优化上线项目&#xff0c;首先在上线打包时我们通过babel插件将console清除&#xff0c;当然对项目打包后的体积的影响是微乎其微&#xff0c;对项目的入口文件的改善也是很有必要的&#xff0c;因为在开发阶段和上线如果我们使用的是同一入口文件&#xff0c;…

Python并发编程—进程

多任务编程 1.意义&#xff1a; 充分利用计算机多核资源&#xff0c;提高程序的运行效率。 2.实现方案 &#xff1a;多进程 &#xff0c; 多线程 3.并行与并发 并发 &#xff1a; 同时处理多个任务&#xff0c;内核在任务间不断的切换达到好像多个任务被同时执行的效果&#xf…

Vue 脚手架中的.eslintrc.js代码规范 的解决

在我们使用Vue脚手架 创建项目时 尤其是团队共同开发项目时 会按照一个共同的代码规范来编程 创建Vue脚手架中有一个.eslintrc.js格式 但是在编程中我们通常会使用 shiftaltf 进行代码格式化 但是由于格式化后的代码 与Vue中的.eslintrc规范不协调 尤其是 “” &#xff1b; 以…

前端面试---Vue部分考点梳理

一. Vue的使用 1. Vue的基本使用 指令 插值 插值 表达式 指令 动态属性 v-html 会有XSS风险 会覆盖子组件 computed 和 watch computed 有缓存 data不变则不会重新计算watch 如何深度监听watch 监听引用类型时 拿不到oldVal v-for v-for 和 v-if 不能同时使用:key的值尽量…

.net core实现跨域

什么是跨域在前面已经讲解过了&#xff0c;这里便不再讲解&#xff0c;直接上代码。 一、后台API接口 用.net core创建一个Web API项目负责给前端界面提供数据。 二、前端界面 建立两个MVC项目&#xff0c;模拟不同的ip&#xff0c;在view里面添加按钮调用WEB API提供的接口进行…

TCP/IP简介

TCP/IP简介 OSI的“实现”&#xff1a;TCP/IP参考模型 并不完全符合OSI的七层参考模型&#xff0c;但我们可以理解为OSI的一种实现 TCP/IP协议简述 在很多情况下&#xff0c;它只是利用IP协议进行通信时&#xff0c;所必须用到的协议群的统称&#xff0c;具体来说&#xff0c;I…

Spring-Cloud 学习笔记-(4)负载均衡器Ribbon

目录 Spring-Cloud 学习笔记-&#xff08;4&#xff09;负载均衡器Ribbon1、前言2、什么是负载均衡2.1、问题分析2.2、什么是Ribbon3、快速入门3.1、实现方式一3.1.1、修改代码3.2、实现方式二3.2.1、启动类3.2.2、调用代码3.2.3、测试3.2.4、实现原理3.2.5、断点调式3.3、修改…

‘仿微信发表朋友圈’项目中登录功能的业务逻辑

登录功能 手机号验证码都通过后端验证后 返回用户数据 登陆成功 成功后 调用store中的setUser方法 store中的setUser方法 将后端返回的用户信息存储到localStorage中 同时登录成功后服务器会将token自动存入我们的cookie中 有过期时间 在我们请求需要登录的接口时将cookie中的…

kubernetes--配置文件

转载于:https://www.cnblogs.com/caiciadeliliang/p/10993388.html

微信动态中的背景图更换

初衷&#xff1a; 图一中的红框中的部分&#xff0c;作为用户自定义的背景图&#xff0c;如果用户没有上传也会为其自动设置一张背景图&#xff0c;当用户点击时则会出现图二中的选项 &#xff0c;点击取消则选项消失&#xff0c;点击从相册选择则会跳转本机的相册&#xff0c…

大数据学习——akka自定义RPC

实现 package cn.itcast.akkaimport akka.actor.{Actor, ActorSystem, Props} import akka.actor.Actor.Receive import com.typesafe.config.ConfigFactoryimport scala.collection.mutableimport scala.concurrent.duration._class Master(val host: String, val port: Int) …

从Client应用场景介绍IdentityServer4(一)

从Client应用场景介绍IdentityServer4&#xff08;一&#xff09; 原文:从Client应用场景介绍IdentityServer4&#xff08;一&#xff09;一、背景 IdentityServer4的介绍将不再叙述&#xff0c;百度下可以找到&#xff0c;且官网的快速入门例子也有翻译的版本。这里主要从Clie…

开发常用代码笔记

Vue 使用moment插件对时间进行格式化&#xff08;全局设置&#xff09; 下载插件 npm install moment --save 在main.js中引入插件 import moment from ‘moment’ 在main.js中定义全局过滤器 Vue.filter(dataFilter,function (dataStr,patten YYYY-MM-DD HH:mm:ss) {retur…

微信小程序——账号及开发工具

1. 注册微信小程序账号 点击我进入微信公众平台 进入后点击立即注册 注册成功且登录后进入小程序管理后台 2. 安装开发者工具 点击进入开发文档 进入安装开发工具&#xff08;稳定版本&#xff09; 一路默认下一步进行安装 3. 开发者工具的使用 使用注册微信小程序的微信号…

CSS注意的地方

content-box和border-box的区别 2018年02月27日 22:20:16 sulingliang 阅读数&#xff1a;8011盒子模型 盒子宽度&#xff1a;paddingbordercontent-width 盒子高度&#xff1a;paddingbordercontent-height 如图所示 盒子模型content-box 说明&#xff1a;在内容宽度和高度之…

机器学习笔记(6) 线性回归

先从最简单的例子开始,假设我们有一组样本(如下图的一个个黑色的圆点),只有一个特征,如下图,横轴是特征值,纵轴是label。比如横轴是房屋面积,纵轴是房屋价格. 现在我们要做什么呢&#xff1f;我们试图找到一条直线yaxb,可以尽量好的拟合这些点. 你可能要问了,为啥是直线,不是曲…

仿微信朋友圈项目梳理

项目功能简介&#xff1a; 用户通过手机号验证码进行登录和注册 可以浏览动态列表中的所有动态 登录成功后用户可以发表自己的动态 也可以对自己认可欣赏的动态进行点赞和评论 也可以通过动态结识志同道合的朋友 进行聊天和探讨 前端&#xff1a;采用Vue框架搭建 weui进行页面…

echarts鼠标事件以及自定义数据获取

事件添加方法&#xff1a; 对应官网位置&#xff1a;https://www.echartsjs.com/api.html#events 鼠标事件包括 click、dblclick、mousedown、mousemove、mouseup、mouseover、mouseout、globalout、contextmenu。 myChart.on(click, function (params) {console.log(params); …

[数学]点、线、面分割问题

平面分割问题 p条直线相交于一点时&#xff0c;分割的图形有 2*(n-1) 个&#xff0c;此时再加一条直线&#xff0c;在 2*(n-1) 的基础上再加 n条&#xff0c;此时为2*n n条曲线&#xff0c;其中有m条相交于一点&#xff0c;每两个曲线都交于两点 平面上有n条直线&#xff0c;且…

移动开发

1.移动端基础 1.1 浏览器现状 PC端浏览器 360浏览器、谷歌浏览器、火狐浏览器、QQ浏览器、百度浏览器&#xff08;停止服务&#xff09;、搜狗浏览器、IE浏览器 移动端浏览器 UC、QQ浏览器、欧朋浏览器、百度手机浏览器、360、搜狗、猎豹、谷歌等其他手机自带的浏览器 国…