一、配置参数

参考官方文档:http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN

wx.config({

    debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。

    appId: '', // 必填,公众号的唯一标识

    timestamp: , // 必填,生成签名的时间戳

    nonceStr: '', // 必填,生成签名的随机串

    signature: '',// 必填,签名,见附录1

    jsApiList: [] // 必填,需要使用的JS接口列表,所有JS接口列表见附录2

});

所需的appId、timestamp、nonceStr、signature都需要在后台生成。

二、后台Java代码

在进行签名之前我们需要先获取到jsapi_ticket,jsapi_ticket在获取前需要先获取到access_token,jsapi_ticket的获取方式参考如下:

 1 import net.sf.json.JSONObject;
 2 
 3 public class Token {
 4 
 5     private static String access_token="";
 6     
 7     private static String jsapi_ticket = "";
 8     
 9     public static int time = 0;
10     
11     private static int expires_in = 7200;
12     
13     static{
14         Thread t = new Thread(new Runnable(){  
15             public void run(){  
16                 do{
17                     time++;
18                     try {
19                         Thread.sleep(1000);
20                     } catch (InterruptedException e) {
21                         e.printStackTrace();
22                     }
23                 }while(true);
24             }});  
25         t.start();
26     }
27     
28     public static String getToken(){
29         if("".equals(access_token)||access_token==null){
30             send();            
31         }else if(time>expires_in){
32             //当前token已经失效,从新获取信息
33             send();
34         }
35         return access_token;
36     }
37     public static String getTicket(){
38         if("".equals(jsapi_ticket)||jsapi_ticket==null){
39             send();            
40         }else if(time>expires_in){
41             //当前token已经失效,从新获取信息
42             send();
43         }
44         return jsapi_ticket;
45     }
46     private static void send(){
47         String url = WXConfig.server_token_url+"&appid="+WXConfig.appid+"&secret="+WXConfig.appsecret;
48         JSONObject json = SendHttpRequest.sendGet(url);
49         access_token = json.getString("access_token");
50         String ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+access_token+"&type=jsapi";
51         jsapi_ticket = SendHttpRequest.sendGet(ticket_url).getString("ticket");
52         time = 0;
53 //        if(!"".equals(access_token)&&!"".equals(jsapi_ticket)){
54 //            new Thread
55 //        }
56 
57     }
58 }

