最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot JS-SDK自定義微信分享的實(shí)現(xiàn)

 更新時(shí)間:2019年09月25日 10:31:50   作者:桌前明月  
這篇文章主要介紹了SpringBoot JS-SDK自定義微信分享的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

在介紹使用微信自定義分享前,我們來先了解一下什么是自定義分享?

訪問自定義微信外鏈地址頁面,點(diǎn)擊紅色框位置進(jìn)行分享給朋友或者朋友圈,具體操作如下圖所示:

在這里插入圖片描述
分享后圖文消息如下圖所示:

我們要做的就是自定義下圖所示中紅框中的信息。

閑話少說,接下來就正式開始自定義分享實(shí)戰(zhàn)環(huán)節(jié)!

自定義分享實(shí)戰(zhàn)

第一步需要先申請(qǐng)接口測(cè)試號(hào)并進(jìn)行JS接口安全域名設(shè)置

訪問如下鏈接進(jìn)行接口測(cè)試號(hào)申請(qǐng)。點(diǎn)擊訪問 選擇接口測(cè)試號(hào)申請(qǐng),如下圖所示:

在這里插入圖片描述

或者直接訪問 :申請(qǐng)測(cè)試賬號(hào)頁面 如下圖所示:

在這里插入圖片描述

點(diǎn)擊登錄進(jìn)行掃碼登錄,如下圖所示:

登錄后如下圖所示:

在這里插入圖片描述

在這里插入圖片描述

windows系統(tǒng)在 hosts 文件中配置回環(huán)地址的域名

在這里插入圖片描述

在這里插入圖片描述

第二步是下載微信web開發(fā)者工具,可以在PC 進(jìn)行測(cè)試。

點(diǎn)擊訪問下載頁面 如下圖所示:

在這里插入圖片描述

傻瓜式一步一步安裝即可。

第三步 看微信操作教程并完成代碼實(shí)現(xiàn)

點(diǎn)擊訪問微信JS-SDK說明文檔 如下圖所示:

在這里插入圖片描述

JSSDK使用步驟

步驟一:綁定域名(上面已經(jīng)操作了)

步驟二:引入JS文件(下面實(shí)戰(zhàn)代碼中會(huì)介紹到如何使用)

在這里插入圖片描述
步驟三:通過config接口注入權(quán)限驗(yàn)證配置(下面實(shí)戰(zhàn)代碼中會(huì)介紹到如何使用)
在這里插入圖片描述

步驟四:通過ready接口處理成功驗(yàn)證(這里就不詳細(xì)介紹了具體內(nèi)容請(qǐng)參看微信文檔查看)

步驟五:通過error接口處理失敗驗(yàn)證(這里就不詳細(xì)介紹了具體內(nèi)容請(qǐng)參看微信文檔查看)

上面步驟步驟三中的 signature是一個(gè)重要的參數(shù),生成它需要獲取 jsapi_ticket,而生成 jsapi_ticket 需要通過 access_token

獲取signature流程如下:

  1. 獲取 access_token 然后根據(jù) access_token 獲取 jsapi_ticket 。
  2. 排序 noncestr(隨機(jī)字符串), 有效的jsapi_ticket, timestamp(時(shí)間戳),url(當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分)4個(gè)參數(shù)拼接例如:noncestr=XX&jsapi_ticket=XX&jtimestamp=XX&jurl=XX
  3. 然后通過sha1加密拼接的4個(gè)參數(shù)獲取到signature

可能你對(duì)操作流程還是看不懂,沒有關(guān)系可以直接參考代碼實(shí)現(xiàn),接下來就是代碼實(shí)現(xiàn):

初始化微信JSSDK配置信息 Controller 內(nèi)容如下:

@RestController
@RequestMapping("/weixin")
public class WeiXinDemoController {
	
