การพัฒนาฟังก์ชั่นการแบ่งปัน WeChat
หลังจากผ่านไปหนึ่งวันฉันได้พัฒนาหน้าที่ของการส่ง WeChat ให้เพื่อนและแบ่งปันให้กับเพื่อนของฉัน ฉันจะแบ่งปันกับคุณที่นี่เพื่อหลีกเลี่ยงการออกนอกเส้นทาง
1. โปรแกรมฝั่งเซิร์ฟเวอร์
แพ็คเกจ com.wimedia.controller; นำเข้า java.io.ioexception; นำเข้า Java.security.messagedigest; นำเข้า java.security.nosuchalgorithmexception; นำเข้า Java.text.parseException; javax.servlet.http.httpservletrequest; นำเข้า Javax.servlet.http.httpservletResponse; นำเข้า org.springframework.beans.factory.annotation.AutoWired; นำเข้า org.springframework.stereotype.controller. org.springframework.web.bind.annotation.requestmapping; นำเข้า com.google.gson.gson; นำเข้า com.wimedia.model.ticket; นำเข้า com.wimedia.service.articlesolrservice; com.wimedia.utils.getrandomstr; นำเข้า com.wimedia.utils.signaturebean; นำเข้า com.wimedia.utils.weixin.weixinutil;/** * * * <p> โครงการ: mryl_phone_v2 </p> * * <p> *<p> บริษัท : Wimedia </p> * *@athor: songjia * *@วันที่: 2016-7-15 09:34:10 am * */@controller@requestmapping ("/weixinsharecontroller/api/inteface @RequestMapping ("/getSignature") สตริงสาธารณะ getSignature (คำขอ httpservletRequest, การตอบกลับ httpservletResponse) พ่น IOException, parseexception {// รับหน้าลายเซ็นลิงก์ url = request.getParameter ("url"); SimpledateFormat format = new SimpledateFormat ("yyyy-mm-dd hh: mm: ss"); // รับแท็กจากฐานข้อมูลและตรวจสอบว่าแท็กหมดอายุหรือไม่ Ticket oldTicket = ticketrepositorysolr.getTicketById ("20160114wiimmediamrylsong1152"); ถ้า (oldTicket == null) {// ครั้งแรกที่คุณเข้าถึงแท็กไม่มีอยู่ Executeticket (การตอบสนอง, "1", URL, รูปแบบ); คืนค่า null; } else {// แท็กมีอยู่ให้ตรวจสอบว่าแท็กหมดเวลาสตริง oldacquiretime = oldTicket.getAcQuireTime (); long different = format.parse (format.format (วันที่ใหม่ ())). getTime ()-format.parse (oldacquiretime) .getTime (); ถ้า (ความแตกต่าง> 71000000) {// การหมดเวลาแท็กให้ไปที่เซิร์ฟเวอร์ WeChat เพื่อขอการหมดเวลาแท็กคือ 7200 วินาที (72000000 มิลลิวินาที) Executeticket (การตอบสนอง, "2", URL, รูปแบบ); คืนค่า null; } else {// แท็กไม่ได้กำหนดเวลา/*** หมายเหตุ* 1. noncestr และ timestamp ที่ใช้สำหรับลายเซ็นจะต้องเหมือนกับ noncestr และ timestamp ใน wx.config * 2. URL ที่ใช้สำหรับลายเซ็นจะต้องเป็น URL ที่สมบูรณ์ของหน้าเว็บที่เรียกอินเตอร์เฟส JS * 3. ด้วยเหตุผลด้านความปลอดภัยนักพัฒนาจะต้องใช้ตรรกะลายเซ็นทางฝั่งเซิร์ฟเวอร์ ***** เป็นเรื่องง่ายที่จะทำผิดพลาดเมื่อกำหนดค่าลายเซ็นตามจุด 1 คุณต้องผ่าน noncestr และ timestamp ที่สร้างตั๋วไปยังลูกค้า ****/ ลายเซ็นสตริง = ลายเซ็น (oldTicket.getTicket (), oldTicket.GetTimestamp () SignatureBean SignatureBean = ใหม่ SignatureBean (); SignatureBean.SetNonCestr (oldTicket.getNonCestr ()); SignatureBean.setSignature (ลายเซ็น); SignatureBean.settimestamp (oldticket.getTimestamp ()); SignatureBean.seturl (URL); Response.setContentType ("ข้อความ/html; charset = utf-8"); Response.getWriter (). พิมพ์ (new GSON (). TOJSON (SignatureBean)); คืนค่า null; }}}/** * * <p> โครงการ: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * * <p> คำอธิบาย: วิธีการอัปเดตและรับตั๋ว เนื่องจากใช้ SOLR การอัปเดตจึงเหมือนกับใหม่ หากไม่มี ID จะมีการเพิ่ม หากมีความรับผิดชอบให้อัปเดต </p> * * <p> บริษัท : Wiimedia </p> * *@athor: songjia * *@วันที่: 2016-7-15 09:45:00 am * */โมฆะสาธารณะ getRandomstr (); สตริง noncestr = randomstr.getRandomString (15); // รับ Timestamp String Timestamp Signature = Long.toString (System.CurrentTimeMillis ()); // คำขอ AccessToken String AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=your appid & Secret = คีย์ของคุณ"; String tokenjson = weixinutil.httprequest (AccessTokenUrl, "get", null); GSON GSON = New GSON (); shareaccess_token token = gson.fromjson (tokenjson, shareaccess_token.class); String to = token.getAccess_token (); // รับแท็กสตริง urlticket = "https://api.weixin.qq.com/cgi-bin/ticket/getTicket?access_token="+ถึง+"& type = jsapi"; String Ticketjson = Weixinutil.httprequest (urlticket, "get", null); ตั๋วตั๋ว = gson.fromjson (Ticketjson, ticket.class); String t = ticket.getTicket (); // string uuid = uuid.randomuuid (). toString (). trim (). replaceall ("-", ""); // ID ตั๋วของฉันเป็นเวลาที่ได้มาจากสตริงตาย = format.format (วันที่ใหม่ ()); Ticket.settid ("20160114wiimmediamrylsong1152"); Ticket.setAcquiretime (AcquireTime); Ticket.settimestamp (การประทับเวลา); Ticket.setNonCestr (noncestr); // เนื่องจากใช้ SOLR วิธีการอัปเดตและการเพิ่มจะเหมือนกัน คุณสามารถแก้ไขได้ตามความต้องการเฉพาะของคุณ บทความนี้จะไม่โพสต์รหัสอีกต่อไป if (flag.equals ("2")) {ticketrepositorysolr.addtickettosolr (ตั๋ว); } else {ticketrepositorysolr.addtickettosolr (ตั๋ว); } /*** หมายเหตุ* 1. noncestr และ timestamp ที่ใช้สำหรับลายเซ็นจะต้องเหมือนกับ noncestr และ timestamp ใน wx.config * 2. URL ที่ใช้สำหรับลายเซ็นจะต้องเป็น URL ที่สมบูรณ์ของหน้าเว็บที่เรียกอินเตอร์เฟส JS * 3. ด้วยเหตุผลด้านความปลอดภัยนักพัฒนาจะต้องใช้ตรรกะลายเซ็นทางฝั่งเซิร์ฟเวอร์ * * ตามจุดที่ 1 มันเป็นเรื่องง่ายที่จะทำผิดพลาดเมื่อกำหนดค่าลายเซ็น คุณต้องผ่าน noncestr และ timestamp ที่สร้างตั๋วไปยังลูกค้า * */ string signature = ลายเซ็น (t, timestamp, noncestr, url); SignatureBean SignatureBean = ใหม่ SignatureBean (); SignatureBean.setNonCestr (noncestr); SignatureBean.setSignature (ลายเซ็น); SignatureBean.settimestamp (การประทับเวลา); SignatureBean.seturl (URL); Response.setContentType ("ข้อความ/html; charset = utf-8"); Response.getWriter (). พิมพ์ (new GSON (). TOJSON (SignatureBean)); }/** * * <p> โครงการ: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * * <p> คำอธิบาย: ลายเซ็นตามแท็ก, timestamps, คีย์, urls </p> * * <p> */ ลายเซ็นสตริงส่วนตัว (สตริง JSAPI_TICKET, String Timestamp, String NonCestr, url สตริง) {JSAPI_TICKET = "JSAPI_TICKET =" + JSAPI_TICKET; timestamp = "timestamp =" + timestamp; noncestr = "noncestr =" + noncestr; url = "url =" + url; สตริง [] arr = สตริงใหม่ [] {jsapi_ticket, timestamp, noncestr, url}; // เรียงลำดับโทเค็นพจนานุกรม, การประทับเวลา, noncest, พารามิเตอร์ URL array.sort (arr); StringBuilder Content = new StringBuilder (); สำหรับ (int i = 0; i <arr.length; i ++) {content.append (arr [i]); if (i! = arr.length - 1) {content.append ("&"); }} MESAGEDIGEST MD = NULL; สตริง tmpstr = null; ลอง {md = messageGeSt.getInstance ("sha-1"); // splice สตริงพารามิเตอร์สามตัวลงในสตริงสำหรับ SHA1 การเข้ารหัสไบต์ [] digest = md.digest (content.toString (). getBytes ()); TMPSTR = BYTETOSTR (DIGEST); } catch (nosuchalgorithmexception e) {e.printstacktrace (); } เนื้อหา = null; ส่งคืน tmpstr; } / ** * แปลงไบต์เป็น hexadecimal String * * @param mbyte * @return * / สตริงคงที่ส่วนตัว bytetohexstr (byte mbyte) {char [] digit = {'0', '1', '2', '3', '4', '5' 'e', 'f'}; ถ่าน [] Temparr = ถ่านใหม่ [2]; Temparr [0] = digit [(mbyte >>> 4) & 0x0f]; Temparr [1] = Digit [MBYTE & 0X0F]; สตริง s = สตริงใหม่ (temparr); กลับ s; } / ** * แปลงอาร์เรย์ไบต์เป็นสตริง hexadecimal * * @param bytearray * @return * / สตริงคงที่ส่วนตัว bytetOSTR (byte [] byteArray) {string strDigest = ""; สำหรับ (int i = 0; i <bytearray.length; i ++) {strdigest+= bytetohexstr (bytearray [i]); } return strdigest; } คลาส shareaccess_token {ส่วนตัวสตริง access_token; สตริงส่วนตัว Expires_in; สตริงสาธารณะ getAccess_token () {return access_token; } โมฆะสาธารณะ setAccess_token (String AccessToken) {access_token = AccessToken; } สตริงสาธารณะ getExpires_in () {return expires_in; } โมฆะสาธารณะ setExpires_in (สตริง expiresin) {expires_in = expiresIn; -2. รหัสลูกค้า
<script type = "text/javascript"> var url = window.location.href; var articleid = ""; var SharetItle = "ข้อมูลทางการแพทย์ของวันพรุ่งนี้"; var ShareimGurl = ""; var userInfo = localstorage.getItem ("_ userInfo"); การประทับเวลา var; var noncestr; ลายเซ็น var; // รับ Signature $ .ajax ({type: "get", url: "weixinsharecontroller/api/inteface/getSignature", // data: {timestamp: timestamp, noncestr: noncestr, url: url}, ข้อมูล: {url: url}, ความสำเร็จ timestamp = objdata.timestamp; function wxShare () {wx.config ({debug: false, // เปิดโหมดการดีบักค่าคืนของ APIs ทั้งหมดที่เรียกว่าจะได้รับการแจ้งเตือนบนไคลเอนต์เพื่อดูพารามิเตอร์ที่ผ่านคุณสามารถเปิดได้ทางด้านพีซี ตัวระบุการประทับเวลาบัญชีอย่างเป็นทางการ: การประทับเวลา, // จำเป็น, สร้างการประทับเวลาของลายเซ็น noncestr: noncestr, // จำเป็น, สร้างสตริงสุ่มของลายเซ็นลายเซ็น: ลายเซ็น, // จำเป็น, การลงชื่อ, ดูภาคผนวก 1 jsapilist: [onmenushareappmessage ' - } wx.ready (function () {// หลังจากการตรวจสอบข้อมูลการกำหนดค่าวิธีการพร้อมจะถูกเรียกใช้งานการโทรอินเตอร์เฟสทั้งหมดจะต้องได้รับหลังจากอินเทอร์เฟซการกำหนดค่าจะได้รับผลลัพธ์ // config เป็นการดำเนินการแบบอะซิงโครนัสของไคลเอนต์ดังนั้นหากคุณต้องการเรียกใช้อินเตอร์เฟสที่เกี่ยวข้อง โดยตรงโดยไม่ต้องใส่ในฟังก์ชั่นที่พร้อมใช้งาน // ถ้าประเภทคือเพลงหรือวิดีโอคุณต้องให้ลิงก์ข้อมูลค่าเริ่มต้นคือความสำเร็จที่ว่างเปล่า: function () {// ฟังก์ชั่นการเรียกกลับที่ดำเนินการหลังจากผู้ใช้ยืนยันการแชร์}, ยกเลิก: ฟังก์ชั่น () {// ฟังก์ชั่นการเรียกกลับที่ดำเนินการหลังจากผู้ใช้ยกเลิกการแชร์}}); // ----------------------- "แบ่งปันให้เพื่อน" wx.onmenusharetimeline ({title: 'วันพรุ่งนี้ข้อมูลทางการแพทย์', // แชร์ลิงก์: '', // แชร์ลิงก์ Imgurl: ShareimGurl, // แชร์ไอคอนความสำเร็จ: ฟังก์ชั่น () {// ฟังก์ชั่นการโทรกลับ // -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- การแบ่งปัน}, ยกเลิก: function () {// ฟังก์ชั่นการเรียกกลับที่ดำเนินการหลังจากผู้ใช้ยกเลิกการแชร์}}); - -3. เครื่องมือและรุ่นที่เซิร์ฟเวอร์ต้องการ
①ตั๋ว
แพ็คเกจ com.wimedia.model; ตั๋วระดับสาธารณะ {สตริงส่วนตัว TID; ตั๋วสตริงส่วนตัว สตริงส่วนตัว Errcode; สตริงส่วนตัว errmsg; สตริงส่วนตัว Expires_in; เวลาซื้อสตริงส่วนตัว สตริงส่วนตัว noncestr; การประทับเวลาสตริงส่วนตัว; ตั๋วสาธารณะ (String TID, สตริงตั๋ว, String errcode, String errmsg, String Expiresin, String Acquisitiontime, String NonCestr, String Timestamp) {super (); this.tid = tid; this.ticket = ตั๋ว; this.errcode = errCode; this.errmsg = errmsg; expires_in = expiresin; this.acquiretime = AcquireTime; this.noncestr = noncestr; this.timestamp = timestamp; } สตริงสาธารณะ getTid () {return tid; } โมฆะสาธารณะ SettId (String TID) {this.tid = tid; } สตริงสาธารณะ getTicket () {ตั๋วกลับ; } โมฆะสาธารณะ Setticket (ตั๋วสตริง) {this.ticket = ตั๋ว; } สตริงสาธารณะ geterRcode () {return errCode; } โมฆะสาธารณะ seterRcode (String errCode) {this.errcode = errCode; } สตริงสาธารณะ geterrmsg () {return errmsg; } โมฆะสาธารณะ setERRMSG (สตริง errmsg) {this.errmsg = errmsg; } สตริงสาธารณะ getExpires_in () {return expires_in; } โมฆะสาธารณะ setExpires_in (สตริง expiresin) {expires_in = expiresIn; } สตริงสาธารณะ getAcquireTime () {return acquisitiontime; } โมฆะสาธารณะ setAcQuireTime (String AcquireTime) {this.acquiretime = AcquireTime; } สตริงสาธารณะ getNonCestr () {return nonCestr; } โมฆะสาธารณะ setNonCestr (สตริง nonCestr) {this.nonCestr = nonCestr; } สตริงสาธารณะ getTimeStamp () {ส่งคืนการประทับเวลา; } โมฆะสาธารณะ setTimestamp (String timestamp) {this.timestamp = timestamp; - ②ธุรกิจที่เพิ่มเข้ามาในฐานข้อมูลถูกนำไปใช้ตามความต้องการของคุณ
③ getRandomstr
แพ็คเกจ com.wiimedia.utils; นำเข้า java.util.random; คลาสสาธารณะ getRandomstr {/** * * <p> โครงการ: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * <p> คำอธิบาย *@วันที่: 2016-7-14 11:14:46 AM * */ สตริงสาธารณะ getRandomString (ความยาว int) {String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; สุ่มสุ่ม = ใหม่สุ่ม (); StringBuffer sb = new StringBuffer (); สำหรับ (int i = 0; i <length; i ++) {หมายเลข int = random.nextint (base.length ()); sb.append (base.charat (หมายเลข)); } return sb.toString (); -④ SignatureBean
แพ็คเกจ com.wimedia.utils; Public Class SignatureBean {String Private String noncestr; URL สตริงส่วนตัว การประทับเวลาสตริงส่วนตัว; ลายเซ็นสตริงส่วนตัว สตริงสาธารณะ getNonCestr () {return noncestr; } โมฆะสาธารณะ setNonCestr (สตริง nonCestr) {this.nonCestr = nonCestr; } สตริงสาธารณะ getUrl () {return url; } โมฆะสาธารณะ setUrl (rl String) {this.url = url; } สตริงสาธารณะ getTimeStamp () {ส่งคืนการประทับเวลา; } โมฆะสาธารณะ setTimestamp (String timestamp) {this.timestamp = timestamp; } สตริงสาธารณะ getSignature () {ส่งคืนลายเซ็น; } โมฆะสาธารณะ setSignature (ลายเซ็นสตริง) {this.signature = ลายเซ็น; -⑤ weixinutil
แพ็คเกจ com.wimedia.utils.weixin; นำเข้า java.io.bufferedreader; นำเข้า java.io.inputstream; นำเข้า java.io.inputstreamreader; นำเข้า java.io.OutputStream; นำเข้า Java.net.connectException; javax.net.ssl.sslcontext; นำเข้า javax.net.ssl.sslsocketfactory; นำเข้า Javax.net.ssl.trustManager;/** * * <p> โครงการ: mryl_phone_v2 </p> * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * <p> บริษัท : wiimedia </p> * * @athor: songjia * * @วันที่: 2016-7-15 09:37:13 am * */คลาสสาธารณะ weixinutil {/** * เริ่มต้นคำขอ HTTPS ค่าแอตทริบิวต์ของวัตถุ JSON ผ่าน jsonObject.get (คีย์)) */ สตริงคงที่สาธารณะ httpRequest (String RequestUrl, String requestMethod, String outputstr) {StringBuffer buffer = new StringBuffer (); ลอง {// สร้างวัตถุ SSLContext และเริ่มต้น TrustManager [] tm = {ใหม่ myx509trustManager ()}; sslContext sslContext = sslContext.getInstance ("ssl", "sunjsse"); sslcontext.init (null, tm, ใหม่ java.security.securerandom ()); // รับวัตถุ SSLSocketFactory จากวัตถุ SSLContext ด้านบน SSLSocketFactory SSF = SSLContext.getSocketFactory (); url url = url ใหม่ (requesturl); httpsurlconnection httpurlconn = (httpsurlconnection) url.openconnection (); httpurlconn.setsslsocketfactory (SSF); httpurlconn.setDooutput (จริง); httpurlconn.setDoInput (จริง); httpurlconn.setusecaches (เท็จ); // ตั้งค่าวิธีการร้องขอ (รับ/โพสต์) httpurlconn.setRequestMethod (requestMethod); if ("get" .equalsignorecase (requestmethod)) httpurlconn.connect (); // เมื่อมีข้อมูลที่จำเป็นต้องส่งถ้า (null! = outputStream outputStream = httpurlconn.getOutputStream (); // ให้ความสนใจกับรูปแบบการเข้ารหัสเพื่อป้องกันไม่ให้ outputstream.write (outputStstr.getByTes ("utf-8")); httpurlconn.getInputStream (); InputStreamReader.close ();4. ณ จุดนี้ฟังก์ชั่นการแบ่งปันได้รับการพัฒนา แต่คุณจะพบปัญหามากมายเมื่อสร้างลายเซ็น นี่คือวิธีการแก้ไขปัญหาบางอย่างสำหรับความล้มเหลวของ WX.Config
①ยืนยันว่าลายเซ็นที่สร้างขึ้นนั้นถูกต้องใน http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign จัดทำโดย WeChat สำหรับการตรวจสอบ
②ไม่ว่าจะเป็น noncest, timestamp ที่ใช้ใน WX.Config นั้นสอดคล้องกับ noncestr และ timestamp ที่เกี่ยวข้องที่ใช้ในการลงนาม ... ดังกล่าวข้างต้น (1. รหัสเซิร์ฟเวอร์)
(เป็นไปได้ว่าเนื่องจากปัญหาคำสั่งซื้อหน้า JS, ลายเซ็นที่สร้างจากเซิร์ฟเวอร์, noncest และการประทับเวลาไม่ได้รับใน wx.config)
③ยืนยันว่า URL เป็น URL ที่สมบูรณ์ของหน้ารวมถึงส่วนพารามิเตอร์ GET ที่ต้องลบออกจาก # ต่อไปนี้
④ appid ในการกำหนดค่าสอดคล้องกับ appid ที่ใช้เพื่อรับ jsapi_ticket หรือไม่?
⑤ข้อผิดพลาด {errmsg: config: ok} เป็นผลตอบแทนปกติของโหมดการดีบักและปิดโหมดการดีบัก ตกลง
wx.config debug: false,
บทความนี้ได้รวบรวมไว้ใน "บทสรุปการสอนการพัฒนา Android WeChat" และ "สรุปการสอนการพัฒนา Java WeChat" ยินดีต้อนรับทุกคนให้เรียนรู้และอ่าน
ข้างต้นเป็นเนื้อหาทั้งหมดของบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์ต่อการเรียนรู้ของทุกคนและฉันหวังว่าทุกคนจะสนับสนุน wulin.com มากขึ้น