配置文件WXConfig.java(redirect_url在微信公众平台中的公众号设置》功能设置》JS接口安全域名

 1 public class WXConfig {
 2 
 3     public static String appid = "wxsdfsfasdfsafsdf";
 4     
 5     public static String appsecret = "8sfsdfsdfsfasdfsdfc1f3";
 6     
 7     public static String access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token";
 8     
 9     public static String oauth_url = "https://open.weixin.qq.com/connect/oauth2/authorize";
10     
11     public static String redirect_uri = "http://sdfsdfsdf";//自己的授权地址
12     
13     public static String server_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential";
14 }

http请求发送:

 2 
 3 import java.io.IOException;
 4 import java.net.URLDecoder;
 5 import java.text.DateFormat;
 6 import java.text.SimpleDateFormat;
 7 import java.util.ArrayList;
 8 import java.util.Date;
 9 import java.util.List;
10 
11 import org.apache.http.HttpResponse;
12 import org.apache.http.NameValuePair;
13 import org.apache.http.client.HttpClient;
14 import org.apache.http.client.methods.CloseableHttpResponse;
15 import org.apache.http.client.methods.HttpGet;
16 import org.apache.http.client.methods.HttpPost;
17 import org.apache.http.entity.StringEntity;
18 import org.apache.http.impl.client.CloseableHttpClient;
19 import org.apache.http.impl.client.DefaultHttpClient;
20 import org.apache.http.impl.client.HttpClients;
21 import org.apache.http.message.BasicNameValuePair;
22 import org.apache.http.params.BasicHttpParams;
23 import org.apache.http.params.HttpConnectionParams;
24 import org.apache.http.params.HttpParams;
25 import org.apache.http.util.EntityUtils;
26 
27 import net.sf.json.JSONObject;
28 
29 public class SendHttpRequest {
30 
31     /**
32      * 
33      * @param url
34      * @param jsonParam
35      * @return
36      */
37     public static JSONObject sendGet(String url){
38         
39         CloseableHttpClient httpclient = HttpClients.createDefault();
40         JSONObject jsonResult = null;
41         HttpGet method = new HttpGet(url);
42         try {
43             CloseableHttpResponse result = httpclient.execute(method);
44             if (result.getStatusLine().getStatusCode() == 200) {
45                 String str = "";
46                 try {
47                     str = EntityUtils.toString(result.getEntity());
48                     jsonResult = JSONObject.fromObject(str);
49                 } catch (Exception e) {
50                     System.out.println("get请求提交失败:" + url);
51                 }
52             }
53         } catch (IOException e) {
54             System.out.println("get请求提交失败:" + url);
55         }
56         return jsonResult;
57     }
58 }

参数组装:

String ticket = Token.getTicket();            
String noncestr = RandomStringGenerator.getRandomStringByLength(32);
            long timestamp = new Date().getTime()/1000;
            String sign =  "jsapi_ticket="+ticket+"&noncestr="//请勿更换字符组装顺序
                            +noncestr+"&timestamp="+timestamp
                            +"&url="+url+";//url为你当前访问的url路径,除去#与#后面的数据
String signature = new SHA1().getDigestOfString(sign.getBytes("utf-8"));

随机数:

package qfwx;

import java.util.Date;
import java.util.Random;

public class RandomStringGenerator {

    /**
     * 获取一定长度的随机字符串
     * @param length 指定字符串长度
     * @return 一定长度的字符串
     */
    public static String getRandomStringByLength(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();
    }

}

签名方法(网上摘取):

public class SHA1 { 
    private final int[] abcde = { 
            0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 
        }; 
    // 摘要数据存储数组 
    private int[] digestInt = new int[5]; 
    // 计算过程中的临时数据存储数组 
    private int[] tmpData = new int[80]; 
    // 计算sha-1摘要 
    private int process_input_bytes(byte[] bytedata) { 
        // 初试化常量 
        System.arraycopy(abcde, 0, digestInt, 0, abcde.length); 
        // 格式化输入字节数组,补10及长度数据 
        byte[] newbyte = byteArrayFormatData(bytedata); 
        // 获取数据摘要计算的数据单元个数 
        int MCount = newbyte.length / 64; 
        // 循环对每个数据单元进行摘要计算 
        for (int pos = 0; pos < MCount; pos++) { 
            // 将每个单元的数据转换成16个整型数据,并保存到tmpData的前16个数组元素中 
            for (int j = 0; j < 16; j++) { 
                tmpData[j] = byteArrayToInt(newbyte, (pos * 64) + (j * 4)); 
            } 
            // 摘要计算函数 
            encrypt(); 
        } 
        return 20; 
    } 
    // 格式化输入字节数组格式 
    private byte[] byteArrayFormatData(byte[] bytedata) { 
        // 补0数量 
        int zeros = 0; 
        // 补位后总位数 
        int size = 0; 
        // 原始数据长度 
        int n = bytedata.length; 
        // 模64后的剩余位数 
        int m = n % 64; 
        // 计算添加0的个数以及添加10后的总长度 
        if (m < 56) { 
            zeros = 55 - m; 
            size = n - m + 64; 
        } else if (m == 56) { 
            zeros = 63; 
            size = n + 8 + 64; 
        } else { 
            zeros = 63 - m + 56; 
            size = (n + 64) - m + 64; 
        } 
        // 补位后生成的新数组内容 
        byte[] newbyte = new byte[size]; 
        // 复制数组的前面部分 
        System.arraycopy(bytedata, 0, newbyte, 0, n); 
        // 获得数组Append数据元素的位置 
        int l = n; 
        // 补1操作 
        newbyte[l++] = (byte) 0x80; 
        // 补0操作 
        for (int i = 0; i < zeros; i++) { 
            newbyte[l++] = (byte) 0x00; 
        } 
        // 计算数据长度,补数据长度位共8字节,长整型 
        long N = (long) n * 8; 
        byte h8 = (byte) (N & 0xFF); 
        byte h7 = (byte) ((N >> 8) & 0xFF); 
        byte h6 = (byte) ((N >> 16) & 0xFF); 
        byte h5 = (byte) ((N >> 24) & 0xFF); 
        byte h4 = (byte) ((N >> 32) & 0xFF); 
        byte h3 = (byte) ((N >> 40) & 0xFF); 
        byte h2 = (byte) ((N >> 48) & 0xFF); 
        byte h1 = (byte) (N >> 56); 
        newbyte[l++] = h1; 
        newbyte[l++] = h2; 
        newbyte[l++] = h3; 
        newbyte[l++] = h4; 
        newbyte[l++] = h5; 
        newbyte[l++] = h6; 
        newbyte[l++] = h7; 
        newbyte[l++] = h8; 
        return newbyte; 
    } 
    private int f1(int x, int y, int z) { 
        return (x & y) | (~x & z); 
    } 
    private int f2(int x, int y, int z) { 
        return x ^ y ^ z; 
    } 
    private int f3(int x, int y, int z) { 
        return (x & y) | (x & z) | (y & z); 
    } 
    private int f4(int x, int y) { 
        return (x << y) | x >>> (32 - y); 
    } 
    // 单元摘要计算函数 
    private void encrypt() { 
        for (int i = 16; i <= 79; i++) { 
            tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14] ^ 
                    tmpData[i - 16], 1); 
        } 
        int[] tmpabcde = new int[5]; 
        for (int i1 = 0; i1 < tmpabcde.length; i1++) { 
            tmpabcde[i1] = digestInt[i1]; 
        } 
        for (int j = 0; j <= 19; j++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f1(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[j] + 0x5a827999; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int k = 20; k <= 39; k++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[k] + 0x6ed9eba1; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int l = 40; l <= 59; l++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f3(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[l] + 0x8f1bbcdc; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int m = 60; m <= 79; m++) { 
            int tmp = f4(tmpabcde[0], 5) + 
                f2(tmpabcde[1], tmpabcde[2], tmpabcde[3]) + tmpabcde[4] + 
                tmpData[m] + 0xca62c1d6; 
            tmpabcde[4] = tmpabcde[3]; 
            tmpabcde[3] = tmpabcde[2]; 
            tmpabcde[2] = f4(tmpabcde[1], 30); 
            tmpabcde[1] = tmpabcde[0]; 
            tmpabcde[0] = tmp; 
        } 
        for (int i2 = 0; i2 < tmpabcde.length; i2++) { 
            digestInt[i2] = digestInt[i2] + tmpabcde[i2]; 
        } 
        for (int n = 0; n < tmpData.length; n++) { 
            tmpData[n] = 0; 
        } 
    } 
    // 4字节数组转换为整数 
    private int byteArrayToInt(byte[] bytedata, int i) { 
        return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16) | 
        ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff); 
    } 
    // 整数转换为4字节数组 
    private void intToByteArray(int intValue, byte[] byteData, int i) { 
        byteData[i] = (byte) (intValue >>> 24); 
        byteData[i + 1] = (byte) (intValue >>> 16); 
        byteData[i + 2] = (byte) (intValue >>> 8); 
        byteData[i + 3] = (byte) intValue; 
    } 
    // 将字节转换为十六进制字符串 
    private static String byteToHexString(byte ib) { 
        char[] Digit = { 
                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 
                'd', 'e', 'f' 
            }; 
        char[] ob = new char[2]; 
        ob[0] = Digit[(ib >>> 4) & 0X0F]; 
        ob[1] = Digit[ib & 0X0F]; 
        String s = new String(ob); 
        return s; 
    } 
    // 将字节数组转换为十六进制字符串 
    private static String byteArrayToHexString(byte[] bytearray) { 
        String strDigest = ""; 
        for (int i = 0; i < bytearray.length; i++) { 
            strDigest += byteToHexString(bytearray[i]); 
        } 
        return strDigest; 
    } 
    // 计算sha-1摘要,返回相应的字节数组 
    public byte[] getDigestOfBytes(byte[] byteData) { 
        process_input_bytes(byteData); 
        byte[] digest = new byte[20]; 
        for (int i = 0; i < digestInt.length; i++) { 
            intToByteArray(digestInt[i], digest, i * 4); 
        } 
        return digest; 
    } 
    // 计算sha-1摘要,返回相应的十六进制字符串 
    public String getDigestOfString(byte[] byteData) { 
        return byteArrayToHexString(getDigestOfBytes(byteData)); 
    } 

} 

 

 posted on 2016-04-20 14:54  第8号  阅读(8489)  评论(0编辑  收藏  举报