WeChat共有機能開発
1日後、私はWeChatを友人に送信し、それを友達のサークルに共有する機能を開発しました。迂回を避けるために、ここであなたと共有します。
1。サーバー側プログラム
パッケージcom.wimedia.controller; import java.io.ioexception; Import java.security.messagegest; import java.security.nosuchalgorithmexception; import java.text.parseexception; Import java.text.simpledateformat; Import java.util.util.util.util.util.util.util.util.util.util.util.util.util.itil. javax.servlet.http.httpservletrequest; Import javax.servlet.httpservletresponse; Import org.springframework.beans.factory.annotation.autowired; import org.springframework.stereoty.controller; import; org.springframework.web.bind.annotation.RequestMapping; Import com.google.gson.gson; Import com.wimedia.model.ticket; Import com.wimedia.service.articlesolrservice; Import com.wimedia.service.ticketrepository; com.wimedia.utils.getrandomstr; Import com.wimedia.utils.signaturebean; Import com.wimedia.utils.weixinutil;/** * * * <p>プロジェクト:mryl_phone_v2 </p> * * * <p> com.wimedia.controller </p> * <p> p> p> controller </p> * *<p> company:wimedia </p> * *@athor:songjia * *@date:2016-7-15 09:34:10 am * */@controller@requestmapping( "/weixinsharecontroller/api/inteface")公開クラス@RequestMapping( "/getSignature")public string gestignature(httpservletrequest request、httpservletresponse応答)IoException、parseexception {//署名ページリンク文字列url = request.getParameter( "url"); SimpleDateFormat format = new SimpledateFormat( "yyyy-mm-dd hh:mm:ss"); //データベースからタグを取得し、タグの有効期限が切れるかどうかを確認します。チケットOldTicket = TicketrePositorySolr.getTicketbyId( "20160114WiimMediamrylsong1152"); if(oldticket == null){//初めてアクセスしたとき、タグは存在しません。 executeticket(response、 "1"、url、format); nullを返します。 } else {//タグが存在し、タグが文字列oldacquiretime = oldticket.getacquiretime();長い差= format.parse(format.format(new date())) if(difference> 71000000){//タグタイムアウト、WeChatサーバーに移動してタグタイムアウトを要求します。 nullを返します。 } else {//タグはタイムアウトしていません/***注* 1。 * 2。署名に使用されるURLは、JSインターフェイスを呼び出すページの完全なURLでなければなりません。 * 3。セキュリティ上の理由から、開発者はサーバー側に署名ロジックを実装する必要があります。 *****ポイント1に従って署名を構成するときにエラーを作成するのは簡単です。クライアントへのチケットを生成する非cestrとタイムスタンプを渡す必要があります****/ string signature = signature()、oldticket.gettimestamp()、oldticket.getnoncestr()、url); SignatureBean SignatureBean = new SignatureBean(); SignatureBean.SetNonCestr(OldTicket.GetNonCestr()); signaturebean.setsignature(signature); signaturebean.settimestamp(oldticket.getTimestamp()); signaturebean.seturl(url); Response.setContentType( "text/html; charset = utf-8"); Response.getWriter()。print(new gson()。tojson(signaturebean)); nullを返します。 }}}/** * * <p>プロジェクト:mryl_phone_v2 </p> * * <p>:mryl_phone_v2 </p> * <p>説明:チケットを更新および取得する方法。 SOLRが使用されるため、更新は新しいものと同じです。 IDがない場合、追加されます。責任がある場合は、更新</p> * * <p>会社:wiimedia </p> * *@athor:songjia * *@date:2016-7-15 09:45:00 am * */public void executeTicket(htttpservletresponse応答、htttpservletresponse応答、ストリングフラグ、string flag、simpledateformat format) new getrandomstr(); string noncestr = randomsstr.getrandomstring(15); //署名タイムスタンプ文字列タイムスタンプ= long.toString(system.currenttimemillis())を取得します。 // AccessToken String AccessTokenUrl = "https://api.weixin.qqq.com/cgi-bin/token?grant_type=client_credential&appid = your appid&secret = your key"; string tokenjson = weixinutil.httprequest(accesstokenurl、 "get"、null); gson gson = new gson(); shareaccess_token token = gson.fromjson(tokenjson、shareaccess_token.class); string to = token.getacess_token(); //タグ文字列urlticket = "https://api.weixin.qq.com/cgi-bin/ticket/gettick?access_token ="+to+"&type = jsapi"; string ticketjson = weixinutil.httprequest(urlticket、 "get"、null);チケットチケット= gson.fromjson(ticketjson、ticket.class);文字列t = ticket.getTicket(); // string uuid = uuid.randomuuid()。toString()。trim()。fallingeall( " - "、 ""); //私のチケットIDは死んだ文字列取得時間= format.format(new date()); ticket.settid( "20160114wiimmediamrylsong1152"); ticket.SetAcquireTime(AcquireTime); ticket.settimestamp(タイムスタンプ); ticket.setnoncestr(noncestr); // SOLRが使用されるため、更新と追加の方法は同じです。特定のニーズに応じて変更できます。この記事は、コードを投稿しなくなります。 if(flag.equals( "2")){ticketrepositorysolr.addtickettetosolr(チケット); } else {ticketrepositorysolr.addtickettosolr(チケット); } /***注*1。署名に使用される非cestrとタイムスタンプは、wx.configの非cestrとタイムスタンプと同じでなければなりません。 * 2。署名に使用されるURLは、JSインターフェイスを呼び出すページの完全なURLでなければなりません。 * 3。セキュリティ上の理由から、開発者はサーバー側に署名ロジックを実装する必要があります。 * *ポイント1によると、署名を構成するときにエラーを簡単に作成できます。クライアントへのチケットを生成する非網とタイムスタンプを渡す必要があります * */ string signature = signature(t、timestamp、noncestr、url); SignatureBean SignatureBean = new SignatureBean(); signaturebean.setnoncestr(noncestr); signaturebean.setsignature(signature); signaturebean.settimestamp(タイムスタンプ); signaturebean.seturl(url); Response.setContentType( "text/html; charset = utf-8"); Response.getWriter()。print(new gson()。tojson(signaturebean)); }/** * * <p>プロジェクト:mryl_phone_v2 </p> * * <p>:mryl_phone_v2 </p> * * <p>説明:タグ、タイムスタンプ、キー、URLS </p> * <p>会社:wiimedia </p> *@athia *@am3:@amp:@amsia *@aimedia </p> * */ 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 = new String [] {jsapi_ticket、Timestamp、noncestr、url}; //辞書トークン、タイムスタンプ、非cestr、urlパラメーターarrays.sort(arr)を並べ替える(arr); stringbuilder content = new StringBuilder(); for(int i = 0; i <arr.length; i ++){content.append(arr [i]); if(i!= arr.length -1){content.append( "&"); }} MESSAGEDGEST MD = null;文字列tmpstr = null; try {md = mesagedigest.getInstance( "sha-1"); // 3つのパラメーター文字列がsha1暗号化byteの文字列にスプライスされます[] digest = md.digest(content.tostring()。getBytes()); tmpstr = bytetostr(digest); } catch(nosuchalgorithmexception e){e.printstacktrace(); } content = null; tmpstrを返します。 } / ** *バイトをヘキサデシマル文字列に変換 * * @param mbyte * @return * / private static string bytetohexstr(byte mbyte){char [] digit = {'0' '、' 1 '、' 2 '、' 3 '、' 4 '、' 5 'e'、 'f'}; char [] temparr = new char [2]; temparr [0] = digit [(mbyte >>> 4)&0x0f]; temparr [1] = digit [mbyte&0x0f];文字列s = new String(temparr); s; } / ** *バイト配列をヘキサデシマル文字列に変換 * * @param bytearray * @return * / private static string bytetostr(byte [] bytearray){string strdigest = ""; for(int i = 0; i <bytearray.length; i ++){strdigest+= bytetohexstr(bytearray [i]); } strdigestを返します。 } class shareaccess_token {private string access_token;プライベート文字列expires_in; public string getaccess_token(){return access_token; } public void setAccess_token(string accessToken){access_token = accessToken; } public string getExpires_in(){return expires_in; } public void setExpires_in(string 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:url}、success(data = json.parse(var objdata); TimeStamp = objdatame = objdata = objdata.log() function wxshare(){wx.config({debug:false、// debugモードをオンにすると、呼び出されたすべてのAPIの戻り値がクライアントに警告されます。パスされたパラメーターを表示するために、パラメーター情報はログを介して印刷され、PC側でのみ印刷されます。公式アカウントの識別子タイムスタンプ:タイムスタンプ、//必須、署名の非網のタイムスタンプを生成:非洞窟://必要な署名の署名のランダムな文字列を生成://必要な署名、署名、署名、jsapilistを参照:['onmenushareapmessage'] }); } wx.ready(function(){//構成情報検証の後、対応方法が実行されます。すべてのインターフェイス呼び出しは結果を取得した後に取得する必要があります。// configはクライアントの非同期操作です。それらは、準備が整った機能に直接呼ばれます。 ''、//タイプが音楽またはビデオである場合、データリンクを提供する必要があります。デフォルトは空の成功です:function(){//ユーザーが共有を確認した後に実行されたコールバック関数、}、cancel:function(){//ユーザーが共有をキャンセルした後に実行されるコールバック関数}); // ------------------------------友人に共有する "wx.onmenusharetimeline({title: 'Tomorrow Medical Information'、//共有タイトルリンク: ''、//リンクImgurl://共有アイコンの成功:function(){ //--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- The callback function executed after the user confirms the共有}、キャンセル:function(){//ユーザーが共有をキャンセルした後に実行されたコールバック関数}}); //------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------3.サーバーが必要とするツールとモデル
①チケット
パッケージcom.wimedia.model; public classチケット{private string tid;プライベート文字列チケット。プライベート文字列errcode;プライベート文字列errmsg;プライベート文字列expires_in;プライベート文字列取得時間;プライベート文字列noncestr;プライベートストリングタイムスタンプ。パブリックチケット(文字列TID、文字列チケット、文字列ERROCODE、STRING ERRMSG、STRING EXPIRESIN、STRING ACHISITIONTIME、STRING NONCESTR、STRING TIMESTAMP){super(); this.tid = tid; this.ticket = ticket; this.errcode = errcode; this.errmsg = errmsg; expires_in = expiresin; this.acquiretime = accoireTime; this.noncestr = noncestr; this.timestamp =タイムスタンプ; } public string getTid(){return tid; } public void settid(string tid){this.tid = tid; } public string getTicket(){return ticket; } public void setticket(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 expires_in; } public void setExpires_in(string expiresin){expires_in = expiresin; } public string getAcquireTime(){return acquisitionTime; } public void setacquiretime(String AcquireTime){this.acquiretime = accoireTime; } public string getNonCestr(){return noncestr; } public void setnoncestr(string noncestr){this.noncestr = noncestr; } public string getTimestamp(){return timestamp; } public void sittimestamp(String Timestamp){this.timestamp = Timestamp; }} datasデータベースに追加されたビジネスは、お客様のニーズに応じて実装されます。
getRandomStr
パッケージcom.wiimedia.utils; Import java.util.random; public class getrandomstr {/** * * <p>プロジェクト:mryl_phone_v2 </p> * * <p>:mryl_phone_vv2 </p> * * <p>説明:inscring string </p> wiimediia:wiimediia:wiimediia:wiimedia *@日付:2016-7-14 11:14:46 AM * */ public String getRandomString(int length){string base = "abcdefghijklmnopqrstuvwxyz0123456789"; RANDOM RANDOM = new Random(); stringbuffer sb = new StringBuffer(); for(int i = 0; i <length; i ++){int number = random.nextint(base.length()); sb.append(base.charat(number)); } return sb.toString(); }}signatureBean
パッケージcom.wimedia.utils; public class signaturebean {private string noncestr;プライベート文字列URL;プライベートストリングタイムスタンプ。プライベート文字列の署名。 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 sittimestamp(String Timestamp){this.timestamp = Timestamp; } public string getSignature(){return signature; } public void setSignature(string signature){this.signature = signature; }}weixinutil
パッケージcom.wimedia.utils.weixin; import java.io.bufferedreader; Import java.io.inputstream; Impture java.io.inputStreamReader; Import java.net.connectexception; Import java.net.net.url; Import Javax.net.net.sssl.sssl.sssl.sssl.sssl.ssl.ssl.ssl.sssl.sssl.net.net.net. javax.net.ssl.sslcontext; Import javax.net.ssl.sslsocketFactory; Import javax.net.ssl.trustmanager;/** * * <p>プロジェクト:mryl_phone_vhphone_v2 </p> * * * * * <p>:mryl_phone_v2 </p <p> * * * * <p> company:wiimedia </p> * * @athor:songjia * * @date:2016-7-15 09:37:13 am * */public class weixinutil {/** * requestを開始し、結果を取得 * jsonobject.get(key)) */ public static string httprequest(string requesturl、string requestmethod、string outputstr){stringbuffer buffer = new StringBuffer(); try {// sslcontextオブジェクトを作成し、trustmanagerを初期化[] tm = {new myx509trustmanager()}; sslcontext sslcontext = sslcontext.getInstance( "ssl"、 "sunjsse"); sslcontext.init(null、tm、new java.security.securerandom()); //上記のSSLSocketFactoryオブジェクトを上記のsslcontextオブジェクトから取得しますsslsocketfactory ssf = sslcontext.getSocketFactory(); url url = new url(requesturl); httpsurlconnection httpurlconn =(httpsurlconnection)url.openconnection(); httpurlconn.setsslsocketFactory(SSF); httpurlconn.setDooutput(true); httpurlconn.setDoinput(true); httpurlconn.setusecaches(false); // request method(get/post)httpurlconn.setRequestMethod(requestMethod); if( "get" .equalsignorecase(requestmethod))httpurlconn.connect(); //提出する必要があるデータがある場合(null!= outputStream outputStream = httpurlconn.getOutputStream(); //エンコード形式に注意を払って、中国のガルドoutputStream.write.write(outputstr.getBytes( "utf-8")); httpurconn.getInputStream()inputStreamReader(utf-8 ")。 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(); } return ""; }}4。この時点で、共有関数が開発されましたが、署名を生成するときに多くの問題が発生します。 wx.config障害のトラブルシューティング方法を以下に示します。
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisignで生成された署名が確認のために提供されるかどうかを確認してください
wx.configで使用されている非cestr、タイムスタンプが対応する非cestrとタイムスタンプが署名に使用されるかどうか...上記のように(1。Serverコード)
(JSページの読み込み順序の問題により、サーバーで生成された署名、非cestr、およびタイムスタンプがwx.configで取得されなかった可能性があります)。
urlがページの完全なURLであることを確認します。
confid appidは、jsapi_ticketを取得するために使用されるappidと一致していますか?
⑤エラー{errmsg:config:ok}は、デバッグモードの通常の戻りで、デバッグモードをオフにします。わかりました
wx.configデバッグ:false、
この記事は「Android Wechat Development Tutorial Summary」にまとめられており、「Java Wechat Development Tutorial Summary」は、すべての人を学び、読むことを歓迎します。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。