Разработка функций совместного использования WeChat
После дня я разработал функцию отправки WeChat друзьям и делиться ею с кругом моих друзей. Я поделюсь этим с вами здесь, чтобы избежать обхода.
1. Серверная программа
пакет com.wimedia.controller; импорт java.io.ioexception; import java.security.messagedigest; импорт java.security.nosuchalgorithmexception; import java.text.parseexception; импорт java.text.simpledateformat; import java.utl.Arrays; импорт. javax.servlet.http.httpservlectrequest; import javax.servlet.http.httpservletresponse; импорт org.springframework.beans.factory.annotation.autowired; импорт org.springframe.stepolype.contory. org.springframework.web.bind.annotation.requestmapping; импорт com.google.gson.gson; импорт com.wimedia.model.ticket; импорт com.wimedia.service.articlesolrservice; импорт com.wimedia.service.ticketRepository; com.wimedia.utils.getrandomstr; import com.wimedia.utils.signature; import com.wimedia.utils.weixin.weixinutil;/** * * * <p> Проект: mryl_phone_v2 </p> * * <p> Пакет: com.wimedia.controller </p> *<p> Компания: wimedia </p> * *@athor: songjia * *@Дата: 2016-7-15 09:34:10 AM * */@Controller@requestMapping ("/weixinshareController/api/inteface") public classosolorsolorsolorsolorsolorsolorsolorsolorsolorsolposolorsolorsolorsolorsolorsolorsolorsolorsolorsolorsolorsolorsolorsolor @Requestmapping ("/getSignature") public String getSignature (httpservlectrequest, httpservletresponse response) throws ioexception, parseexception {// Получить ссылку на страницу подписи url = request.getParameter ("url"); SimpleDateFormat format = new SimpleDateFormat ("yyyy-mm-dd HH: MM: SS"); // Получить тег из базы данных и проверить, истекает ли тег. Билет OldTicket = TicketRepositorysolr.getTicketByid ("20160114wiimmediamrylsong1152"); if (oldticket == null) {// В первый раз, когда вы получаете доступ, тег не существует. executeTicket (ответ, «1», URL, формат); вернуть ноль; } else {// существует тег, определите, является ли тег временем string letcquiretime = oldticket.getacquiretime (); длинная разница = format.parse (format.format (new Date ()). gettime ()-format.parse (allacquiretime) .gettime (); if (разница> 71000000) {// The Tag Timeout, перейдите на сервер WeChat, чтобы запросить тайм -аут тега составляет 7200 секунд (72000000 миллисекунд) ExecuteTicket (ответ, «2», URL, формат); вернуть ноль; } else {// Тэг не истекал/*** Примечания* 1. Неиседжная и временная метка, используемые для подписи, должны быть такими же, как и неэптрос и временной метки в wx.config. * 2. URL, используемый для подписи, должен быть полным URL -адресом страницы, вызывающего интерфейс JS. * 3. По соображениям безопасности разработчики должны реализовать логику подписи на стороне сервера. ***** Легко допускать ошибки при настройке подписи в соответствии с точкой 1. Вам необходимо передавать неэкестру и временной метки, которая генерирует билет на клиенту ****/ строка Signature = Signature (OldTicket.getTicket (), OldTicket.getTimeStamp (), OldTicket.getNoNcestR (), url); SignatureBean Signature Bean = New SignatureBean (); SignatureBean.SetNonCestR (OldTicket.getNoncestR ()); SignatureBean.Setsignature (подпись); SignatureBean.SetTimeStamp (OldTicket.getTimeStamp ()); SignatureBean.Seturl (URL); response.setContentType ("text/html; charset = utf-8"); response.getWriter (). print (new Gson (). Tojson (Signature)); вернуть ноль; }}}/** * * <p> Project: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * * <p> Описание: метод для обновления и получения билетов. Поскольку используется Solr, обновление такое же, как и новое. Если нет идентификатора, он будет добавлен. Если это ответственность, обновление </p> * * <p> Компания: wiimedia </p> * *@athor: songjia * *@Дата: 2016-7-15 09:45:00 Am * */public void executiceteTicket (httpservletrespons Getrandomstr (); String noncestr = randomstr.getrandomString (15); // Получить подпись временной метки строки timeStamp = 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 (); // Получить tag String urlticket = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+to+"& type = jsapi"; String ticketjson = weixinutil.httprequest (urlticket, "get", null); Билет билета = gson.fromjson (ticketjson, ticket.class); String t = ticket.getTicket (); // string uuid = uuid.randomuuid (). // мой идентификатор билета является мертвой строкой Time = format.format (new Date ()); ticket.settid ("20160114wiimmediamrylsong1152"); ticket.setacquiretime (acciertime); ticket.settimestamp (timestamp); ticket.setnoncest (noncestry); // Поскольку используется Solr, метод обновления и добавления одинаково. Вы можете изменить его в соответствии с вашими конкретными потребностями. Эта статья больше не будет публиковать код. if (flag.equals ("2")) {ticketRepositorysolr.addtickettosolr (билет); } else {ticketRepositorysolr.addtickettosolr (билет); } /*** Примечания* 1. Неэкестром и временная метка, используемая для подписи, должны быть такими же, как и неэптрой и временной меткой в wx.config. * 2. URL, используемый для подписи, должен быть полным URL -адресом страницы, вызывающего интерфейс JS. * 3. По соображениям безопасности разработчики должны реализовать логику подписи на стороне сервера. * * Согласно пункту 1, при настройке подписи легко ошибочно. Вам необходимо передать неэкестру и временной метке, которая генерирует билет на клиент * */ строка Signature = Signature (T, TimeStamp, Noncestr, URL); SignatureBean Signature Bean = New SignatureBean (); SignatureBean.SetNONCESTR (не CESTR); SignatureBean.Setsignature (подпись); SignatureBean.SetTimeStamp (TimeStamp); SignatureBean.Seturl (URL); response.setContentType ("text/html; charset = utf-8"); response.getWriter (). print (new Gson (). Tojson (Signature)); }/** * * <p> Проект: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * * <p> Описание: подпись на тегах, временные метки, ключи, urls </p> * * <p>: Wiimedia </p> * *@athor: songjia *@@@@@@ather: wiimedia </p> *@athor: songjia *@@@@@@@@at aterial: 2016-7 Подпись частной строки (string jsapi_ticket, строка TimeStamp, String uncestr, String url) {jsapi_ticket = "jsapi_ticket =" + jsapi_ticket; TimeStamp = "TimeStamp =" + TimeStamp; noncestr = "noncestr =" + noncestr; url = "url =" + url; String [] arr = new String [] {jsapi_ticket, timestamp, uncestr, url}; // Сортировать токен словаря, временная метка, несестры, параметры URL Arrays.sort (arr); StringBuilder Content = new StringBuilder (); for (int i = 0; i <arr.length; i ++) {content.append (arr [i]); if (i! = arr.length - 1) {content.append ("&"); }} Messagegegest md = null; String tmpstr = null; try {md = messagegest.getinstance ("sha-1"); // Сплайсировать три строки параметров в строку для шифрования SHA1 Byte [] digest = md.digest (content.toString (). GetBytes ()); tmpstr = bytetostr (digest); } catch (nosuchalgorithmexception e) {e.printstacktrace (); } content = null; вернуть tmpstr; } /** * Convert bytes to hexadecimal string* * @param mByte * @return */ 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); возврат 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; Приватная строка истекает_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 TimeStamp; var noncestr; Подпись VAR; // Получить подпись $ .ajax ({type: «Get», url: «weixinsharecontroller/api/inteface/getsignature», // data: {timestamp: timestamp, noncestr: uncestr, url: url}, data: {url: url}, succest: function (data) {var objdAprse; TimeStamp = objdata.Timestamp; function wxshare () {wx.config ({Debug: false, // Включение режима отладки, возвращаемые значения всех API, вызванных, будут предупреждены на клиенте. Чтобы просмотреть пропущенные параметры, вы можете открыть их на стороне ПК. identifier of the official account timestamp:timestamp, // Required, generate the timestamp of the signature nonceStr: noncestr, // Required, generate the random string of signature signature: signature, // Required, signing, see Appendix 1 jsApiList: [ 'onMenuShareAppMessage' ] // Required, list of JS interfaces to be used, and list of all JS interfaces is shown in Appendix 2 }); } wx.ready (function () {// После проверки информации о конфигурации, метод готового. Вызовывают непосредственно, не помещая их в функцию готового. // Если тип является музыкой или видео, вам необходимо предоставить ссылку на данные, по умолчанию пустое успех: function () {// Функция обратного вызова, выполненная после того, как пользователь подтверждает общий доступ,}, cancel: function () {// Функция обратного вызова, выполненная после того, как пользователь отменит общий доступ}}); // ----------------------- "Поделиться с друзьями" wx.onmenushareTimeline ({title: 'Завтра медицинская информация', // поделиться ссылкой на заголовок: '', // поделиться ссылкой imgurl: shareImgurl, // поделиться успехом значка: function () {// Функция обратного вызова, выполненное после завершения пользовательского подтверждения}, function () {// Callback Function Functed atfected Procement); // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------. Обмен}, Cancel: function () {// Функция обратного вызова, выполненная после того, как пользователь отменил общий доступ}}); // --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------3. Инструменты и модели, требуемые сервером
① Билет
пакет com.wimedia.model; билет открытого класса {private String Tid; частный билет строк; Приватная строка Errcode; Приватная строка Errmsg; Приватная строка истекает_in; частное приобретение строки; частная строка не Cestr; Частная строковая временная метка; public Ticket (String Tid, String Ticket, String errcode, String errmsg, String asciresin, String uquisitiontime, String noncest, String TimeStamp) {super (); this.tid = tid; this.ticket = билет; this.errcode = errcode; this.errmsg = errmsg; истекает_ин = истекает; this.acquiretime = acceiretime; 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 Centicket (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 aquisitionTime; } public void setAcquireTime (String accierTime) {this.AcquireTime = acpireTime; } public String getNonCestR () {return noncestr; } public void setNonCestR (String noncestr) {this.noncestr = noncest; } public String getTimestAmp () {return TimeStamp; } public void setTimeStamp (String TimeStamp) {this.TimestAmp = timeStamp; }} ② Бизнес, добавленный в базу данных, реализуется в соответствии с вашими потребностями.
③ Getrandomstr
Пакет com.wiimedia.utils; import java.util.random; public class getrandomstr {/** * * <p> Проект: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * <p>: генерируйте мгновенную строку </p> * <p>: *@Дата: 2016-7-14 11:14:46 AM * */ public String getRandomString (int length) {String base = "abcdefghijklmnopqrstuvwxyz0123456789"; Случайный случайный = new Random (); StringBuffer sb = new StringBuffer (); for (int i = 0; i <length; i ++) {int number = random.nextint (base.length ()); sb.append (base.charat (номер)); } вернуть sb.toString (); }}④ Signature Bean
пакет com.wimedia.utils; public Class SignatureBean {private String noncestr; частная строковая URL; Частная строковая временная метка; Частная строковая подпись; public String getNonCestR () {return noncest; } public void setNonCestR (String noncestr) {this.noncestr = noncest; } 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 (строковая подпись) {this.Signature = Signature; }}⑤ Weixinutil
пакет com.wimedia.utils.weixin; импорт java.io.bufferedReader; импорт java.io.inputStream; импорт java.io.inputStreamReader; импорт java.io.outputStream; импорт java.net.concexception; импорт java.net.Url; import.Miporm.net.Sl.HttpsUR; javax.net.ssl.sslcontext; import javax.net.ssl.sslsocketFactory; import javax.net.ssl.trustmanager;/** * * <p> Проект: mryl_phone_v2 </p> * * <p>: mryl_phone_v2 </p> * <p> * <p> Компания: wiimedia </p> * * @athor: songjia * * @Дата: 2016-7-15 09:37:13 AM * */Public Class WeixInutil {/** * Инициировать запрос https и получить результат * * @param requesturl Адрес * @param requestmethod (get, post) * @param output объекта JSON через 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.openconcenection (); httpurlconn.setsslsocketfactory (ssf); httpurlconn.setDoOutput (true); httpurlconn.setDoinput (true); httpurlconn.setusecaches (false); // Установить метод запроса (get/post) httpurlconn.setrequestmethod (requestmethod); if ("Get". EqualsIgnoreCase (requestMethod)) httpurlconn.connect (); // Когда есть данные, которые необходимо отправить, если (NULL! httpurlconn.getinputstream (); inputStream.close ();4. На данный момент была разработана функция совместного использования, но вы столкнетесь с множеством проблем при создании подписи. Вот некоторые методы устранения неполадок для сбоев wx.config.
① Убедитесь, правильная ли сгенерированная подпись в http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign предоставлена WeChat для проверки
② Независимо от того, согласуется ли не CESTR, TimeStamp, используемая в wx.config с соответствующей неэкровской и временной меткой, используемой для подписи ... как указано выше (1. Код сервера)
(Возможно, что из-за задачи загрузки на странице JS в wx.config, созданная сервером, подпись, несестры и временные метки.
③ Убедитесь, что URL -адрес является полным URL -адресом страницы, включая деталь GET, которая необходимо удалить из следующего #
④ Appid In Config в соответствии с Appid, используемым для получения jsapi_ticket?
⑤ Ошибка {errmsg: config: OK} - это нормальное возвращение режима отладки и отключить режим отладки. ХОРОШО
WX.Config Debug: False,
Эта статья была составлена в «Резюме для разработки Android WeChat», и «Резюме по разработке Java WeChat» приветствует всех учиться и читать.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.