最近公司项目要求自定义微信分享样式,我就接手了这个微信JSSDK的接口调用。

首先你要有一个公众号。

然后需要在公众号的设置-公众号设置-功能设置

设置我们的安全域名。

java微信sdk版本 java版微信还能用么_JSSSDK

java微信sdk版本 java版微信还能用么_JSSSDK_02

我们把文件下载下来,然后放到我们填写的域名,注意:一定要放在你要调用微信的接口的路径下一,只能是域名后跟一个目录,

我们要调用的页面必须是在这个目录下的子目录或者这个目录下。还有如果你用的是SpringMVC的话请对这个域名下的静态资源进行处理。因为微信要去判断你填写的这个域名下是否有这个文件。

这一步完成之后我们进入 开发-基础配置-服务器配置

首先我们需要对我们服务器的IP地址加入白名单。

java微信sdk版本 java版微信还能用么_java微信sdk版本_03


去启用的我们的服务器信息,这个服务器必须是你要调用微信的JSSDK的项目服务器。

java微信sdk版本 java版微信还能用么_微信_04

首先说下这个URL,这个URL必须要能接受微信发送的请求

微信服务器会给你发送一个请求,这个请求有几个参数

分别是:signature timestamp nonce echostr

拿到这四个参数之后,需要将 你在页面中写Token,nonce,timestamp 放入到一个String数组里面,然后进行sort排序,

排序完成之后将这三个字符串进行拼接,然后使用SHA-1算法进行加密,将加密后的结果与echostr进行比较,相同返回微信发给你的echostr

具体代码:

@RequestMapping(value="getToken",method=RequestMethod.GET)
public @ResponseBody String getToken(String signature,String timestamp,String nonce,String echostr) throws NoSuchAlgorithmException{
String[] array ={wxToken,nonce,timestamp};
Arrays.sort(array);
String newArray="";
for (int i = 0; i < array.length; i++) {
	newArray+=array[i];
}
//SHA-1加密
MessageDigest instance = MessageDigest.getInstance("SHA-1");
instance.update(newArray.getBytes());
byte[] digest = instance.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
    shaHex = Integer.toHexString(digest[i] & 0xFF);
    if (shaHex.length() < 2) {
	hexstr.append(0);
    }
    hexstr.append(shaHex);
}
if(hexstr.equals(signature)){
	return echostr;//相同返回微信发给我们的echostr
}
return "erro";
}

此时就可以完成认证了。

然后是页面:

     

var wxObjet;
	href=encodeURIComponent(window.location.href)//这个参数是用来获取当前页面的url
	$.ajax({
		url:用来提供配置权限信息的一个Controller/href,
		type:"get",
		dataType:"json",
		async: false,
		success:function(data){
			wxObjet=data;
		}
	})
	
wx.config({
    debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
    appId: wxObjet.aapid, // 必填,公众号的唯一标识
    timestamp: wxObjet.timestamp, // 必填,生成签名的时间戳
    nonceStr: wxObjet.noncestr, // 必填,生成签名的随机串
    signature: wxObjet.Signature,// 必填,签名
    jsApiList: ["onMenuShareTimeline","onMenuShareAppMessage","onMenuShareQQ"] // 必填,需要使用的JS接口列表
    
});

然后看后台代码:

