H5分享到微信朋友圈与好友实现思路
本文只是实现思路,代码写的比较水,仅供参考
使用springBoot 返回ModelAndView 实现
HTML使用Thymeleaf
1.添加MyX509TrustManager类(从微信提供的包中导入或自己创建都可以)
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
public class MyX509TrustManager implements X509TrustManager {
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException
{
}
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException
{
}
public X509Certificate[] getAcceptedIssuers()
{
return null;
}
}
2.maven添加JSON依赖
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib-ext-spring</artifactId>
<version>1.0.2</version>
</dependency>
3.创建WeixinUtil类
需要注意:
1.由于微信限制access_token获取次数,access_token需要缓存,建议由程序统一获取和刷新access_token,其他业务逻辑所使用的access_token均来自于该统一获取的access_token,不应该各自去刷新,目前access_token的有效期为7200秒,此处示例代码不做处理,实际开发请自行处理
2.微信appId与secret请根据项目要求自行存放到配置文件或Config类
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.ConnectException;
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;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.servlet.http.HttpServletRequest;
import net.sf.json.JSONObject;
public class WeixinUtil {
/**
* 方法名:httpRequest</br>
* 详述:发送http请求</br>
* @param requestUrl
* @param requestMethod
* @param outputStr
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
public static JSONObject httpRequest(String requestUrl,String requestMethod, String outputStr) {
JSONObject jsonObject = null;
StringBuffer buffer = new StringBuffer();
try {
TrustManager[] tm = { new MyX509TrustManager() };
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, tm, new java.security.SecureRandom());
SSLSocketFactory ssf = sslContext.getSocketFactory();
URL url = new URL(requestUrl);
HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
httpUrlConn.setSSLSocketFactory(ssf);
httpUrlConn.setDoOutput(true);
httpUrlConn.setDoInput(true);
httpUrlConn.setUseCaches(false);
httpUrlConn.setRequestMethod(requestMethod);
if ("GET".equalsIgnoreCase(requestMethod))
httpUrlConn.connect();
if (null != outputStr) {
OutputStream outputStream = httpUrlConn.getOutputStream();
outputStream.write(outputStr.getBytes("UTF-8"));
outputStream.close();
}
InputStream inputStream = httpUrlConn.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String str = null;
while ((str = bufferedReader.readLine()) != null) {
buffer.append(str);
}
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
inputStream = null;
httpUrlConn.disconnect();
jsonObject = JSONObject.fromObject(buffer.toString());
} catch (ConnectException ce) {
ce.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return jsonObject;
}
/**
* 方法名:getWxConfig</br>
* 详述:获取微信的配置信息 </br>
* @param request
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
public static Map<String, Object> getWxConfig(HttpServletRequest request) {
Map<String, Object> ret = new HashMap<String, Object>();
//此处appid与secret应该放到配置文件中,测试实现仅供参考
String appId = "wxappId "; // 必填,公众号的唯一标识
String secret = "wxsecret";
//url
String requestUrl = request.getRequestURL().toString();
String access_token = "";
String jsapi_ticket = "";
String timestamp = Long.toString(System.currentTimeMillis() / 1000); // 必填,生成签名的时间戳
String nonceStr = UUID.randomUUID().toString(); // 必填,生成签名的随机串
String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+ appId + "&secret=" + secret;
JSONObject json = WeixinUtil.httpRequest(url, "GET", null);
if (json != null) {
//要注意,由于微信限制access_token获取次数,access_token需要缓存,
//建议由程序统一获取和刷新access_token,其他业务逻辑所使用的access_token均来自于该统一获取的access_token,不应该各自去刷新,
//目前access_token的有效期为7200秒,此处示例代码不做处理,实际开发请自行处理
access_token = json.getString("access_token");
url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token="+ access_token + "&type=jsapi";
json = WeixinUtil.httpRequest(url, "GET", null);
if (json != null) {
jsapi_ticket = json.getString("ticket");
}
}
String signature = "";
// 注意这里参数名必须全部小写,且必须有序
String sign = "jsapi_ticket=" + jsapi_ticket + "&noncestr=" + nonceStr+ "×tamp=" + timestamp + "&url=" + requestUrl;
try {
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(sign.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
ret.put("appId", appId);
ret.put("timestamp", timestamp);
ret.put("nonceStr", nonceStr);
ret.put("signature", signature);
return ret;
}
/**
* 方法名:byteToHex</br>
* 详述:字符串加密辅助方法 </br>
* 开发人员:souvc </br>
* 创建时间:2016-1-5 </br>
* @param hash
* @return 说明返回值含义
* @throws 说明发生此异常的条件
*/
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;
}
}
4.测试controller
其中title/desc等字段亦可由前端通过js代入
@Controller
public class TestController {
@RequestMapping(value = "/test", method = RequestMethod.GET)
public ModelAndView test(HttpServletRequest request){
ModelAndView model = new ModelAndView();
Map<String,Object> ret = new HashMap<String,Object>();
//获取必要参数信息
ret= WeixinUtil.getWxConfig(request);
根据业务编写业务代码
//......
//加入需要展示的标题title
ret.put("title", "xxx");
//加入需要展示的详情desc
ret.put("desc", "xxx");
//获取URL
String url = request.getRequestURL().toString();
//加入需要展示的详情URL
ret.put("link", url);
model.addObject("wxConfig",ret);
//返回页面
model.setViewName("test");
return model;
}
}
5.HTML页面
//1.引入js
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
//2.通过config接口注入权限验证配置
wx.config({
debug: true,
appId: '[(${wxConfig.appId})]',
timestamp: '[(${wxConfig.timestamp})]',
nonceStr: '[(${wxConfig.nonceStr})]',
signature: '[(${wxConfig.signature})]',
jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData']
});
//3.通过ready接口处理成功验证,并调用相应接口
wx.ready(function(){
// 获取“分享到朋友圈”按钮点击状态及自定义分享内容接口
wx.updateAppMessageShareData({
title: '[(${wxConfig.title})]', // 分享标题
desc: '[(${wxConfig.desc})]', // 分享描述
link: '[(${wxConfig.link})]', //分享URL
imgUrl: "https://picsum.photos/200/200", // 分享图标,此处我测试使用了外部图片
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
// 获取“分享给朋友”按钮点击状态及自定义分享内容接口
wx.updateTimelineShareData({
title: '[(${wxConfig.title})]', // 分享标题
link: '[(${wxConfig.link})]', //分享URL
//分享给朋友不需要使用分享描述desc字段
imgUrl: "https://picsum.photos/200/200", // 分享图标,此处我测试使用了外部图片
success: function () {
// 用户确认分享后执行的回调函数
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
});
6.在微信公众号配置中添加JS接口安全域名
7.测试效果
分享给好友:
分享到朋友圈:
8.完成