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

到现在为止,在新公司呆了也有几个月了,很莫名的自己从Android开发,变成了web app的开发,所以写一下关于自己这一

两个月对于微信公众号的开发心得,说到底,微信公众号的前台除去要调用微信的接口,也就单纯的H5开发而已,看看微信的网页

开发文档就知道,想要用微信的接口必须先注册一个公众号,公司就用服务号,个人就用订阅号,当然,如果只是想测试或者玩一

玩,又想用服务号的接口(比如说硬件接口),那我们可以注册一个测试号(在开发者工具中就可以找到了),下面就说一下具体

流程。


一:成为开发者


如果想开发微信公众号网页,我们必须使自己的公众号成为开发者,在基本配置中,启动服务器配置:你会发现要填写的有服务器地址(url),token,还有解密密匙,


解密密匙我们不管,消息加密选择明文就可以了。而服务器我是用servlet写的,比较简单,反正又不是写项目,能不用框架就不用,代码如下:


TokenServlet .java代码:WeixinUtil.java

public class TokenServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
      
   @Override
public void init() throws ServletException {
// TODO Auto-generated method stub


SignatureThread 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 stub

PrintWriter 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 stub
this.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获取,可以通过至于签名的获取方式由以下代码实现:


三:获取签名

WeixinUtil.java代码:

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 httpEntity = 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+"&timestamp="+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的数据类型给到

前台(处理跨域传递数据的问题)





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值