1. 程式人生 > >Java與微信相關

Java與微信相關

cat pin scope location ole quest 需要 n-1 pub

微信登錄並不復雜,其核心邏輯是每個用戶對應每個應用都有唯一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<String,Object> 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<String, Object> 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進行加密運算,必須匹配才可分享
前端引入
<script src="https://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>

前端需要引入的自定義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<String, String> 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<String, String> 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<String,Object> 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.分享只能分享當前頁,不能分享其他頁。



Java與微信相關