微信 java_Java与微信相关

微信登录并不复杂,其核心逻辑是每个用户对应每个应用都有唯一openId,根据openId进行用户的校验和处理。

//初始化方法

public static String getCodeUrl(String username) throws ClientProtocolException, IOException {

String url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";

url = url.replace("APPID", appid);

url = url.replace("STATE", "1");

url = url.replace("REDIRECT_URI", URLEncoder.encode(redictUri, "utf-8"));

//System.out.println("----------微信取用户url="+url+",redictUri="+redictUri);

return url;

}

访问该url执行初始化,在微信上设置回调函数,将秘钥文件放在目录结构下,就可以回调了。(微信公众号必须是服务号,订阅号不支持)

//微信获取openId方法

//获取access_token,openId

public static Map getOpendId(String code) {

String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=AppId&secret=AppSecret&code=CODE&grant_type=authorization_code";

url = url.replace("AppId", appid).replace("AppSecret", appsecret).replace("CODE", code);

Map headersParams = new HashMap<>();

//获取access_token,openId等

String result = HttpRequestUtil.sendPost(url, headersParams,"UTF-8");

System.out.println("获取accessToken和openId:url="+url+",返回结果:"+result);

JSONObject obj = JSONObject.parseObject(result);

//把返回参数(4个)返回

JSONObject resultObj = new JSONObject();

headersParams.put("openid",obj.getString("openid"));

headersParams.put("accessToken",obj.getString("access_token"));

headersParams.put("appid",appid);

headersParams.put("appname","应用名称");

return headersParams;

}

//获取用户信息

public static JSONObject getUserInfo(String openid,String accessToken){

//拉取用户信息

String url = "https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID&lang=zh_CN";

url = url.replace("ACCESS_TOKEN",accessToken);

url = url.replace("OPENID",openid);

String result = HttpRequestUtil.sendGet(url, "");

System.out.println("拉取用户信息:url="+url+",返回结果:"+result);

JSONObject obj = JSONObject.parseObject(result);

return obj;

}

-------------------------------------------微信分享相关-----------------------------------微信分享相对稍微复杂,主要是对签名的计算,首先需要引入微信的js文件,然后根据appid,随机数,时间戳和url进行加密运算,必须匹配才可分享

前端引入

前端需要引入的自定义js文件需要引入的内容:

function wx_ready_fenxiang(title, desc, imgUrl,url){

$.post("/weixin/share",{"url":url},function(result){

var appid,timestamp,nonceStr,signature;

appid = result.appId;

timestamp = result.timestamp;

nonceStr = result.nonceStr;

signature = result.signature;

wx.config({

debug: false,//debug模式会打印日志,微信端会弹框

appId: appid,

timestamp:timestamp,

nonceStr: nonceStr,

signature: signature,

jsApiList: [

'onMenuShareTimeline', 'onMenuShareAppMessage', 'onMenuShareQQ', 'onMenuShareWeibo', 'onMenuShareQZone'

]

});

_wx(title, desc, imgUrl, 'link',url);

},"json")

}

function _wx(title, desc, imgUrl, type,url){

wx.ready(function() {

//朋友圈

wx.onMenuShareTimeline({

title: title, // 分享标题

link: url, // 分享链接

imgUrl: imgUrl, // 分享图标

success: function() {

// alert('谢谢分享');

// 用户确认分享后执行的回调函数

},

cancel: function() {

// alert('谢谢分享');

// 用户取消分享后执行的回调函数

}

});

//微信好友

wx.onMenuShareAppMessage({

title: title, // 分享标题

desc: desc, // 分享描述

link: url, // 分享链接

imgUrl: imgUrl, // 分享图标

type: type, // 分享类型,music、video或link,不填默认为link

// dataUrl: dataurl, // 如果type是music或video,则要提供数据链接,默认为空

success: function() {

// alert('谢谢分享');

},

cancel: function() {

// alert('分享失败');

// 用户取消分享后执行的回调函数

}

});

//qq好友

wx.onMenuShareQQ({

title: title, // 分享标题

desc: desc, // 分享描述

link: url, // 分享链接

imgUrl: imgUrl, // 分享图标

success: function() {

// 用户确认分享后执行的回调函数

},

cancel: function() {

// 用户取消分享后执行的回调函数

}

});

//腾讯微博

wx.onMenuShareWeibo({

title: title, // 分享标题

desc: desc, // 分享描述

link: url, // 分享链接

imgUrl: imgUrl, // 分享图标

success: function() {

// 用户确认分享后执行的回调函数

},

cancel: function() {

// 用户取消分享后执行的回调函数

}

});

//qq空间

wx.onMenuShareQZone({

title: title, // 分享标题

desc: desc, // 分享描述

link: url, // 分享链接

imgUrl: imgUrl, // 分享图标

success: function() {

// 用户确认分享后执行的回调函数

},

cancel: function() {

// 用户取消分享后执行的回调函数

}

});

// alert("wx ready 哈哈哈");

// config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。

});

wx.error(function(res) {

// alert(res + "wx-error");

// config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。

});

}

