获取access_token和ticket,access_token有效时常7200秒,每天限制获取最大200次,因此不能时时获取需写定时器来获取
代码说明
先在项目web.xml配置定时任务的监听
<listener>
<listener-class>
com.dmsc.web.h5.jssdk.timer.SysContextListener
</listener-class>
</listener>
定时任务的代码
package com.dmsc.web.h5.jssdk.timer;
import java.util.Timer;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SysContextListener implements ServletContextListener {
private Timer timer=null;
@Override
public void contextDestroyed(ServletContextEvent event) {
//在这里关闭监听器,所以在这里销毁定时器。
timer.cancel();
event.getServletContext().log("定时器销毁");
}
@Override
public void contextInitialized(ServletContextEvent event) {
//在这里初始化监听器,在tomcat启动的时候监听器启动,可以在这里实现定时器功能
timer = new Timer(true);
event.getServletContext().log("定时器已启动");//添加日志,可在tomcat日志中查看到
timer.schedule(new ExportHistoryBean(event.getServletContext()),0,60*60*1000);//调用exportHistoryBean,0表示任务无延迟,5*1000表示每隔5秒执行任务,60*60*1000表示一个小时。
event.getServletContext().log("已经添加任务");
}
}
定时任务处理业务
package com.dmsc.web.h5.jssdk.timer;
import java.io.IOException;
import java.util.TimerTask;
import javax.servlet.ServletContext;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.lang.StringUtils;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.dmsc.web.base.utils.Constants;
public class ExportHistoryBean extends TimerTask {
private static boolean isRunning = false;
private ServletContext context = null;
public ExportHistoryBean(ServletContext context)
{
this.context = context;
}
public void run()
{
if(!isRunning)
{
isRunning = true;
context.log("开始执行指定任务");
//-------------------开始保存当日历史记录
String token;
try {
token = getAccess_token(Constants.getParamValueByName("weixin_appid"), Constants.getParamValueByName("weixin_appsecret"));
System.out.println("token:"+token);
String ticket=getJsApiTicket(token);
context.setAttribute("ticket", ticket);//在把ticket保存在session中功能页面使用这个参数
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
//-------------------结束
isRunning = false;
context.log("指定任务执行结束");
}
else
{
context.log("上一次任务执行还未结束");
}
}
public String getAccess_token(String appid, String appsecret) throws Exception, IOException {
//凭证获取(GET)
String token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
String requestUrl = token_url.replace("APPID", appid).replace("APPSECRET", appsecret);
// 发起GET请求获取凭证
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(requestUrl);
int status = client.executeMethod(method);
String access_token = null;
if(200 == status){
String responseValue =new String(method.getResponseBodyAsString().getBytes("UTF-8"));
// logger.debug(">>>>>>> responseValue:"+responseValue);
if(StringUtils.isNotBlank(responseValue)){
JSONObject json = JSONObject.parseObject(responseValue);
if(!json.isEmpty()){
try {
access_token = json.getString("access_token");
} catch (JSONException e) {
// 获取token失败
// logger.debug("获取token失败 errcode:{} errmsg:{}", json.getShort("errcode"), json.getString("errmsg"));
}
}
}
}
return access_token;
}
/**
* 调用微信JS接口的临时票据
*
* @param access_token 接口访问凭证
* @return
* @throws IOException
* @throws HttpException
*/
public String getJsApiTicket(String access_token) throws HttpException, IOException {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi";
String requestUrl = url.replace("ACCESS_TOKEN", access_token);
// 发起GET请求获取凭证
HttpClient client = new HttpClient();
GetMethod method = new GetMethod(requestUrl);
int status = client.executeMethod(method);
String ticket = null;
if(200 == status){
String responseValue =new String(method.getResponseBodyAsString().getBytes("UTF-8"));
// logger.debug(">>>>>>> responseValue:"+responseValue);
JSONObject json = JSONObject.parseObject(responseValue);
if(!json.isEmpty()){
try {
ticket = json.getString("ticket");
} catch (JSONException e) {
// 获取token失败
// logger.debug("获取ticket失败 errcode:{} errmsg:{}", json.getShort("errcode"), json.getString("errmsg"));
}
}
}
return ticket;
}
}
打开使用jssdk页面的方法需要处理关于jssdk的代码
String urlStr = request.getRequestURL().toString();//获取你请求的url地址
if (request.getQueryString() != null) {
urlStr += "?" + request.getQueryString();//地址拼接上请求参数
}
Map<String, String> ret = channelService.sign(request.getSession()
.getServletContext().getAttribute("ticket").toString(),
urlStr);//对地址进行签证
for (Map.Entry entry : ret.entrySet()) {
System.out.println(entry.getKey() + ", " + entry.getValue());
if ("timestamp".equals(entry.getKey())) {
model.put("timestamp", entry.getValue());
}
if ("nonceStr".equals(entry.getKey())) {
model.put("nonceStr", entry.getValue());
}
if ("signature".equals(entry.getKey())) {
model.put("signature", entry.getValue());
}
}
jssdk签证的代码
public Map<String, String> sign(String jsapi_ticket, String url) {
Map<String, String> ret = new HashMap<String, String>();
String nonce_str = create_nonce_str();
String timestamp = create_timestamp();
String string1;
String signature = "";
//注意这里参数名必须全部小写,且必须有序
string1 = "jsapi_ticket=" + jsapi_ticket +
"&noncestr=" + nonce_str +
"×tamp=" + timestamp +
"&url=" + url;
System.out.println(string1);
try
{
MessageDigest crypt = MessageDigest.getInstance("SHA-1");
crypt.reset();
crypt.update(string1.getBytes("UTF-8"));
signature = byteToHex(crypt.digest());
}
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;
}
到页面时
<script>
/*
* 注意:
* 1. 所有的JS接口只能在公众号绑定的域名下调用,公众号开发者需要先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
* 2. 如果发现在 Android 不能分享自定义内容,请到官网下载最新的包覆盖安装,Android 自定义分享接口需升级至 6.0.2.58 版本及以上。
* 3. 常见问题及完整 JS-SDK 文档地址:http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html
*
* 开发中遇到问题详见文档“附录5-常见错误及解决办法”解决,如仍未能解决可通过以下渠道反馈:
* 邮箱地址:weixin-open@qq.com
* 邮件主题:【微信JS-SDK反馈】具体问题
* 邮件内容说明:用简明的语言描述问题所在,并交代清楚遇到该问题的场景,可附上截屏图片,微信团队会尽快处理你的反馈。
*/
var timestampStr="${timestamp}";//这3个参数就是上面保存的
var nonceString="${nonceStr}";
var signatureStr="${signature}";
wx.config({
debug: false,
appId: 'appid',
timestamp: timestampStr,
nonceStr: nonceString,
signature: signatureStr,
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage'
]
});
</script>
最后页面在引用jssdk提供的几个js文件就可以了
<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script src="${ctx}/res/skin/h5/prizephase/js/zepto.min.js"></script>
<script src="${ctx}/res/skin/h5/prizephase/js/demo.js"></script>
在jssdk分享的事件触发方法
function idvalue(obj){
$('.pop-wrap').show();
imgUrlStr=$("#img_"+obj)[0].src;
linkStr=domianUrl+$("#link_"+obj).html()+"&channelId="+channelId;
titleStr=$("#title_"+obj).text();
var shareData = {
title: titleStr,
desc: linkStr,
link: linkStr,
imgUrl: imgUrlStr
};
wx.onMenuShareAppMessage(shareData);
wx.onMenuShareTimeline(shareData);
}