您的位置:首页 > 移动开发 > 微信开发

菜鸟日记(yzy) 微信公众号网页的开发基础(微信接口调用)

2017-12-06 15:50 405 查看
到现在为止,在新公司呆了也有几个月了,很莫名的自己从Android开发,变成了web app的开发,所以写一下关于自己这一两个月对于微信公众号的开发心得,说到底,微信公众号的前台除去要调用微信的接口,也就单纯的H5开发而已,看看微信的网页开发文档就知道,想要用微信的接口必须先注册一个公众号,公司就用服务号,个人就用订阅号,当然,如果只是想测试或者玩一玩,又想用服务号的接口(比如说硬件接口),那我们可以注册一个测试号(在开发者工具中就可以找到了),下面就说一下具体流程。一:成为开发者如果想开发微信公众号网页,我们必须使自己的公众号成为开发者,在基本配置中,启动服务器配置:你会发现要填写的有服务器地址(url),token,还有解密密匙,解密密匙我们不管,消息加密选择明文就可以了。而服务器我是用servlet写的,比较简单,反正又不是写项目,能不用框架就不用,代码如下:TokenServlet .java代码:WeixinUtil.javapublic class TokenServlet extends HttpServlet {private static final long serialVersionUID = 1L;         @Overridepublic void init() throws ServletException {// TODO Auto-generated method stubSignatureThread thread = new SignatureThread();new Thread(thread)..start();}/*** @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)*/protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubPrintWriter out = response.getWriter();     String signature = request.getParameter("signature");    String timestamp = request.getParameter("timestamp");    String nonce = request.getParameter("nonce");    String echostr = request.getParameter("echostr");         if(SignUtil.checkSignature(signature, timestamp, nonce)){     out.print(echostr);           System.out.println("微信服务验证成功!");    }    out.close();    out = null;}/*** @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)*/protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// TODO Auto-generated method stubthis.doGet(request, response);}}SignUtil.java代码 // 与接口配置信息中的Token要一致      private static String token = "";        /**      * 验证签名      *       * @param signature      * @param timestamp      * @param nonce      * @return      */      public static boolean checkSignature(String signature, String timestamp, String nonce) {          String[] arr = new String[] { token, timestamp, nonce };          // 将token、timestamp、nonce三个参数进行字典序排序          Arrays.sort(arr);          StringBuilder content = new StringBuilder();          for (int i = 0; i < arr.length; i++) {              content.append(arr[i]);          }          MessageDigest md = null;          String tmpStr = null;            try {              md = MessageDigest.getInstance("SHA-1");              // 将三个参数字符串拼接成一个字符串进行sha1加密              byte[] digest = md.digest(content.toString().getBytes());              tmpStr = byteToStr(digest);          } catch (NoSuchAlgorithmException e) {              e.printStackTrace();          }            content = null;          // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信          return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;      }        /**      * 将字节数组转换为十六进制字符串      *       * @param byteArray      * @return      */      private static String byteToStr(byte[] byteArray) {          String strDigest = "";          for (int i = 0; i < byteArray.length; i++) {              strDigest += byteToHexStr(byteArray[i]);          }          return strDigest;      }        /**      * 将字节转换为十六进制字符串      *       * @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);          return s;      }}最后,很重要的一点要说明:上述项目要放在公网上行,端口也要用80端口。二:wx.config配置当我们查看微信开发文档时,注意到微信接口调用有几个步骤,首先wx.config和wx.ready这两个是必可少的,后者还好说,前面简直坑的不要不要的,代码如下:
<script type="text/javascript" src="js/jsweixin-1.2.0.js"></script>
<script type="text/javascript">
wx.config({
beta: true, // 开启内测接口调用,注入wx.invoke方法
debug: true, // 开启调试模式
appId: '', // 第三方app唯一标识
timestamp: , // 生成签名的时间戳
nonceStr: '', // 生成签名的随机串
signature: '',// 签名
// 需要使用的jsapi列表
jsApiList: [
'getLocation'
]
});
wx.ready(function(){wx.checkJsApi({jsApiList:['getLocation'],success:function(res){alert(JSON.stringify(res));wx.getLocation({type:'wgs84',success:function(res){alert("location:("+res.latitude+","+res.longitude+")");}})}});})
这段代码是调用了微信的定位接口,APPID要注意是正式版的ID还是测试号的,在开发前我们注意要填写IP白名单和JS接口安全域名,否则,是没有使用权限的,IP地址是多少可以通过获取access_token接口来看返回的IP获取,可以通过至于签名的获取方式由以下代码实现:三:获取签名[b]WeixinUtil.java代码:[/b]public class WeixinUtil {/**   *    * @param appid   * @param appsecret   * @return   */   public static AccessToken getAccessToken(String appid, String appsecret) {         String get_token_url = "https://api.weixin.qq.com/cgi-bin/token?"    + "grant_type=client_credential&appid=APPID&"    + "secret=APPSECRET";       String line = new String();       AccessToken accessToken = null ;        BufferedReader reader ;       try {HttpClient httpClient = new DefaultHttpClient();HttpGet httpGet = new HttpGet(get_token_url);HttpResponse response = httpClient.execute(httpGet);if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {HttpEntity httd4a1pEntity = response.getEntity(); reader = new BufferedReader(new InputStreamReader(httpEntity.getContent()));if ((line = reader.readLine()) != null) {accessToken = AccessToken.getAccessToken(line);}}} catch (Exception e) {// TODO: handle exception}             return accessToken;    }       /**     * sapi_ticket    *      * @param appid     * @param appsecret    * @return     */    public static JsapiTicket getJsapiTicket(String accessToken) {           String jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+accessToken+"&type=jsapi";    System.out.println(jsapi_ticket_url);    JsapiTicket jsapiticket = null;     BufferedReader reader ;    String line = new String();       if(accessToken != null){     try {     HttpClient httpClient = new DefaultHttpClient();   HttpGet httpGet = new HttpGet(jsapi_ticket_url);     HttpResponse response = httpClient.execute(httpGet);   if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {HttpEntity httpEntity = response.getEntity(); reader = new BufferedReader(new InputStreamReader(httpEntity.getContent()));if ((line = reader.readLine()) != null) {System.out.println(line);jsapiticket = JsapiTicket.getTicket(line);}}     }catch(Exception e){          }    }       return jsapiticket;    }       public static Signature getSignature(JsapiTicket ticket) {    String noncestr = UUID.randomUUID().toString().replace("-", "").substring(0, 16);//    String timestamp = String.valueOf(System.currentTimeMillis() / 1000);//    String urlLocation="http://yzy1992.duapp.com/location.html";//微信定位//     String urlDevice="http://yzy1992.duapp.com/loginPager.html";//设备触发//    String urlUerInfo="http://yzy1992.duapp.com/getUserInfo.html";    String url = "";       String jsapi_ticket = ticket.getTicket();    Signature signature = new Signature();       String signatureStr = "jsapi_ticket="+jsapi_ticket+"&noncestr="+noncestr+"×tamp="+timestamp+"&url="+url;        signatureStr = SHA1(signatureStr);            signature.setNoncestr(noncestr);    signature.setJsapi_ticket(jsapi_ticket);    signature.setSignature(signatureStr);    signature.setTimestamp(timestamp);    signature.setUrl(url);           return signature;}      public static String SHA1(String signature) {    try {             MessageDigest digest = java.security.MessageDigest.getInstance("SHA-1");             digest.update(signature.getBytes());             byte messageDigest[] = digest.digest();             // Create Hex String             StringBuffer hexString = new StringBuffer();                         for (int i = 0; i < messageDigest.length; i++) {                     String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);                     if (shaHex.length() < 2) {                         hexString.append(0);                     }                     hexString.append(shaHex);                 }                 return hexString.toString();                   } catch (NoSuchAlgorithmException e) {                 e.printStackTrace();             }             return "";  }}SignatureThread.java代码public SignatureThread() {}public void run() {    while (true) {         try {             accessToken = WeixinUtil.getAccessToken(appId, appSecret);           CallbackManager manager = null ;           if (null != accessToken) {                 System.out.println("获取access_token成功,有效时长"+ accessToken.getExpiresIn()+"秒 token:"+ accessToken.getToken());                 try{               ticket = WeixinUtil.getJsapiTicket(accessToken.getToken());                   if(ticket!=null){                   System.out.println("获取jsapiTicket成功,有效时长"+ ticket.getExpiresIn()+"秒 ticket:"+ ticket.getTicket());                    signature = WeixinUtil.getSignature(ticket);                   System.out.println("Signature为:"+signature.getSignature()+"/n"                   + "Noncestr为:" + signature.getNoncestr() + "/n"                    + "timestamp为:" + signature.getTimestamp());                   if(manager == null){                   manager = CallbackManager.getInstance();                   }                   manager.onGetSignature(signature);                                      }               }catch(Exception e){               // 如果jsapiTicket为null,60秒后再获取                     Thread.sleep(60 * 1000);                 }               // 休眠7000秒                 Thread.sleep((accessToken.getExpiresIn() - 200) * 1000);             } else {                 // 如果access_token为null,60秒后再获取                 Thread.sleep(60 * 1000);             }         } catch (InterruptedException e) {             try {                 Thread.sleep(60 * 1000);             } catch (InterruptedException e1) {              System.out.println(e1);             }             System.out.println(e);         }     }    }}  注:通过微信接口回调的数据都是使用Gson存放到bean实体类中,而线程中的signature.class中的数据通过回调函数和ajax以jsonp的数据类型给到前台(处理跨域传递数据的问题)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