@RequestMapping("getJsapi")
public @ResponseBody Map getJsapi(String url//就是你发送请求的页面){
		Map map=new HashMap();
		try {
			//微信JSSDK Acces_token和jsapi的全局缓存
			//因为微信的Token和jsapi30分钟内有效,每天只能获取2000次,所以我们要加上缓存。
			String token ="";
			String jsapi_ticket ="";
			Map mes = (Map)redisTemplate.opsForValue().get("mes");
			Map redis=mes;
			if(mes==null){
				redis=new HashMap();
				token=CommonUtil.getToken(appid, appsecret);//写一个工具类,用来给微信发送请求,请求所需参数:appid,和AppSecret,下面有代码
				jsapi_ticket= CommonUtil.getJsapi_ticket(token);//拿到微信给我们的token之后我们去获取jsapi_ticket.下,下面有代码
				//放入ticket
				redis.put("ticket",jsapi_ticket);
				redis.put("ticketDate",new Date().getTime());
				//放入token
				redis.put("token",token);
				redis.put("tokenDate",new Date().getTime());
				redisTemplate.opsForValue().set("mes", redis);
			}else{
				long  tokenDate=(long)mes.get("tokenDate");
				if(new Date().getTime()-tokenDate>=1200000){
					token=CommonUtil.getToken(appid, appsecret);
					//放入token
					System.out.println(token);
					redis.put("token",token);
					redis.put("tokenDate",new Date().getTime());
				}else{
					token=(String) mes.get("token");
					
				}
				long  ticketDate=(long)mes.get("ticketDate");
				if(new Date().getTime()-ticketDate>=1200000){
					jsapi_ticket= CommonUtil.getJsapi_ticket(token);
					//放入ticket
					redis.put("ticket",jsapi_ticket);
					redis.put("ticketDate",new Date().getTime());
				}else{
					jsapi_ticket = (String)mes.get("ticket");
				}
				redisTemplate.opsForValue().set("mes", redis);
			}
			
			
			
			
			//生成一个随机字符,我这里直接用时间戳来代替了
			long time = new Date().getTime();
			String noncestr = String.valueOf(time);
			//时间绰
			long time2 = new Date().getTime();
			String timestamp=String.valueOf(time2/1000);//微信接收的时间戳是10位的所以咱们要除以1000
			//去使用SHA-1获取安全签名 ,下面有代码
			String jsSDKSignature = CommonUtil.getJsSDKSignature(jsapi_ticket, noncestr, timestamp, url);
			map.put("Signature",jsSDKSignature);//将所有验证权限所需要数据放入一个map,这个是安全签名
			map.put("noncestr",noncestr);//这个是随机字符
			map.put("aapid",appid);//这个是咱们的APPID
			map.put("timestamp", timestamp);//这个是时间戳
			return map;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return map;
	}

工具类代码

import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;

/**
 * 拿到微信的Access_Tocken
 * 
 * @author liuyk
 *
 */
public class CommonUtil {
	public static String getToken(String appid, String appSecret) throws ClientProtocolException, IOException {
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 创建参数队列
		List<NameValuePair> params = new ArrayList<NameValuePair>();
		params.add(new BasicNameValuePair("grant_type", "access_token"));
		params.add(new BasicNameValuePair("appid", appid));
		/* secret */
		params.add(new BasicNameValuePair("appid", AppSecret));
		String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appid + "&secret="
				+ appSecret;
		// 创建httpget.
		HttpGet httpget = new HttpGet(url);
		// 发送请求
		CloseableHttpResponse response = httpclient.execute(httpget);
		// 得到响应提
		HttpEntity entity = response.getEntity();

		String param = EntityUtils.toString(entity);
		System.out.println(param);
		// 将JSON转换为Map
		Map parseParam = (Map) JSON.parse(param);
		Object object = parseParam.get("access_token");
		return object.toString();
	}

	public static String getJsSDKSignature(String jsapi_ticket, String noncestr, String timestamp, String url) {
            //这几个参数名按照字典顺序进行拼接
		String string = "jsapi_ticket=" + jsapi_ticket;
		string += "&noncestr=" + noncestr;
		string += "&tamp=" + timestamp;
		string += "&url=" + url;
                
		StringBuffer hexstr = new StringBuffer();
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			// 对接后的字符串进行sha1加密
			md.update(string.getBytes());
			byte[] digest = md.digest();
			String shaHex = "";
			for (int i = 0; i < digest.length; i++) {
				shaHex = Integer.toHexString(digest[i] & 0xFF);
				if (shaHex.length() < 2) {
					hexstr.append(0);
				}
				hexstr.append(shaHex);
			}
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return hexstr.toString();
	}

	public static String getJsapi_ticket(String access_token) {
		String ticket = "";
		String requestUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=" + access_token
				+ "&type=jsapi";
		CloseableHttpClient httpclient = HttpClients.createDefault();
		// 先从线程中取值,如果取不到,说明没有使用线程,再利用这个方法获取
		// 因为发送信息等操作,都是调用的这个方法,所以在这里进行处理一下吧
		HttpGet httpget = new HttpGet(requestUrl);
		// 发送请求
		CloseableHttpResponse response = null;
		try {
			response = httpclient.execute(httpget);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// 得到响应提
		HttpEntity entity = response.getEntity();

		String param = null;
		try {
			param = EntityUtils.toString(entity);
		} catch (ParseException | IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		System.out.println(param);
		// 将JSON转换为Map
		Map parseParam = (Map) JSON.parse(param);
		Object object = parseParam.get("ticket");
		return object.toString();
	}

}
//前端的权限认证之后我们把要用的微信接口放入ready回调里面
wx.ready(function(){
	/* 分享到朋友圈 */
	wx.onMenuShareTimeline({
    title: '', // 分享标题
    link: '', // 分享链接,这个链接必须是你配置的jssdk的安全域名,如果不是在那个域名或者路径下会没有效果
    imgUrl: '', // 同上

    });
  /*分享给朋友  */
	wx.onMenuShareAppMessage({
    title: '', // 分享标题
    desc: '', // 分享描述
    link: '', // 分享链接,该链接域名必须与当前企业的可信域名一致
    imgUrl: '', // 分享图标
    type: '', // 分享类型,music、video或link,不填默认为link
    dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
    success: function () {
        alert("分享成功");
    },
    cancel: function () {
        // 用户取消分享后执行的回调函数
        alert("已取消分享");
    }
});



以上就是整个流程,如果有什么问题可以来问我,很欢迎帮忙解决。