	@Autowired
	private WeiXinService weiXinService;
	/**
	 * 初始化微信JSSDK配置信息
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping("/initWXJSSDKConfigInfo")
	public String initWXJSConfig (HttpServletRequest request,HttpServletResponse response) throws Exception{
		String shareUrl = request.getParameter("shareUrl");//分享的URL
		Map map = weiXinService.initJSSDKConfigInfo(shareUrl);
		String json = weiXinService.mapToJson(map);
		return json;
	}
	
}

初始化JSSDK配置信息,配置信息有:noncestr(隨機(jī)字符串)、有效的jsapi_ticket、timestamp(時(shí)間戳)、shareUrl(當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分)appid(公眾號(hào) appid)。

	/**
	 * 初始化JSSDK配置信息
	 * @param shareUrl
	 * @return
	 * @throws Exception
	 */
	public Map initJSSDKConfigInfo(String shareUrl) throws Exception {
		
		String accessToken = this.getJSSDKAccessToken();
		String jsapiTicket = this.getJSSDKJsapiTicket(accessToken);
		String timestamp = Long.toString(System.currentTimeMillis() / 1000);
		String nonceStr = UUID.randomUUID().toString();
		String signature = this.buildJSSDKSignature(jsapiTicket,timestamp,nonceStr,shareUrl);
		
		Map<String,String> map = new HashMap<String,String>();
		map.put("shareUrl", shareUrl);
		map.put("jsapi_ticket", jsapiTicket);
		map.put("nonceStr", nonceStr);
		map.put("timestamp", timestamp);
		map.put("signature", signature);
		map.put("appid", weiXinConfig.getAppID());
		return map;
	}

獲取 JSSDK access_token 方法。

public String getJSSDKAccessToken() {
		String token = null;
		String url = JSSDK_ACCESSTOKEN.replaceAll("APPID",
				weiXinConfig.getAppID()).replaceAll("APPSECRET",
				weiXinConfig.getAppsecret());

		String json = postRequestForWeiXinService(url);
		Map map = jsonToMap(json);
		if (map != null) {
			token = (String) map.get("access_token");
		}
		return token;
	}

獲取 JSSDK jsapi_ticket 方法。

public String getJSSDKJsapiTicket(String token) {
	 String url = JSSDK_GETTICKET.replaceAll("ACCESS_TOKEN", token);
	 String json = postRequestForWeiXinService(url);
	 Map map = jsonToMap(json);
	 String jsapi_ticket = null;
	 if (map != null) {
     jsapi_ticket = (String) map.get("ticket");
   }
	 return jsapi_ticket;
	}

拼接 noncestr(隨機(jī)字符串), 有效的jsapi_ticket、 timestamp(時(shí)間戳)、url(當(dāng)前網(wǎng)頁的URL,不包含#及其后面部分)并通過sha1進(jìn)行加密。

 /**
   * 構(gòu)建分享鏈接的簽名。
   * @param ticket
   * @param nonceStr
   * @param timeStamp
   * @param url
   * @return
   * @throws Exception
   */
  public static String buildJSSDKSignature(String ticket,String timestamp,String nonceStr ,String url) throws Exception {
  	
  	String orderedString = "jsapi_ticket=" + ticket
        + "&noncestr=" + nonceStr + "&timestamp=" + timestamp
        + "&url=" + url;
    return sha1(orderedString);
  }
   /**
   * sha1 加密JSSDK微信配置參數(shù)獲取簽名。
   * 
   * @param signature
   * @param timestamp
   * @param nonce
   * @return
   */
  public static String sha1(String orderedString) throws Exception {
    String ciphertext = null;
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] digest = md.digest(orderedString.getBytes());
    ciphertext = byteToStr(digest);
    return ciphertext.toLowerCase();
  }
  /** 
   * 將字節(jié)數(shù)組轉(zhuǎn)換為十六進(jìn)制字符串 
   * 
   * @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; 
  } 
  /** 
   * 將字節(jié)轉(zhuǎn)換為十六進(jìn)制字符串 
   * 
   * @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; 
  }

基礎(chǔ)工具方法如下:

public String mapToJson(Map map){
		Gson gson = new Gson();
		String json = gson.toJson(map);
		return json;
	}
	private Map jsonToMap(String json) {
		Gson gons = new Gson();
		Map map = gons.fromJson(json, new TypeToken<Map>(){}.getType());
		return map;
	}

	private String postRequestForWeiXinService(String getAccessTokenUrl) {
		ResponseEntity<String> postForEntity = restTemplate.postForEntity(getAccessTokenUrl, null, String.class);
		String json = postForEntity.getBody();
		return json;
	}
	
	private String getRequestForWeiXinService(String getUserInfoUrl) {
		ResponseEntity<String> postForEntity = restTemplate.getForEntity(getUserInfoUrl.toString(), String.class);
		String json = postForEntity.getBody();
		return json;
	}

wxShare.js 主要是獲取JSSDK配置信息并定義分享功能處理。具體代碼如下:

//alert(window.location.href.split('#')[0]);/***用于獲得當(dāng)前連接url用**/
/***用戶點(diǎn)擊分享到微信圈后加載接口接口*******/
$.post("/weixin/initWXJSSDKConfigInfo",{"shareUrl":window.location.href.split('#')[0]},function(data,status){
  data=eval("("+data+")");
  wx.config({
    debug: false,
    appId: data.appid,
    timestamp:data.timestamp,
    nonceStr:data.nonceStr,
    signature:data.signature,
    jsApiList: [
      'checkJsApi',
      'onMenuShareTimeline',
      'onMenuShareAppMessage',
      'onMenuShareQQ',
      'onMenuShareWeibo',
      'onMenuShareQZone',
      'hideOptionMenu',
    ]
  });
  var shareTitle = $("#wx_share_span").data("shareTitle");
  if(!shareTitle){
  	shareTitle = $("title").html();
  }
  var shareImg = $("#wx_share_span").data("shareImg");
  if(!shareImg){
  	//shareImg = common.bp()+'/m_images/shareImg.jpg';
  }
  var shareLink = $("#wx_share_span").data("shareLink");
  if(!shareLink){
  	shareLink = window.location.href.split('#')[0];
  }
  var shareDesc = $("#wx_share_span").data("shareDesc");
  if(!shareDesc){
  	shareDesc = $("meta[name=description]").attr("content");
  }
  wx.ready(function(){
    // alert("準(zhǔn)備分享");
    wx.onMenuShareTimeline({
      title : shareTitle, // 分享標(biāo)題
      link : shareLink, // 分享鏈接
      imgUrl : shareImg, // 分享圖標(biāo)
      success : function() {
        // 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
        //alert("分享成功");
      },
      cancel : function() {
        // 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
        //alert("分享取消");
      }
    });
    //wx.hideOptionMenu();/***隱藏分享菜單****/
    wx.onMenuShareAppMessage({
    	title: shareTitle, // 分享標(biāo)題
    	desc: shareDesc, // 分享描述
    	link: shareLink, // 分享鏈接,該鏈接域名或路徑必須與當(dāng)前頁面對(duì)應(yīng)的公眾號(hào)JS安全域名一致
    	imgUrl: shareImg, // 分享圖標(biāo)
    	success: function () {
    	// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
    	},
    	cancel: function () {
    	// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
    	}
  	});
    wx.onMenuShareQQ({
    	title: shareTitle, // 分享標(biāo)題
    	desc: shareDesc, // 分享描述
    	link: shareLink, // 分享鏈接
    	imgUrl: shareImg, // 分享圖標(biāo)
    	success: function () {
    	// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
    	},
    	cancel: function () {
    	// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
    	}
  	});
    wx.onMenuShareWeibo({
    	title: shareTitle, // 分享標(biāo)題
    	desc: shareDesc, // 分享描述
    	link: shareLink, // 分享鏈接
    	imgUrl: shareImg, // 分享圖標(biāo)
    	success: function () {
    	// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
    	},
    	cancel: function () {
    	// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
    	}
  	});
    wx.onMenuShareQZone({
    	title: shareTitle, // 分享標(biāo)題
    	desc: shareDesc, // 分享描述
    	link: shareLink, // 分享鏈接
    	imgUrl: shareImg, // 分享圖標(biāo)
    	success: function () {
    	// 用戶確認(rèn)分享后執(zhí)行的回調(diào)函數(shù)
    	},
    	cancel: function () {
    	// 用戶取消分享后執(zhí)行的回調(diào)函數(shù)
    	}
  	});
  });
});

分享頁面該頁面需要引入wxShare.js和jweixin-1.2.0.js,并且通過在隱藏的span標(biāo)簽上定義自定義分享的內(nèi)容,具體代碼如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="/jquery-1.8.3.min.js" type="text/javascript" ></script>
</head>
<body>
<span id="wx_share_span" style="display: none"></span>
<script type="text/javascript">
	$(document).ready(function(){
		
		$("#wx_share_span").data("shareTitle", "桌前明月教你玩微信公眾號(hào)自定義分享");
		$("#wx_share_span").data("shareDesc", "保證學(xué)會(huì)哈!");
		//$("#wx_share_span").data("shareLink", "/weixinshare.html");
		//$("#wx_share_span").data("shareImg", "/banner.jpg");
	});
</script>

<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.2.0.js"></script>
<script type="text/javascript" src="/wxShare.js"></script>
</body>
</html>

測(cè)試

訪問:http://www.zhuoqianmingyue.com:8090/weixinshare.html 未引入 wxShare.js 的測(cè)試結(jié)果如下:

在這里插入圖片描述

引入 wxShare.js 的測(cè)試結(jié)果如下:

在這里插入圖片描述

一般情況下我們通過接口測(cè)試號(hào)配置成測(cè)試環(huán)境域名,上述測(cè)試通過后就可以在正式服務(wù)號(hào)上配置JS接口安全域名,順便在把我們項(xiàng)目配置的 appid 換成服務(wù)號(hào)的 appid 即可。具體操作如下:

在這里插入圖片描述

在這里插入圖片描述

小結(jié)

微信自定義分享具體操作步驟如下:

