日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

用spring搭建微信公众号开发者模式下服务器处理用户消息的加密传输构架(java)

發(fā)布時(shí)間:2025/3/15 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 用spring搭建微信公众号开发者模式下服务器处理用户消息的加密传输构架(java) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? ? 要搭建加密傳輸?shù)奈⑿殴娞?hào)消息傳輸,首先要在開發(fā)這平臺(tái)下載一下微信加密的相關(guān)jar包,并做一些準(zhǔn)備。準(zhǔn)備的步驟如下:


1.打開開發(fā)者文檔,找到消息加減密--->接入指引,如下圖所示:



2.在頁(yè)面底部找到實(shí)例代碼,并下載解壓,下載的地方如下圖所示:


3.在解壓的地方找到j(luò)ava版本,并做如下準(zhǔn)備:

(1)將commons-codec-1.9.jar導(dǎo)入到項(xiàng)目中。



(2)將dist下的aes-jre1.6.jar導(dǎo)入到項(xiàng)目中。


(3)打開readme.txt,按照他的指示操作。紅色對(duì)勾的地方很重要。


要下載的東西就是下圖標(biāo)記的地方


這樣準(zhǔn)備工作就完成了,可以進(jìn)入正式的代碼編寫了。


代碼部分的解釋基本都放在注釋中,首先開用來(lái)核心控制的controller。內(nèi)容如下:

