微信分享
后台逻辑
import java.io.UnsupportedEncodingException;
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 org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alibaba.fastjson.JSONObject;
import cn.com.sinosoft.util.CommonUtil;
import cn.com.sinosoft.util.HttpUtil;
@Controller
public class WxShareController {
private Logger log = Logger.getLogger(this.getClass());
//获取相关的参数,在application.properties文件中
// @Value("${wechat.appId}")
private String appId ="8783214d";
// @Value("${wechat.appSecret}")
private String appSecret ="6b947a42845a74dde114";
// @Value("${wechat.url.accessToken}")
private String accessTokenUrl ="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
// @Value("${wechat.url.apiTicket}")
private String apiTicketUrl ="https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
//微信参数
private String accessToken;
private String jsApiTicket;
//获取参数的时刻
private Long getTiketTime = 0L;
private Long getTokenTime = 0L;
//参数的有效时间,单位是秒(s)
private Long tokenExpireTime = 0L;
private Long ticketExpireTime = 0L;
//获取微信参数
@RequestMapping("/wechatParam")
@ResponseBody
public Map<String, String> getWechatParam(String url) throws Exception{
//当前时间
long now = System.currentTimeMillis();
log.info("currentTime====>"+now+"ms");
//判断accessToken是否已经存在或者token是否过期
/*if(StringUtils.isBlank(accessToken)||(now - getTokenTime > tokenExpireTime*1000)){
JSONObject tokenInfo = getAccessToken();
log.info("————————————————————————————————+"+tokenInfo);
if(tokenInfo != null){
log.info("tokenInfo====>"+tokenInfo.toJSONString());
accessToken = tokenInfo.getString("access_token");
tokenExpireTime = tokenInfo.getLongValue("expires_in");
//获取token的时间
getTokenTime = System.currentTimeMillis();
log.info("accessToken====>"+accessToken);
log.info("tokenExpireTime====>"+tokenExpireTime+"s");
log.info("getTokenTime====>"+getTokenTime+"ms");
}else{
log.info("====>tokenInfo is null~");
log.info("====>failure of getting tokenInfo,please do some check~");
}
}*/
//判断jsApiTicket是否已经存在或者是否过期
if(StringUtils.isBlank(jsApiTicket)||(now - getTiketTime > ticketExpireTime*1000)){
JSONObject ticketInfo = getJsApiTicket();
if(ticketInfo!=null){
log.info("ticketInfo====>"+ticketInfo.toJSONString());
jsApiTicket = ticketInfo.getString("ticket");
ticketExpireTime = ticketInfo.getLongValue("expires_in");
getTiketTime = System.currentTimeMillis();
log.info("jsApiTicket====>"+jsApiTicket);
log.info("ticketExpireTime====>"+ticketExpireTime+"s");
log.info("getTiketTime====>"+getTiketTime+"ms");
}else{
log.info("====>ticketInfo is null~");
log.info("====>failure of getting tokenInfo,please do some check~");
}
}
//生成微信权限验证的参数
Map<String, String> wechatParam= makeWXTicket(jsApiTicket,url);
return wechatParam;
}
//获取accessToken
/*private JSONObject getAccessToken(){
//String accessTokenUrl = https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
String requestUrl = accessTokenUrl.replace("APPID",appId).replace("APPSECRET",appSecret);
log.info("getAccessToken.requestUrl====>"+requestUrl);
JSONObject result = HttpUtil.doGet(requestUrl);
return result ;
}*/
//获取ticket
private JSONObject getJsApiTicket() throws Exception{
//String apiTicketUrl = https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
accessToken = CommonUtil.getAccessToken();
String requestUrl = apiTicketUrl.replace("ACCESS_TOKEN", accessToken);
log.info("getJsApiTicket.requestUrl====>"+requestUrl);
JSONObject result = HttpUtil.doGet(requestUrl);
log.info("————————————————————"+result);
return result;
}
//生成微信权限验证的参数
public Map<String, String> makeWXTicket(String jsApiTicket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonceStr = createNonceStr();
String timestamp = createTimestamp();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsApiTicket +
"&noncestr=" + nonceStr +
"×tamp=" + timestamp +
"&url=" + url;
log.info("String1=====>"+string1);
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
log.info("signature=====>"+signature);
}
catch (NoSuchAlgorithmException e)
{
log.error("WeChatController.makeWXTicket=====Start");
log.error(e.getMessage(),e);
log.error("WeChatController.makeWXTicket=====End");
}
catch (UnsupportedEncodingException e)
{
log.error("WeChatController.makeWXTicket=====Start");
log.error(e.getMessage(),e);
log.error("WeChatController.makeWXTicket=====End");
}
ret.put("url", url);
ret.put("jsapi_ticket", jsApiTicket);
ret.put("nonceStr", nonceStr);
ret.put("timestamp", timestamp);
ret.put("signature", signature);
ret.put("appid", appId);
return ret;
}
//字节数组转换为十六进制字符串
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 createNonceStr() {
return UUID.randomUUID().toString();
}
//生成时间戳
private static String createTimestamp() {
return Long.toString(System.currentTimeMillis() / 1000);
}
}
前端页面调用微信分享接口
只要在js中引入微信的js脚本
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
其他的js直接模仿,修改link,appid ,script即可
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes">
<!-- <meta http-equiv="refresh" content="5" /> --><!--每隔5秒,网页刷新一次-->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>(通过分享页面进入的)</title>
<link rel="stylesheet" href="/MyVotes/css/bootstrap.css"/>
<link rel="stylesheet" href="/MyVotes/css/activiAll.css"/>
<script type="text/javascript" src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<style>
html body{
/* background-color: red;
*/
background: -webkit-linear-gradient(to bottom, rgba(255, 0, 0, 0.31), rgb(184, 92, 195)); /* Safari 5.1 - 6.0 */
background: -o-linear-gradient(to bottom, rgba(255, 0, 0, 0.31), rgb(184, 92, 195));/* Opera 11.1 - 12.0 */
background: -moz-linear-gradient(to bottom, rgba(255, 0, 0, 0.31), rgb(184, 92, 195));/* Firefox 3.6 - 15 */
background: linear-gradient(to bottom, rgba(255, 0, 0, 0.31), rgb(184, 92, 195)); /* 标准的语法 */
}
.container{padding-top: 10px; padding-left: 10px;padding-right: 10px; }
.hwtj{
text-align: center;
border-radius: 8px;
width:100%;
height:500px;
background-color: white;
}
.hwtjDiv{
width: 94%;
background-color: #f9f3f3;
display: inline-block;
position: relative;
text-align: center;
margin:10px 10px ;
border-top:1px solid #f0f0f0;
border-radius: 8px;
height: 140px;
}
.hwtjDiv img{
top: 0;
left: 0;
width: 120px;
height: 120px;
float:left;
margin-left: 10px;
margin-top: 10px;
}
footer{
position: fixed;
bottom: 0;
width: 100%;
height: 60px;
color: #999;
border-top: 1px solid #969696;
z-index: 1;
background-color: #f0f0f0;
}
footer div{
display: inline-block;
width: 48%;
text-align: center;
margin-top: 5px;
}
.active{
#color: #af8d60 !important;
color: rgb(122,36,133) !important;
}
.btn-PT{
background-color: red;
color: white;
border: 1px solid red;
float: right;
padding: 4px 8px;
border-radius: 0.1rem;
font-size: 14px;
margin-left: 0.8rem;
margin-top: -0.6rem;
}
.proPS{font-size: 10px; color: #999; vertical-align: middle; }
.proYj{font-size: 10px; color: #999; text-decoration: line-through;}
.proDet{
height: 43px;
font-weight: bold;
text-overflow: ellipsis;
overflow: hidden;
font-size: 16px;
margin-bottom: 0rem;
text-align: left;
padding-left: 10px;
margin-right: 10px;
margin-top: 10px;
}
.proMon{
float: left;
color: red;
margin-bottom: 0rem;
padding-bottom: 0rem;
font-size: 14px;
margin-left: 10px;
text-align: left;
}
.proRenShu {
float: right;
color: #999;
margin-bottom: 0rem;
padding-bottom: 0rem;
font-size: 12px;
text-align: left;
margin-left: 10px;
}
.kjjdt font{color:red;}
.kjjdt p {font-size:18px;}
.xhp{color: red;}
.progress{margin-left: 30px; margin-right: 30px;height:10px;}
.progress-bar{
background-color: #f3f305;
height:10px;
}
.btn{
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
background-color: #f3f305;
border-radius: 30px;
width:300px;
font-size: 16px;
font-weight: bold;
color: red;
padding: 12px 12px;
/* margin-left: 50px;
margin-right: 50px;*/
}
.tableClass{
width: 300px;
background-color: #f9f3f3;
/* text-align: center; */
margin-left: 20px;
/* margin-right: 50px; */
border-radius: 10px;
margin-top: 10px;
text-align: left;
}
.tableClass img{
width:50px;
height:50px;
border-radius: 50%;
}
.prospec{
float: left;
margin-left: 10px;
text-align:left;
}
.modal-header {
padding: 15px;
border-bottom: 0px solid #e5e5e5;
}
.modal-content{background-color: #fff0!important;}
.modal-content-share{
position: relative;
background-color: #fff0!important;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 0px solid #999;
border:0px solid rgba(0, 0, 0, .2);
border-radius: 6px;
outline: 0;
-webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0);
box-shadow: 0 3px 9px rgba(0, 0, 0, 0);
}
.modal-body{
text-align: center;
position: relative;
/* padding: 30px; */
color: white;
padding-top: 40px;
}
</style>
</head>
<body>
<div class="container">
<div class="hwtj text-center" >
<a type="button"
href="https://open.weixin.qq.com/connect/oauth2/authorize?appid=fe1928b80fb&redirect_uri=http%3a%2f%2fwww.fsui.club%2fMyVotes%2fFxActivityController%2fselectUserAssistance&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect">
点我助力</a>
</div>
</div>
<footer style="position:fixed;background-color:white;">
<div class="_kjsp" >
<i class=" glyphicon glyphicon-gift"></i>
<p>首页</p>
</div>
<div class="_wdkj active">
<i class="glyphicon glyphicon-user"></i>
<p class="">我的活动</p>
</div>
</footer>
<div class="modal fade" style="background-color: #fff0" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" style="background-color: #fff0">
<div class="modal-content-share" style="background-color: #fff0">
<div class="modal-header" style="background-color: #fff0">
<img src="/MyVotes/images/arr_top.png" height="70" width="40" style="position: absolute; right: 0; top: 0;"/>
</div>
<div class="modal-body" style="font-size:20px;" style="background-color: #fff0">
</div>
</div><!-- /.modal-content -->
</div><!-- /.modal -->
<input type="hidden" id="first" value="${first }">
<%-- <input type="hidden" name="activity_id" value="${ap.activity.id }">
<input type="hidden" name="price" value="${ap.scProduct.price}">
<input type="hidden" name="ap_id" value="${ap.id }"> --%>
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript" src="/MyVotes/js/jquery-2.2.3.min.js"></script>
<script type="text/javascript" src="/MyVotes/dist/js/swiper.min.js"></script>
<script type="text/javascript" src="/MyVotes/js/jquery.countdown.min.js"></script>
<script type="text/javascript" src="/MyVotes/js/bootstrap.js"></script>
<script>
(function (doc, win) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (!clientWidth) return;
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
};
if (!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document, window);
</script>
<script>
$("footer div").click(function() {
$(this).addClass("active").siblings().removeClass("active");
});
$(".modal-content-share").css("background-color","#fff0");
$(".modal-content").css("background-color","#fff0");
if(${ap.scProduct.price - ua.price } ==0){
$(".pb").css("width", 0);
}else if(${ua.price - ap.price }==0) {
$(".pb").css("width", "100%");
}else{
var bfb = (${ap.scProduct.price - ua.price }/(${ap.scProduct.price - ua.price }+${ua.price - ap.price }))*100;
$(".pb").css("width", bfb+"%");
}
$(".pb2").css("width",0);
$('.countdown_kill').countdown("${ua.endtimestr }", function (event) {
$(this).html(event.strftime('%D天%H:%M:%S'));
})
$('.countdown_kill').countdown("${ua.endtimestr }").on('finish.countdown', function(){});
$(".container").height($(".container").height()+$("footer").height()+30);
</script>
<script>
$(function(){
var url = location.href.split('#').toString();//url不能写死
var appId = "13123fe1928b80fb";
var secret = "a123141231235b19f586";
var product_id=${ap.scProduct.id}
var activity_id=${ap.activity.id}
$.ajax({
type : "get",
url : "/MyVotes/wechatParam",
dataType : "json",
async : true,
data:{url:url},
success : function(data) {
wx.config({
debug: true,生产环境需要关闭debug模式
appId: data.appid,//appId通过微信服务号后台查看
timestamp: data.timestamp,//生成签名的时间戳
nonceStr: data.nonceStr,//生成签名的随机字符串
signature: data.signature,//签名
jsApiList: [//需要调用的JS接口列表
'checkJsApi',//判断当前客户端版本是否支持指定JS接口
'onMenuShareTimeline',//分享给好友
'onMenuShareAppMessage'//分享到朋友圈
]
});
},
error: function(xhr, status, error) {
// alert(status);
//alert(xhr.responseText);
}
})
wx.ready(function () {
wx.onMenuShareTimeline({
title: '${fxActivity.share_title}',
desc: '${fxActivity.share_text}', // 分享描述
//link:'https://open.weixin.qq.com/connect/oauth2/authorize?appid=33f312382636&redirect_uri=http%3A%2F%2F9finance.cc%2FMyVotes%2FkjOther%3Fua_id=${ua.id}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect'
link:'http://9finance.cc/MyVotes/getCode?userId=${user_id}&activityId=${fxActivity.id}',
imgUrl: 'http://9finance.cc/MyVotes/upload/${fxActivity.share_url}', // 分享图标 // 分享图标
success: function () {
// 用户确认分享后执行的回调函数
//alert("xxxxxx");
//var form_data = {"buttonName":'分享朋友圈',"source":window.location.href};
/* $.post({
url:"/MyVotes/addMyKj",
data:{
activity_id:${ap.activity.id},
price:${ap.scProduct.price},
ap_id:${ap.id},
},
async:false,
success:function(args){
if (args == 'success'){
alert("分享成功");
}
}
}) */
},
cancel: function () {
// 用户取消分享后执行的回调函数
//alert("-------");
}
});
//分享给朋友
wx.onMenuShareAppMessage({
title: '${fxActivity.share_title}',
desc: '${fxActivity.share_text}', // 分享描述
link:'http://9finance.cc/MyVotes/getCode?userId=${user_id}&activityId=${fxActivity.id}',
imgUrl: 'http://9finance.cc/MyVotes/upload/${fxActivity.share_url}', // 分享图标 // 分享图标
type: '', // 分享类型,music、video或link,不填默认为link
dataUrl: '', // 如果type是music或video,则要提供数据链接,默认为空
success: function () {
// 用户确认分享后执行的回调函数
//var form_data = {"buttonName":'分享朋友',"source":window.location.href};
/* $.post({
url:"/MyVotes/addMyKj",
data:{
activity_id:${ap.activity.id},
price:${ap.scProduct.price},
ap_id:${ap.id},
},
async:false,
success:function(args){
if (args == 'success'){
alert("生成成功");
}else{
alert("生成失败");
}
}
}) */
},
cancel: function () {
// 用户取消分享后执行的回调函数
}
});
wx.error(function (res) {
// alert(res.errMsg);
});
});
});