微信JSSDK开发JAVA版实现

微信JSSDK开发JAVA版实现

JSSDK JAVA开发第一步:绑定域名

登录微信公众平台进入“公众号设置”(作者:在页面左下角,认证订阅号,认证服务号皆可配置

(备注:登录后可在“开发者中心”可查看对应的接口权限。)

再选择页面上方“功能设置”

这时可以看到“JS接口安全域名”。点击设置弹出以下输入框,按照要求填写域名(注意:IP不可用)

如:www.ipastimes.com, ipastimes.com, examples.ipastimes.com 可用

JSSDK JAVA开发第二步:引入微信JS

在需要引用微信JS接口的页面引入微信js文件(微信在其浏览器内置wx对象)http://res.wx.qq.com/open/js/jweixin-1.0.0.js

JSSDK JAVA开发第三步:后台实现签名逻辑

1.获取access_token

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

/**

* 获取接口访问凭证

*

* @param appid 凭证

* @param appsecret 密钥

* @return

*/

public static String getAccess_token(String appid, String appsecret) {

//凭证获取(GET)

String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET" ;

String requestUrl = token_url.replace( "APPID" , appid).replace( "APPSECRET" , appsecret);

// 发起GET请求获取凭证

JSONObject jsonObject = httpsRequest(requestUrl, "GET" , null );

String access_token = null ;

if ( null != jsonObject) {

try {

access_token = jsonObject.getString( "access_token" );

} catch (JSONException e) {

// 获取token失败

log.error( "获取token失败 errcode:{} errmsg:{}" , jsonObject.getInt( "errcode" ), jsonObject.getString( "errmsg" ));

}

}

return access_token;

}

2.获取jsapi_ticket

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

/**

* 调用微信JS接口的临时票据

*

* @param access_token 接口访问凭证

* @return

*/

public static String getJsApiTicket(String access_token) {

String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi" ;

String requestUrl = url.replace( "ACCESS_TOKEN" , access_token);

// 发起GET请求获取凭证

JSONObject jsonObject = httpsRequest(requestUrl, "GET" , null );

String ticket = null ;

if ( null != jsonObject) {

try {

ticket = jsonObject.getString( "ticket" );

} catch (JSONException e) {

// 获取token失败

log.error( "获取token失败 errcode:{} errmsg:{}" , jsonObject.getInt( "errcode" ), jsonObject.getString( "errmsg" ));

}

}

return ticket;

}

3.实现签名逻辑(根据官方sample改)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

import java.io.UnsupportedEncodingException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.text.SimpleDateFormat;

import java.util.Date;

import java.util.Formatter;

import java.util.HashMap;

import java.util.Map;

import java.util.UUID;

import javax.servlet.http.HttpServletRequest;

import net.sf.json.JSONObject;

import org.apache.struts2.ServletActionContext;

public class PastUtil {

public static Token token = null ;

public static String time = null ;

public static String jsapi_ticket = null ;

/**

*

* @param appId 公账号appId

* @param appSecret

* @param url 当前网页的URL,不包含#及其后面部分

* @return

*/

public static String getParam(String appId,String appSecret){

if (token == null ){

token = CommonUtil.getToken(appId, appSecret);

jsapi_ticket = CommonUtil.getJsApiTicket(token.getAccessToken());

time = getTime();

} else {

if (!time.substring( 0 , 13 ).equals(getTime().substring( 0 , 13 ))){ //每小时刷新一次

token = null ;

token = CommonUtil.getToken(appId, appSecret);

jsapi_ticket = CommonUtil.getJsApiTicket(token.getAccessToken());

time = getTime();

}

}

String url = getUrl();

Map<String, String> params = sign(jsapi_ticket, url);

params.put( "appid" , appId);

JSONObject jsonObject = JSONObject.fromObject(params);

String jsonStr = jsonObject.toString();

System.out.println(jsonStr);

return jsonStr;

}

private static String getUrl(){

HttpServletRequest request = ServletActionContext.getRequest();

StringBuffer requestUrl = request.getRequestURL();

String queryString = request.getQueryString();

String url = requestUrl + "?" +queryString;

return url;

}

public static Map<String, String> sign(String jsapi_ticket, String url) {

Map<String, String> ret = new HashMap<String, String>();

String nonce_str = create_nonce_str();

String timestamp = create_timestamp();

String str;

String signature = "" ;

//注意这里参数名必须全部小写,且必须有序

str = "jsapi_ticket=" + jsapi_ticket +

"&noncestr=" + nonce_str +

"&timestamp=" + timestamp +

"&url=" + url;

try

{

MessageDigest crypt = MessageDigest.getInstance( "SHA-1" );

crypt.reset();

crypt.update(str.getBytes( "UTF-8" ));

signature = byteToHex(crypt.digest());

}

catch (NoSuchAlgorithmException e)

{

e.printStackTrace();

}

catch (UnsupportedEncodingException e)

{

e.printStackTrace();

}

ret.put( "url" , url);

ret.put( "jsapi_ticket" , jsapi_ticket);

ret.put( "nonceStr" , nonce_str);

ret.put( "timestamp" , timestamp);

ret.put( "signature" , signature);

return ret;

}

private static String byteToHex( final byte [] hash) {

Formatter formatter = new Formatter();

for ( byte b : hash)

{

formatter.format( "%02x" , b);

}

String result = formatter.toString();

formatter.close();

return result;

}

private static String create_nonce_str() {

return UUID.randomUUID().toString();

}

private static String create_timestamp() {

return Long.toString(System.currentTimeMillis() / 1000 );

}

//获取当前系统时间 用来判断access_token是否过期

public static String getTime(){

Date dt= new Date();

SimpleDateFormat sdf = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss" );

return sdf.format(dt);

}

}

大部分开发者在签名认证处出错,开启debug模式,当进入页面时会alert出如下信息:

按照如下步骤排错:

1.确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisign 页面工具进行校验。

2.确认config中noncestr, timestamp与用以签名中的对应noncestr, timestamp一致。

3.确认url是页面完整的url,包括GET参数部分。

4.确认 config 中的 appid 与用来获取 jsapi_ticket 的 appid 一致。

5.确保一定缓存access_token和jsapi_ticket,可以减少两次服务器请求加速体验外,还避免了触发频率限制,提高服务稳定性。

附JS SDK权限表

更多信息请参考:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html

免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部