Pengembangan fungsi berbagi wechat
Setelah sehari, saya telah mengembangkan fungsi mengirim WeChat ke teman -teman dan membagikannya ke lingkaran teman saya. Saya akan membaginya dengan Anda di sini untuk menghindari jalan memutar.
1. Program sisi server
Paket com.wimedia.controller; impor java.io.ioexception; impor java.security.messagedigest; impor java.security.nosuchalithmexception; impor java.text.parseexception; impor java.text.simpledateFor; javax.servlet.http.httpservletRequest; impor javax.servlet.http.httpservletResponse; impor org.springframework.beans.factory.notation.Autowired; impor org.springframework.stereotipe.confoller; org.springframework.web.bind.annotation.requestmapping; impor com.google.gson.gson; impor com.wimedia.model.ticket; impor com.wimedia.sicrepositori; com.wimedia.utils.getrandomstr; import com.wimedia.utils.SignatureBean; import com.wimedia.utils.weixin.weixinutil;/** * * * * <p> Proyek: Paket Mryl_phone_v2 </p> * * <p> *<p> Perusahaan: Wimedia </p> * *@athor: Songjia * *@Tanggal: 2016-7-15 09:34:10 AM * */@Controller@RequestMapping ("/WeixinshareController/API/Inteface") Public Class WeixinshareController {@Arautowirired PriverryryrolirysoPerorysoPorysolyroller; @RequestMapping ("/getSignature") Public String GetSignature (permintaan httpservletRequest, httpservletResponse response) melempar ioException, parseException {// dapatkan halaman tanda tangan tautan string = request.getParameter ("Url"); Format SimpleDateFormat = new SimpleDateFormat ("yyyy-mm-dd hh: mm: ss"); // Dapatkan tag dari database dan periksa apakah tag berakhir. Tiket oldTicket = ticketrepositorysolr.getticketbyId ("20160114Wiimmediamrylsong1152"); if (oldTicket == null) {// Pertama kali Anda mengakses, tag tidak ada. executeticket (respons, "1", url, format); kembali nol; } else {// tag ada, tentukan apakah tag diatur waktunya string oldAcquiretime = oldTicket.getAcquiretime (); perbedaan panjang = format.parse (format.format (tanggal baru ())). getTime ()-format.parse (oldacquiretime) .getTime (); if (perbedaan> 71000000) {// Tag timeout, buka server WeChat untuk meminta tag timeout adalah 7200 detik (72000000 milidonds) Executeticket (respons, "2", url, format); kembali nol; } else {// Tag belum menghitung waktu/*** Catatan* 1. Noncestr dan stempel waktu yang digunakan untuk tanda tangan harus sama dengan noncestr dan cap waktu di wx.config. * 2. URL yang digunakan untuk tanda tangan harus menjadi URL lengkap dari halaman yang memanggil antarmuka JS. * 3. Untuk alasan keamanan, pengembang harus menerapkan logika tanda tangan di sisi server. ? SignatureBean SignatureBean = New SignatureBean (); SignatureBean.setnoncestr (oldTicket.getNoncestr ()); SignatureBean.setsignature (tanda tangan); SignatureBean.settimestamp (oldticket.gettimestamp ()); SignatureBean.setUrl (URL); response.setContentType ("Teks/html; charset = utf-8"); response.getWriter (). Print (GSON baru (). TOJSON (SignatureBean)); kembali nol; }}}/** * * <p> Proyek: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * * <p> Deskripsi: Metode untuk memperbarui dan mendapatkan tiket. Karena SOLR digunakan, pembaruannya sama dengan yang baru. Jika tidak ada ID, itu akan ditambahkan. If it is responsible, update</p> * *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-15 09:45:00 am * */ public void executeTicket(HttpServletResponse response,String flag,String url,SimpleDateFormat format) throws IOException{ //Get the signature and then the string GetRandomStr randomStr = baru getRandomStr (); String noncestr = randomstr.getRandomString (15); // Dapatkan string timestamp tanda tangan timestamp = long.toString (System.currentTimeMillis ()); // Minta AccessToken String AccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=y Anda appid & rahasia = kunci Anda"; String tokenJson = weixInutil.httpRequest (accessTokenUrl, "get", null); GSON GSON = GSON baru (); ShareAccess_token token = gson.fromjson (tokenjson, shareAccess_token.class); String ke = token.getAccess_token (); // Dapatkan tag string urlticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+to+"& type = jsapi"; String ticketjson = weixInutil.httpRequest (urlticket, "get", null); Tiket tiket = gson.fromjson (ticketjson, ticket.class); String t = ticket.getticket (); // string uuid = uuid.randomuuid (). Tostring (). Trim (). Replaceall ("-", ""); // ID tiket saya adalah waktu akuisisi string mati = format.format (tanggal baru ()); Ticket.settid ("20160114Wiimmediamrylsong1152"); Ticket.setAcquiretime (Acquiretime); Ticket.settimestamp (timestamp); Ticket.setnoncestr (noncestr); // Karena SOLR digunakan, metode memperbarui dan menambahkan adalah sama. Anda dapat memodifikasinya sesuai dengan kebutuhan spesifik Anda. Artikel ini tidak akan lagi memposting kode. if (flag.equals ("2")) {ticketrepositorysolr.addtickettosolr (tiket); } else {ticketrepositorysolr.addtickettosolr (tiket); } /*** Catatan* 1. Noncestr dan stempel waktu yang digunakan untuk tanda tangan harus sama dengan noncestr dan cap waktu di wx.config. * 2. URL yang digunakan untuk tanda tangan harus menjadi URL lengkap dari halaman yang memanggil antarmuka JS. * 3. Untuk alasan keamanan, pengembang harus menerapkan logika tanda tangan di sisi server. * * Menurut titik 1, mudah untuk membuat kesalahan saat mengkonfigurasi tanda tangan. Anda perlu melewati non -cestr dan stempel waktu yang menghasilkan tiket ke klien * */ string Signature = Signature (T, Timestamp, NonCestr, URL); SignatureBean SignatureBean = New SignatureBean (); SignatureBean.setnoncestr (noncestr); SignatureBean.setsignature (tanda tangan); SignatureBean.settimestamp (timestamp); SignatureBean.setUrl (URL); response.setContentType ("Teks/html; charset = utf-8"); response.getWriter (). Print (GSON baru (). TOJSON (SignatureBean)); }/** * * <p> Proyek: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * * <p> Deskripsi: tanda tangan berdasarkan tag, cap waktu, kunci, url </p> * * <p> Perusahaan: wiimedia </p> * *@athor: AMRIA: DATE: WIIMEDIA </P> * *@ATHOR; Private String Signature (String JSAPI_TICKET, String Timestamp, String NonCestr, String URL) {jsapi_ticket = "jsapi_ticket =" + jsapi_ticket; timestamp = "timestamp =" + timestamp; noncestr = "noncestr =" + noncestr; url = "url =" + url; String [] arr = string baru [] {jsapi_ticket, timestamp, noncestr, url}; // Urutkan token kamus, stempel waktu, non -cestr, parameter URL arrays.sort (ARR); StringBuilder Content = New StringBuilder (); untuk (int i = 0; i <arr.length; i ++) {content.append (arr [i]); if (i! = arr.length - 1) {content.append ("&"); }} MessageScageSest md = null; String tmpstr = null; coba {md = messageDigest.getInstance ("sha-1"); // splice tiga string parameter ke dalam string untuk byte enkripsi sha1 [] digest = md.digest (content.toString (). GetBytes ()); tmpstr = bytetoStr (digest); } catch (nosuchalgorithMexception e) {e.printstacktrace (); } content = null; mengembalikan tmpr; } / ** * Konversi byte menjadi hexadecimal string * * @param mbyte * @return * / private static string bytetohexstr (byte mbyte) {char [] digit = {'0', '1', '2', '3', '4', '5', '6', '', '', ',', ',', '', ',', '', '', 'E', 'f'}; char [] temparr = char baru [2]; temparr [0] = digit [(mbyte >>> 4) & 0x0f]; temparr [1] = digit [mbyte & 0x0f]; String s = string baru (temparr); kembali S; } / ** * Konversi array byte ke string hexadecimal * * @param bytearray * @return * / private static string bytetoStr (byte [] byteArray) {string strdigest = ""; untuk (int i = 0; i <bytearray.length; i ++) {strdigest+= bytetoHexstr (bytearray [i]); } return strdigest; } kelas shareAccess_token {private string access_token; string pribadi kedaluwarsa_in; string publik getAccess_token () {return access_token; } public void setAccess_Token (String accessToken) {access_token = accessToken; } public String getExpires_in () {return excires_in; } public void setExpires_in (String kedaluwarsa) {Expires_in = Expiresin; }}}2. Kode Klien.
<script type = "text/javascript"> var url = window.location.href; var artikelid = ""; var sharetitle = "informasi medis besok"; var shareimgurl = ""; var userInfo = localstorage.getItem ("_ userInfo"); var timestamp; var noncestr; var tanda tangan; //Get the signature $.ajax({ type: "GET", url: "WeixinshareController/Api/Inteface/getSignature", //data:{timestamp:timestamp,noncestr:noncestr,url:url}, data:{url:url}, success: function(data){ var objData=JSON.parse(data); Timestamp = Objdata.Timestamp; fungsi wxshare () {wx.config ({debug: false, // nyalakan mode debug, nilai pengembalian semua API yang disebut akan diberitahu pada klien. Untuk melihat parameter yang diteruskan, Anda dapat membukanya di sisi PC. Parameter akan dicetak melalui log dan hanya akan dicetak pada sisi PC. dari cap waktu akun resmi: cap waktu, // Diperlukan, menghasilkan cap waktu dari tanda tangan noncestr: noncestr, // Diperlukan, menghasilkan string acak tanda tangan tanda tangan: tanda tangan, // diperlukan, penandatanganan, lihat Lampiran 1 JSAPILIST: ['OnMenushareAppMessage'] // Diperlukan, Daftar JSApilist: ['OnMenushareAppMessage'] / / Dibutuhkan, Daftar JSApilist: ['onMenushareAppMessage'] / / Dibutuhkan, Daftar JSApilists JSE JSE BEGUNA BURUK SEMUA YANG DIGUNAKAN ' } wx.ready (function () {// Setelah verifikasi informasi konfigurasi, metode yang siap akan dijalankan. Semua panggilan antarmuka harus diperoleh setelah antarmuka konfigurasi mendapatkan hasilnya. // Config adalah operasi asinkron dari klien. Oleh karena itu, jika Anda perlu memanggil antarmuka yang relevan ketika halaman yang dipenuhi. be called directly without putting them in the ready function. //-------------"Share to friends" wx.onMenuShareAppMessage({ title: "Tomorrow's Medical Information", // Share title desc: shareTitle, // Share description link: url, // Share link imgUrl: shareImgUrl, // Share icon type: '', // Share type, music, video or link, do not fill in the default link dataUrl: '', // Jika jenisnya adalah musik atau video, Anda perlu menyediakan tautan data, default adalah keberhasilan kosong: function () {// fungsi callback dieksekusi setelah pengguna mengkonfirmasi berbagi,}, batal: function () {// fungsi callback dieksekusi setelah pengguna membatalkan berbagi}}); //-----------------------"Share to friends" wx.onMenuShareTimeline({ title: 'Tomorrow Medical Information', // Share title link: '', // Share link imgUrl: shareImgUrl, // Share icon success: function () { // Callback function executed after user confirms sharing}, cancel: function () { // Callback function executed after user cancels sharing} }); // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Berbagi}, batal: function () {// fungsi panggilan balik dieksekusi setelah pengguna membatalkan berbagi}}); // ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------3. Alat dan model yang diperlukan oleh server
① Tiket
paket com.wimedia.model; tiket kelas publik {private string tid; tiket string pribadi; private string errcode; private string errmsg; string pribadi kedaluwarsa_in; Waktu Akuisisi String Pribadi; string pribadi noncestr; timestamp string pribadi; Tiket Umum (TID String, Tiket String, String ErrCode, String ERRMSG, String Expiresin, String AcquisitionTime, String NonCestr, String Timestamp) {super (); this.tid = tid; this.ticket = tiket; this.errcode = errcode; this.errmsg = errmsg; kedaluwarsa_in = kedaluwarsa; this.acquiretime = Acquiretime; this.noncestr = noncestr; this.timestamp = timestamp; } public string getTid () {return tid; } public void settid (string tid) {this.tid = tid; } public String getTicket () {return ticket; } public void seticket (string ticket) {this.ticket = ticket; } public String getErrCode () {return errcode; } public void seterRcode (String errCode) {this.errcode = errCode; } public string getErrMSG () {return errmsg; } public void seterRMSG (string errmsg) {this.errmsg = errmsg; } public String getExpires_in () {return excires_in; } public void setExpires_in (String kedaluwarsa) {Expires_in = Expiresin; } public string getAcquiretime () {return AcquisitionTime; } public void setAcquiretime (String Acquiretime) {this.acquiretime = Acquiretime; } public String getNoncestr () {return noncestr; } public void setNoncestr (String noncestr) {this.noncestr = noncestr; } public String getTimestamp () {return timestamp; } public void setTimestamp (string timestamp) {this.timestamp = timestamp; }} ② Bisnis yang ditambahkan ke database diimplementasikan sesuai dengan kebutuhan Anda.
③ GetRandomstr
Paket com.wiimedia.utils; import java.util.random; kelas publik getRandomStr {/** * * <p> Proyek: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * <p> Deskripsi: Hasilkan string instan </p> * * * *@Tanggal: 2016-7-14 11:14:46 AM * */ Public String getRandomString (panjang int) {string base = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; Acak acak = acak baru (); StringBuffer SB = StringBuffer baru (); untuk (int i = 0; i <panjang; i ++) {int number = random.nextInt (base.length ()); SB.Append (base.charat (angka)); } return sb.toString (); }}④ SignatureBean
paket com.wimedia.utils; kelas publik SignatureBean {private string noncestr; URL string pribadi; timestamp string pribadi; tanda tangan string pribadi; Public String getNoncestr () {return noncestr; } public void setNoncestr (String noncestr) {this.noncestr = noncestr; } public String getUrl () {return url; } public void setUrl (string url) {this.url = url; } public String getTimestamp () {return timestamp; } public void setTimestamp (string timestamp) {this.timestamp = timestamp; } public string getSignature () {return Signature; } public void setSignature (String Signature) {this.Signature = Signature; }}⑤ weixinutil
Paket com.wimedia.utils.weixin; import java.io.bufferedreader; impor java.io.inputstream; import java.io.inputStreamReader; impor java.io.outputStream; impor java.net.connectException; impor java.net.urets java.net.connectException; impor java.net.urets; javax.net.ssl.sslcontext; import javax.net.ssl.sslsocketfactory; import javax.net.ssl.trustManager;/** * * <p> Proyek: mryl_phone_v2 </p> * * <p> *<p>Company:Wiimedia</p> * *@Athor:SongJia * *@Date:2016-7-15 09:37:13 am * */public class WeixinUtil { /** * Initiate https request and get the result* * @param requestUrl Request Address* @param requestMethod Request Method (GET, POST) * @param outputStr Data submitted* @return JSONObject(get the attribute Nilai objek JSON melalui JSONObject.get (key)) */ public static String httpRequest (String requestUrl, string requestMethod, string outputStr) {stringBuffer buffer = stringBuffer baru (); Coba {// Buat objek SSLContext dan inisialisasi trustManager [] tm = {new Myx509TrustManager ()}; Sslcontext sslcontext = sslcontext.getInstance ("ssl", "sunjsse"); sslcontext.init (null, tm, java.security.securerandom ()) baru; // Dapatkan objek SSLSocketFactory dari objek SSLContext SSLSocketFactory SSF = sslcontext.getSocketFactory (); Url url = url baru (requestUrl); HttpsurlConnection httpurlconn = (httpsurlconnection) url.openconnection (); httpurlconn.setsslsocketfactory (SSF); httpurlconn.setDoOutput (true); httpurlconn.setdoInput (true); httpurlconn.setusecaches (false); // Set Metode Permintaan (GET/POST) HTTPURLCONN.SETREQUESTMETHOD (RequestMethod); if ("get" .equalsignorecase (requestMethod)) httpurlconn.connect (); // Ketika ada data yang perlu diserahkan jika (null! = OutputStream outputStream = httpurlconn.getoutputStream (); // Perhatikan format pengkodean untuk mencegah outputStream.write output. inputStream = httpurlconn.getInputStream (); buffer.append(str); } bufferedReader.close(); inputStreamReader.close(); // Release the resource inputStream.close(); inputStream = null; httpUrlConn.disconnect(); return buffer.toString(); } catch (ConnectException ce) { ce.printStackTrace(); } catch (Exception e) {E.PrintStackTrace ();4. Pada titik ini, fungsi berbagi telah dikembangkan, tetapi Anda akan menghadapi banyak masalah saat menghasilkan tanda tangan. Berikut adalah beberapa metode pemecahan masalah untuk kegagalan WX.config.
① Konfirmasikan apakah tanda tangan yang dihasilkan benar di http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign yang disediakan oleh WeChat untuk verifikasi
② Apakah noncestr, cap waktu yang digunakan dalam wx.config konsisten dengan noncestr yang sesuai dan cap waktu yang digunakan untuk menandatangani ... seperti di atas (1. Kode server)
(Ada kemungkinan bahwa karena masalah pesanan pemuatan halaman JS, tanda tangan yang dihasilkan server, noncestr, dan cap waktu tidak diperoleh di wx.config).
③ Konfirmasikan bahwa URL adalah URL lengkap dari halaman, termasuk bagian parameter GET yang perlu dihapus dari # berikut
④ Apakah appID dalam konfigurasi konsisten dengan appid yang digunakan untuk mendapatkan jsapi_ticket?
⑤ error {errmsg: config: ok} adalah pengembalian normal mode debugging dan matikan mode debug. OKE
wx.config debug: false,
Artikel ini telah dikompilasi menjadi "Ringkasan Tutorial Pengembangan Android WeChat", dan "Java WeChat Development Tutorial Ringkasan" menyambut semua orang untuk dipelajari dan dibaca.
Di atas adalah semua konten artikel ini. Saya harap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.