微信公眾號開發-接入

一?首先實現內網穿透,公眾號需要連接我們的服務器,內外無法訪問,所以先實現自己的內網可以測試時連接外網,下載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.pswp.cn/news/248778.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248778.shtml
英文地址,請注明出處:http://en.pswp.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; 以…

innodb_locks_unsafe_for_binlog分析

mysql數據庫中默認的隔離級別為repeat-read. innodb默認使用了next-gap算法&#xff0c;這種算法結合了index-row鎖和gap鎖。正因為這樣的鎖算法&#xff0c;innodb在可重復讀這樣的默認隔離級別上&#xff0c;可以避免幻象的產生。 innodb_locks_unsafe_for_binlog最主要的作用…

emacs的使用方法

emacs的使用方法 emacs配置&#xff1a; 將文件命名為.emacs&#xff0c;把配置敲進去&#xff0c;放在home文件夾 emacs命令行&#xff1a; altx打開命令行 編譯&#xff1a; 在命令行輸入compile&#xff0c;回車&#xff0c;會出現make -k&#xff0c;刪掉它&#xff0c;輸入…

前端面試---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…

springboot 參數校驗詳解

https://www.jianshu.com/p/89a675b7c900 在日常開發寫rest接口時&#xff0c;接口參數校驗這一部分是必須的&#xff0c;但是如果全部用代碼去做&#xff0c;顯得十分麻煩&#xff0c;spring也提供了這部分功能,本文來探究一下如何實現 1.配置 spring-boot-starter-web包自動依…

微信小程序——賬號及開發工具

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進行頁面…