package org.calonlan.soulpower.controller;import java.io.IOException; import java.io.PrintWriter; import java.io.StringReader; import java.util.Map;import javax.annotation.Resource; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.calonlan.soulpower.service.WeiInfoService; import org.calonlan.soulpower.util.AesUtils; import org.calonlan.soulpower.util.MessageUtil; import org.calonlan.soulpower.util.SignUtil; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod;/*** @author Administrator* 這個(gè)controller是用來(lái)處理消息的核心controller,在這里有兩個(gè)請(qǐng)求地址都為/sign的請(qǐng)求地址,一個(gè)是用get方式,用來(lái)* 做服務(wù)器和微信服務(wù)器之間的認(rèn)證;一個(gè)是post方式,用來(lái)在服務(wù)器和微信服務(wù)器之間傳遞消息。*/ @Controller @RequestMapping("/core") public class CoreController {@Resourceprivate WeiInfoService weiInfoService;/** 這個(gè)service大家可以不用管,* 因?yàn)樵谖业捻?xiàng)目中我是把所有的微信相關(guān)的配置信息都保存在一個(gè)weiInfo的類中了* ,這里只會(huì)用到token。*//*** @param request* @param response* @throws IOException* @throws ServletException* 用來(lái)和微信服務(wù)器之間相互認(rèn)證*/@RequestMapping(method = RequestMethod.GET, value = "/sign")public void goGet(HttpServletRequest request, HttpServletResponse response)throws IOException, ServletException {String signature = request.getParameter("signature");// 獲得signatureString timestamp = request.getParameter("timestamp");// 獲得timestampString nonce = request.getParameter("nonce");// 獲得nonceString echostr = request.getParameter("echostr");// 獲得echostr/** 上面的四個(gè)參數(shù)都是微信服務(wù)器發(fā)送過來(lái)的,其中signature、timestamp、nonce是要參與服務(wù)器的驗(yàn)證的,* 而echostr是在我們通過驗(yàn)證后返回給服務(wù)器告訴服務(wù)器我們就是要通訊 的那個(gè)遠(yuǎn)程服務(wù)器*/PrintWriter out = response.getWriter();if (SignUtil.checkSignature(signature, timestamp, nonce,weiInfoService.get())) {//在SignUtil中使用checkSignature來(lái)進(jìn)行驗(yàn)證,代碼附在后面。out.print(echostr);//驗(yàn)證通過后就把echostr返回給微信服務(wù)器。}out.close();out = null;}@RequestMapping(method = RequestMethod.POST, value = "/sign")/*** * 用來(lái)和微信服務(wù)器通信* * */public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {request.setCharacterEncoding("UTF-8");response.setCharacterEncoding("UTF-8");/** 進(jìn)行消息分發(fā) *//* 首先定義一個(gè)空的回復(fù)消息 */String respMessage = "";try {/* 從請(qǐng)求中獲得xml格式的信息。并轉(zhuǎn)化為map類型 */Map<String, String> requestMapSecret = MessageUtil.parseXml(request);//從request中獲得獲得xml,并解析,代碼附在后面/* 獲得解密后的消息正文 */String mingwenXML = AesUtils.descMessage(//用微信官方給的jar包中的AesUtils來(lái)對(duì)消息進(jìn)行解密requestMapSecret.get("Encrypt"),/* 加密的消息體 */request.getParameter("msg_signature"),/* 請(qǐng)求中的消息簽名 */request.getParameter("timestamp"),/* 時(shí)間戳 */request.getParameter("nonce"));/* 無(wú)序數(shù)列 *//* 將明文再次進(jìn)行xml解析 */Map<String, String> requestMap = MessageUtil.parseXml(new StringReader(mingwenXML));//將明文的xml再次解析后放入map中,/** 獲得用戶發(fā)來(lái)的消息類型,并做相應(yīng)的處理 */String messageType = requestMap.get("MsgType");System.out.println(messageType);/*處理不同格式的消息類型開始-------------------------------------------------------*/// 用戶發(fā)來(lái)的是文本消息if (messageType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {System.out.println(requestMap.get("Content"));}// 用戶發(fā)來(lái)的是圖片消息else if (messageType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {}// 用戶發(fā)來(lái)地理位置信息else if (messageType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {}// 用戶發(fā)來(lái)鏈接消息else if (messageType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {}// 用戶發(fā)來(lái)音頻消息else if (messageType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {}/** 事件推送的處理 */else if (messageType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {// 事件類型String eventType = requestMap.get("Event");// 訂閱if (eventType.equals(MessageUtil.REQ_MESSAGE_TYPE_SUBSCRIBE)) {}// 取消訂閱else if (eventType.equals(MessageUtil.REQ_MESSAGE_TYPE_UNSUBSCRIBE)) {}// 點(diǎn)擊按鈕事件else if (eventType.equals(MessageUtil.REQ_MESSAGE_TYPE_CLICK)) {}}/*處理不同格式的消息類型介紹-------------------------------------------------------*//*對(duì)于不同類型的消息的處理網(wǎng)上有很多高手已經(jīng)發(fā)表了很多文章了,我自己也會(huì)總結(jié)一下,不過不是在這里---------*/// 給返回的消息加密AesUtils.aescMessage(respMessage,request.getParameter("timestamp"),request.getParameter("nonce"));} catch (Exception e) {e.printStackTrace();}/*返回消息給微信服務(wù)器,然后微信服務(wù)器把消息轉(zhuǎn)發(fā)給用戶···額,貌似我們聊什么,微信服務(wù)器都是可以截獲的,*/PrintWriter out = response.getWriter();out.print(respMessage);out.close();} }

SignUtil的checkSignature代碼如下:

public static boolean checkSignature(String signature, String timestamp,String nonce, WeiInfo info) {/** 微信服務(wù)器發(fā)送過來(lái)的signature是通過某些處理然后進(jìn)行SHA1加密的,我們來(lái)用它發(fā)過來(lái)的信息自己生成一個(gè)signature,* 然后兩者之間進(jìn)行比對(duì),一致的話我們就是伙伴,不一致就拒絕它*/String[] arr = new String[] { info.getToken(), timestamp, nonce };/* token是我們自己填寫的,具體填寫位置見下圖;timestamp、nonce是微信服務(wù)器發(fā)送過來(lái)的,這里我們把他們都放到數(shù)組中。*/Arrays.sort(arr);//對(duì)數(shù)組中的數(shù)據(jù)進(jìn)行字典排序。。。。要不然加密出來(lái)的東西是沒用的StringBuilder content = new StringBuilder();for (int i = 0; i < arr.length; i++) {content.append(arr[i]);}//把字典排序好的數(shù)組讀取成字符串。MessageDigest md = null;String tmpStr = null;try {/*進(jìn)行sha1加密*/md = MessageDigest.getInstance("SHA-1");byte[] digest = md.digest(content.toString().getBytes());tmpStr = byteToStr(digest);//將加密后的byte轉(zhuǎn)化為16進(jìn)制字符串,這就是我們自己構(gòu)造的signature} catch (NoSuchAlgorithmException e) {e.printStackTrace();}content = null;return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;//進(jìn)行對(duì)比,相同返回true,不同返回false}
private static String byteToStr(byte[] byteArray) {String strDigest = "";for (int i = 0; i < byteArray.length; i++) {strDigest += byteToHexStr(byteArray[i]);//分別把沒一個(gè)byte位轉(zhuǎn)換成一個(gè)16進(jìn)制字符,代碼見下面}return strDigest;}
private static String byteToHexStr(byte mByte) {char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A','B', 'C', 'D', 'E', 'F' };char[] tempArr = new char[2];tempArr[0] = Digit[(mByte >>> 4) & 0X0F];tempArr[1] = Digit[mByte & 0X0F];String s = new String(tempArr);return s;}

AesUtils的具體代碼

package org.calonlan.soulpower.util;import org.calonlan.soulpower.dao.impl.WeiInfoDaoImpl; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class AesUtils {private static ApplicationContext applicationContext;/** 這里我直接使用的spring來(lái)讀取weiInfo對(duì)象中的加解密密鑰的內(nèi)容,大家可以不用這樣,直接把密鑰放在這里就可以了,* 也可以放在properties文件中讀取更方便*/public static String descMessage(String encrypt, String msgSignature,String timestamp, String nonce) throws AesException {applicationContext = new ClassPathXmlApplicationContext("config/application-context.xml");WeiInfoDaoImpl daoImpl = (WeiInfoDaoImpl) applicationContext.getBean("weiInfoDao");String token = daoImpl.get().getToken();//獲得tokenString encodingAesKey = daoImpl.get().getEncodingAesKey();//獲得加解密密鑰String appId = daoImpl.get().getAppId();//獲得appid,這個(gè)在開發(fā)者模式下就能看到,填寫你自己的。String format = "<xml><ToUserName><![CDATA[toUser]]></ToUserName><Encrypt><![CDATA[%1$s]]></Encrypt></xml>";String fromXML = String.format(format, encrypt);WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);String result = pc.decryptMsg(msgSignature, timestamp, nonce, fromXML);return result;}/*加密和解密類似,就不做注釋了*/public static String aescMessage(String replyMsg, String timestamp,String nonce) throws AesException {applicationContext = new ClassPathXmlApplicationContext("config/application-context.xml");WeiInfoDaoImpl daoImpl = (WeiInfoDaoImpl) applicationContext.getBean("weiInfoDao");String token = daoImpl.get().getToken();String encodingAesKey = daoImpl.get().getEncodingAesKey();String appId = daoImpl.get().getAppId();WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);String mingwen = pc.encryptMsg(replyMsg, timestamp, nonce);return mingwen;} }
MessageUtil中的parseXml代碼,有兩個(gè),一個(gè)是用來(lái)直接解析request中的xml,一個(gè)是用來(lái)解析字符串類型的xml


解析request中的xml代碼

public static Map<String, String> parseXml(HttpServletRequest request)throws Exception {Map<String, String> map = new HashMap<String, String>();InputStream inputStream = request.getInputStream();SAXReader reader = new SAXReader();//我用的是SAXReaderDocument document = reader.read(inputStream);Element root = document.getRootElement();@SuppressWarnings("unchecked")List<Element> elementList = root.elements();for (Element e : elementList) {map.put(e.getName(), e.getText());}inputStream.close();inputStream = null;return map;}


解析字符串中的xml代碼

public static Map<String, String> parseXml(StringReader readers) {Map<String, String> map = new HashMap<String, String>();SAXReader reader = new SAXReader();Document document = null;try {InputSource inputSource = new InputSource(readers);document = reader.read(inputSource);} catch (DocumentException e1) {// TODO Auto-generated catch blocke1.printStackTrace();}Element root = document.getRootElement();@SuppressWarnings("unchecked")List<Element> elementList = root.elements();for (Element e : elementList) {map.put(e.getName(), e.getText());}return map;}

到這里,構(gòu)建就完成了,可以用我們的服務(wù)器來(lái)和微信服務(wù)器進(jìn)行密文的消息傳遞了。

總結(jié)

以上是生活随笔為你收集整理的用spring搭建微信公众号开发者模式下服务器处理用户消息的加密传输构架(java)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: jizz日本在线播放 | 91av综合 | 国产男女爽爽爽 | 欧美最顶级a∨艳星 | 青青草国产在线观看 | 亚洲一区二区三区四区五区xx | 韩国明星乱淫(高h)小说 | 少妇久久久久久久 | 日韩尤物 | av导航站 | 夜夜嗨av一区二区 | 综合久久2o19 | 国产又黄又猛又粗 | 亚洲精品一区二区三区四区五区 | 亚洲va久久久噜噜噜久久天堂 | 日本成人免费 | 香蕉久久网 | 久久国产精品国产精品 | 少妇光屁股影院 | 永久免费在线观看av | 久久久久久久久一区 | 狠狠躁夜夜躁人人爽视频 | 欧美一区二区三区 | 午夜视频免费在线观看 | 99爱这里只有精品 | 日韩一区二区久久 | 日韩欧美一区在线观看 | 国产精品厕所 | 黄色网址视频 | 国产夫妻自拍小视频 | 国产青青 | 午夜激情视频网 | 97在线视频人妻无码 | 久操免费视频 | 欧美黑人xxx | 69视频免费看 | 99热香蕉 | 日本一区二区三区四区在线观看 | 99999av| av一级免费 | 成人免费在线观看av | 日韩精品你懂的 | 男生捅女生肌肌 | 国产日韩免费 | 久久久国产成人一区二区三区 | 国产吞精囗交免费视频 | 欧美一区二区在线免费观看 | 色妞网| 精品日本一区二区 | 日韩午夜影院 | 人人草在线视频 | 日本精品一区二区三区在线观看 | www.日日夜夜 | 超碰公开在线观看 | 午夜在线影院 | 国产精品xxxx| 99久视频| 男女国产视频 | 男人天堂成人 | www.欧美亚洲 | 老熟妇一区二区三区啪啪 | 国产裸体视频 | 亚洲美女偷拍 | 国产福利免费 | 少妇被按摩师摸高潮了 | 久草不卡| 国产aaa视频 | 可以在线看黄的网站 | 天堂一区二区三区四区 | 69久久夜色精品国产69 | 天干夜夜爽爽日日日日 | 91久久久久久久久久久久 | 日韩亚洲一区二区 | 歪歪6080 | 99精品视频免费在线观看 | 青青国产在线观看 | www.黄色片网站 | 国产主播在线看 | 久久成人激情 | 亚洲综合a | 国内久久精品 | 欧美一区二区福利视频 | 成人在线不卡 | 你懂的在线观看视频 | www.av在线播放 | 青青草免费看 | 麻豆免费观看网站 | 高潮av| 亚洲精品观看 | 久热网站 | 嫩草嫩草嫩草嫩草嫩草嫩草 | 男女瑟瑟网站 | 免费看国产曰批40分钟粉红裤头 | 国产免费又黄又爽又色毛 | 日韩黄色在线观看 | 在线91av | 韩国三级丰满少妇高潮 | 欧美日韩国产第一页 | 欧美日韩一区二区三区视频 |