  • 定義獲取JS-SDK配置信息接口
  • 定義頁面初始化調(diào)用JS-SDK配置信息接口 js 代碼和定義分享接口js代碼
  • 分享頁面引入 jweixin-1.2.0.js和 調(diào)用JS-SDK配置信息的js文件

三步中最為總要的就是第一步:定義獲取JS-SDK配置信息接口,這個(gè)接口需要獲取jsapi_ticket 并通過和配置信息參數(shù)一起生成簽名 signature。

在這里再三強(qiáng)調(diào)一下,微信提供操作文檔一定要多看幾篇,因?yàn)楹芏嗉?xì)節(jié)都在文檔中進(jìn)行了說明。當(dāng)你把微信提供操作文檔看透,你就會(huì)覺得其實(shí)就是個(gè)API 調(diào)用而已。

代碼示例

具體代碼示例請(qǐng)查看我的GitHub 倉庫 springbootexamples 中的 spring-boot-2.x-weixin 查看。

GitHub:https://github.com/zhuoqianmingyue/springbootexamples

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 一文詳解SpringBoot如何使用pageHelper做分頁處理

    一文詳解SpringBoot如何使用pageHelper做分頁處理

    分頁是常見大型項(xiàng)目都需要的一個(gè)功能,PageHelper是一個(gè)非常流行的MyBatis分頁插件,下面就跟隨小編一起來了解下SpringBoot是如何使用pageHelper做分頁處理的吧
    2025-03-03
  • Java女裝商城系統(tǒng)的實(shí)現(xiàn)流程

    Java女裝商城系統(tǒng)的實(shí)現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)一個(gè)女裝商城系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • Java中將接口返回的字節(jié)串轉(zhuǎn)為文件詳解

    Java中將接口返回的字節(jié)串轉(zhuǎn)為文件詳解

    這篇文章主要給大家介紹了關(guān)于Java中將接口返回的字節(jié)串轉(zhuǎn)為文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-11-11
  • Request的包裝類HttpServletRequestWrapper的使用說明

    Request的包裝類HttpServletRequestWrapper的使用說明

    這篇文章主要介紹了Request的包裝類HttpServletRequestWrapper的使用說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • eclipse自動(dòng)創(chuàng)建SpringBoot項(xiàng)目報(bào)錯(cuò)的解決

    eclipse自動(dòng)創(chuàng)建SpringBoot項(xiàng)目報(bào)錯(cuò)的解決

    這篇文章主要介紹了eclipse自動(dòng)創(chuàng)建SpringBoot項(xiàng)目報(bào)錯(cuò)的解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java學(xué)習(xí)之緩沖流的原理詳解

    Java學(xué)習(xí)之緩沖流的原理詳解

    為了提高其數(shù)據(jù)的讀寫效率,Java中又定義了四種緩沖流,分別是:字節(jié)緩沖輸入流、字節(jié)緩沖輸出流、字符緩沖輸入流和字符緩沖輸出流。本文主要來和大家聊聊這些緩沖流的原理,希望對(duì)大家有所幫助
    2023-01-01
  • Java項(xiàng)目中大批量數(shù)據(jù)查詢導(dǎo)致OOM的解決

    Java項(xiàng)目中大批量數(shù)據(jù)查詢導(dǎo)致OOM的解決

    本文主要介紹了Java項(xiàng)目中大批量數(shù)據(jù)查詢導(dǎo)致OOM的解決,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案

    Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案

    這篇文章主要給大家介紹了關(guān)于Java異常:java.net.UnknownHostException產(chǎn)生的原因和解決方案,這個(gè)異常是java.net包中的一部分,具體說它是類的一個(gè)實(shí)例,異常通常是由主機(jī)名無法解析為IP地址引起的,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下
    2024-01-01
  • java8 統(tǒng)計(jì)字符串字母?jìng)€(gè)數(shù)的幾種方法總結(jié)(推薦)

    java8 統(tǒng)計(jì)字符串字母?jìng)€(gè)數(shù)的幾種方法總結(jié)(推薦)

    下面小編就為大家分享一篇java8 統(tǒng)計(jì)字符串字母?jìng)€(gè)數(shù)的幾種方法總結(jié)(推薦),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來吧
    2017-11-11
  • JDK與Dubbo中的SPI詳細(xì)介紹

    JDK與Dubbo中的SPI詳細(xì)介紹

    這篇文章主要介紹了JDK中的SPI與Dubbo中的SPI,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09

最新評(píng)論

吉水县| 临泽县| 右玉县| 乐都县| 名山县| 石城县| 二连浩特市| 奈曼旗| 镇安县| 邯郸县| 商河县| 东平县| 丰都县| 丰镇市| 阜平县| 杭锦旗| 岚皋县| 普兰县| 环江| 晋城| 如东县| 上栗县| 新巴尔虎右旗| 南阳市| 万宁市| 淮阳县| 溆浦县| 崇义县| 柯坪县| 东阳市| 英吉沙县| 江城| 财经| 上高县| 木里| 郎溪县| 安顺市| 鄄城县| 琼结县| 海林市| 孟津县|