个人亲测通过
用微信打开一个网页,选择右上角的“发送给朋友”后,收到的消息是这样的:
而为了推广效果,我们更希望能自定义标题、描述、访问连接和图片,效果如下图:
下面介绍下怎样来实现这个功能
准备工作
需要一个认证的微信公众号,一定要确定认证
在登录微信公众平台https://mp.weixin.qq.com
在公众号设置–>功能设置,填写设置Js接口安全域名
Js安全域名是需要把微信提供的文件,放在指定域名或者目录下面可以访问的。
1,引用js
jquery-1.8.3.min.js
https://res.wx.qq.com/open/js/jweixin-1.0.0.js
注意,如果自己的域名模式是https模式,要使用https模式,不然会出现mixed content block,微信js不会执行
JS-sdk中的方法要在获取signature之后再执行,不然有可能会执行错误等,同时分享的调用要在wx.ready方法体里面执行,即微信配置都okay的情况下在执行。
2,页面添加js代码
3,java代码
/**
* 获取分享数据
*/
@RequestMapping(value = "/wxConfig", method = RequestMethod.GET)
@ResponseBody
public R wxConfig(@RequestParam String link) throws UnsupportedEncodingException {
String appid = "wxf7******9c9";//公众号的唯一标识(开发者ID(AppID))
String secret = "cafb0ad5******9c9f286";//开发者密码(AppSecret)
Map ret = new HashMap();
String ticket = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "jsapi_ticket");//从redis获取jsapi_ticket
String url = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "url");//从redis获取url
link = URLDecoder.decode(link, "UTF-8");//url地址参数乱问处理
if (url != null && !link.startsWith("https:")) {
link = link.replaceAll("http", "https");
}
if (StringUtil.isEmpty(ticket) || (StringUtil.isNotEmpty(url) && (!url.equals(link)))) {
ret = WxJSUtil.sign(appid, secret, link, null);
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + "=" + entry.getValue());
//把相关参数放入redis
if ("jsapi_ticket".equals(entry.getKey())) {
jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "jsapi_ticket", entry.getValue().toString(), 6000);
} else if ("timestamp".equals(entry.getKey())) {
jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "timestamp", entry.getValue().toString(), 6000);//生成签名的时间戳
} else if ("nonceStr".equals(entry.getKey())) {
jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "nonceStr", entry.getValue().toString(), 6000);//生成签名的随机串
} else if ("signature".equals(entry.getKey())) {
jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "signature", entry.getValue().toString(), 6000);//签名,见附录1
} else if ("url".equals(entry.getKey())) {
jedies.setValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "url", entry.getValue().toString(), 6000);
}
}
} else {
String timestamp = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "timestamp");
String nonceStr = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "nonceStr");
String signature = jedies.getValue(JedisKeyPrefix.JEDIS_KEY_PREFIX_WECHAT_TICKET, "signature");
ret.put("url", url);
ret.put("jsapi_ticket", ticket);
ret.put("nonceStr", nonceStr);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
}
return R.ok().put("appid", appid).put("map", ret);
}
WxJSUtil.java文件
import net.sf.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 微信分享参数处理
*/
public static Map sign(String appid, String secret, String url, String jsapi_ticket) {
Map ret = new HashMap();
if (jsapi_ticket == null) {
jsapi_ticket = getJSApiTicket(appid, secret);
}
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String signature = "";
//注意这里参数名必须全部小写,且必须有序
String string1 = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonce_str +
"×tamp=" + timestamp + "&url=" + url;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
System.out.println("JSSDK签名:" + signature);
} 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;
}
/***
* 获取jsapiTicket
*/
public static String getJSApiTicket(String appid, String secret) {
//获取token
String acess_token = getAccessToken(appid, secret);
String backData = requestHttp(
"https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="
+ acess_token + "&type=jsapi",
"get", "");
String ticket = (String) JSONObject.fromObject(backData).get("ticket");
System.out.println("调用微信jsapi的凭证票为:" + ticket);
return ticket;
}
/***
* 获取acess_token
*/
public static String getAccessToken(String appid, String secret) {
String result = requestHttp(
"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+ appid + "&secret=" + secret,
"get", "");
JSONObject jsonObject = JSONObject.fromObject(result);
System.out.println("access_token" + result);
String token = jsonObject.getString("access_token");
return token;
}
public static String requestHttp(String path, String method, String params) {
HttpURLConnection connection = null;
String result = "";
try {
URL url = new URL(path);
connection = (HttpURLConnection) url.openConnection();
if (method.equalsIgnoreCase("GET")) {
connection.connect();
} else if (method.equalsIgnoreCase("POST")) {
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.connect();
OutputStream os = connection.getOutputStream();
os.write(params.getBytes("UTF-8"));
os.close();
}
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream(), "UTF-8"));
String lines;
StringBuilder sb = new StringBuilder();
while ((lines = reader.readLine()) != null) {
sb.append(lines);
}
result = sb.toString();
reader.close();
connection.disconnect();
return result;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return result;
}
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);
}
附上获取signature处理代码,在获取signature之前,需要获取accessToken 和 对应的Ticket,这两个方式都比较简单,不在列举
http://demo.open.weixin.qq.com/jssdk/sample.zip