//调用方法

wx_ready_fenxiang("名称", "详情", '图片url',location.href)

JAVA后台部分:

//获取分享的token

public static String getShareAccessToken() throws IOException {

String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appid+"&secret="+appsecret;

Map headersParams = new HashMap<>();

String resultStr = HttpUtils.get(url,headersParams);

// sendGet:用get方法获取数据 ,具体请参考之间的关于微信的文章 http://www.cnblogs.com/jiduoduo/p/5749363.html

System.out.println("------------微信分享share的accessToken:url="+url+",返回结果:"+resultStr);

//返回结果

JSONObject obj = JSONObject.parseObject(resultStr);

String access_token = obj.getString("access_token");

return access_token;

}

//获取jsapi_ticket

public static String getJsapiTicket(String accessToken) throws IOException {

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

Map headersParams = new HashMap<>();

String resultStr = HttpUtils.get(url, headersParams);

System.out.println("Redpack.WeixinUtils.getJsapiTicket获取JsapiTicket:url="+url+",返回结果:"+resultStr);

//返回结果

JSONObject obj = JSONObject.parseObject(resultStr);

String ticket = obj.getString("ticket");

return ticket;

}

//生成签名

public static String getSignature(String jsapi_ticket, String noncestr, Long timeStamp, String url) {

String string1 = "jsapi_ticket=JSAPI_TICKET&noncestr=NONCESTR&timestamp=TIMESTAMP&url=URL";

string1 = string1.replace("JSAPI_TICKET", jsapi_ticket);

string1 = string1.replace("NONCESTR", noncestr);

string1 = string1.replace("TIMESTAMP", timeStamp.toString());

string1 = string1.replace("URL",url);

String signature= DigestUtils.shaHex(string1);

System.out.println("------生成签名string1="+string1+",结果signature="+signature);

return signature;

}

Controller层,就是前台js引用的接口:

@RequestMapping("/share")

@ResponseBody

public JSONObject share(HttpServletRequest request,@RequestParam String url) throws IOException {

System.out.println("----------------------------微信分享url="+url);

//url = url.replace("sendfriend","redpack/get");

//时间戳(10位)

Long timeStamp = System.currentTimeMillis()/1000;

//随机数(可以任意指定)

String noncestr="12345678";

//获得jsapi_ticket

//1.拿到accessToken

String accessToken = WeixinUtils.getShareAccessToken();

//此处accessToken过期时间为2个小时,第一次取可以存入redis,两个小时之内有效,如果accessToken尚在有效期内,再次取是会报错的。

String jsapi_ticket = WeixinUtils.getJsapiTicket(accessToken);

//获得签名

String signature = WeixinUtils.getSignature(jsapi_ticket,noncestr,timeStamp,url);

//Map param = WeixinUtils.getOpendId(code);

JSONObject obj = new JSONObject();

obj.put("appId",PropertyConstants.getValue("com.tencent.weixin.appid"));

obj.put("timestamp",timeStamp);

obj.put("nonceStr",noncestr);

obj.put("signature",signature);

obj.put("jsapi_ticket",jsapi_ticket);

obj.put("url",url);

return obj;

}

注意:1.时间戳必须是10位,13位的时间戳是无法取到正确的值的。

2.随机数可以任意指定,不需要太复杂,我就设的12345678

3.可否分享就是看签名校验是否正确,可以在微信公众号开发者工具里的网址进行计算,匹配则可分享。

4.分享标题和内容是有敏感词的,比如红包,现金等,具体请查阅微信官方的说明。

5.分享只能分享当前页,不能分享其他页。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值