定时获取微信的 AccessToken
使用 Quartz 2.2.3 开启定时任务,每个整点获取一次,如下:
String jobName = "GetWeixinAccessToken";
String triggerName = jobName;
// 每个整点执行一次
quartzManager.addJob(jobName, triggerName, WeixinAccessTokenJob.class, "0 0 */1 * * ?", wxAccesstokenManager);
QuartzManager 使用 Spring 注入:
import java.util.Date;
import java.util.List;
import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.Trigger;
import org.quartz.TriggerBuilder;
import org.quartz.TriggerKey;
import org.quartz.impl.StdSchedulerFactory;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.stereotype.Service;
@Service
public class QuartzManager {
public static SchedulerFactory schedulerFactory = new StdSchedulerFactory();
public void addJob(String jobName, String triggerName,
Class jobClass, String cron, Object obj) {
try {
Scheduler sched = schedulerFactory.getScheduler();
// 任务名,任务组,任务执行类
JobDetail jobDetail = JobBuilder.newJob(jobClass)
.withIdentity(jobName).build();
jobDetail.getJobDataMap().put("obj", obj);
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder
.newTrigger();
// 触发器名
triggerBuilder.withIdentity(triggerName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建 Trigger 对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置 JobDetail 和 Trigger
sched.scheduleJob(jobDetail, trigger);
// 启动
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 添加一个定时任务
*
* @param jobName 任务名
* @param jobGroupName 任务组名
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param jobClass 任务
* @param cron 时间设置,参考 quartz 说明文档
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public void addJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName, Class jobClass, String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
// 任务名,任务组,任务执行类
JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建 Trigger 对象
CronTrigger trigger = (CronTrigger) triggerBuilder.build();
// 调度容器设置 JobDetail 和 Trigger
sched.scheduleJob(jobDetail, trigger);
// 启动
if (!sched.isShutdown()) {
sched.start();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 修改任务的触发时间
* @param jobName
* @param triggerName
* @param cron
*/
public void modifyJobTime(String jobName, String triggerName,
String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
/** 方式一 :调用 rescheduleJob 开始 */
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder
.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder
.cronSchedule(cron));
// 创建 Trigger 对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
sched.rescheduleJob(triggerKey, trigger);
/** 方式一 :调用 rescheduleJob 结束 */
/** 方式二:先删除,然后在创建一个新的 Job */
// JobDetail jobDetail =
// sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
// Class<? extends Job> jobClass = jobDetail.getJobClass();
// removeJob(jobName, jobGroupName, triggerName,
// triggerGroupName);
// addJob(jobName, jobGroupName, triggerName, triggerGroupName,
// jobClass, cron);
/** 方式二 :先删除,然后在创建一个新的 Job */
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 修改一个任务的触发时间
*
* @param jobName
* @param jobGroupName
* @param triggerName 触发器名
* @param triggerGroupName 触发器组名
* @param cron 时间设置,参考 quartz 说明文档
*/
public void modifyJobTime(String jobName,
String jobGroupName, String triggerName, String triggerGroupName, String cron) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
CronTrigger trigger = (CronTrigger) sched.getTrigger(triggerKey);
if (trigger == null) {
return;
}
String oldTime = trigger.getCronExpression();
if (!oldTime.equalsIgnoreCase(cron)) {
/** 方式一 :调用 rescheduleJob 开始 */
// 触发器
TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
// 触发器名,触发器组
triggerBuilder.withIdentity(triggerName, triggerGroupName);
triggerBuilder.startNow();
// 触发器时间设定
triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
// 创建 Trigger 对象
trigger = (CronTrigger) triggerBuilder.build();
// 方式一 :修改一个任务的触发时间
sched.rescheduleJob(triggerKey, trigger);
/** 方式一 :调用 rescheduleJob 结束 */
/** 方式二:先删除,然后在创建一个新的 Job */
//JobDetail jobDetail = sched.getJobDetail(JobKey.jobKey(jobName, jobGroupName));
//Class<? extends Job> jobClass = jobDetail.getJobClass();
//removeJob(jobName, jobGroupName, triggerName, triggerGroupName);
//addJob(jobName, jobGroupName, triggerName, triggerGroupName, jobClass, cron);
/** 方式二 :先删除,然后在创建一个新的 Job */
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务
*
* @param jobName
* @param triggerName
*/
public void removeJob(String jobName, String triggerName) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName);
sched.pauseTrigger(triggerKey);// 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
sched.deleteJob(JobKey.jobKey(jobName));// 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description: 移除一个任务
*
* @param jobName
* @param jobGroupName
* @param triggerName
* @param triggerGroupName
*/
public void removeJob(String jobName, String jobGroupName,
String triggerName, String triggerGroupName) {
try {
Scheduler sched = schedulerFactory.getScheduler();
TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
sched.pauseTrigger(triggerKey);// 停止触发器
sched.unscheduleJob(triggerKey);// 移除触发器
sched.deleteJob(JobKey.jobKey(jobName, jobGroupName));// 删除任务
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:启动所有定时任务
*/
public static void startJobs() {
try {
Scheduler sched = schedulerFactory.getScheduler();
sched.start();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @Description:关闭所有定时任务
*/
public static void shutdownJobs() {
try {
Scheduler sched = schedulerFactory.getScheduler();
if (!sched.isShutdown()) {
sched.shutdown();
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 判断 JobName 是否在执行队列中
* @param jobName
* @return
*/
public synchronized static boolean isJobExist(String jobName) throws SchedulerException {
boolean isExistJob = false;
Scheduler scheduler = schedulerFactory.getScheduler();
for (String groupName : scheduler.getJobGroupNames()) {
for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher
.jobGroupEquals(groupName))) {
String tmpJobName = jobKey.getName();
String jobGroup = jobKey.getGroup();
// get job's trigger
@SuppressWarnings("unchecked")
List<Trigger> triggers = (List<Trigger>) scheduler
.getTriggersOfJob(jobKey);
Date nextFireTime = triggers.get(0).getNextFireTime();
System.out.println("[jobName] : " + tmpJobName
+ " [groupName] : " + jobGroup + " - "
+ nextFireTime);
if (tmpJobName.equals(jobName)) {
return true;
}
}
}
return isExistJob;
}
}
在 Spring ApplicationContext 注入后,才可获取 bean,web.xml 配置拦截如下:
<!--Spring ApplicationContext 载入 -->
<listener>
<!-- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> -->
<listener-class>com.test.hello.ContextLoaderListenerOverWrite</listener-class>
</listener>
拦截类是为了获取 manager,然后存放 AccessToken 到数据库中。实现如下:
public class ContextLoaderListenerOverWrite extends ContextLoaderListener {
@Override
public void contextInitialized(ServletContextEvent event) {
// TODO Auto-generated method stub
super.contextInitialized(event);
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
startGetWeixinAccessTokenJobs(applicationContext);
}
/**
* 开启整点定时任务
*/
public void startGetWeixinAccessTokenJobs(ApplicationContext ctx) {
WxBean currentBean = Utility.getAccessToken();
WxAccesstoken currentToken = new WxAccesstoken();
currentToken.setAccesstoken(currentBean.getAccess_token());
currentToken.setExpiresIn(Integer.valueOf(currentBean.getExpires_in()));
currentToken.setLastRequestTime(new Date());
QuartzManager quartzManager = (QuartzManager)ctx.getBean("quartzManager");
WxAccesstokenManager wxAccesstokenManager = (WxAccesstokenManager)ctx.getBean("wxAccesstokenManager");
WxAccesstoken dbWxToken = wxAccesstokenManager.findFirst();
if (dbWxToken == null) { // 新增 Token
wxAccesstokenManager.save(currentToken);
System.out.println("新增 Token:" + currentToken);
} else { // 更新 Token
currentToken.setId(dbWxToken.getId());
wxAccesstokenManager.update(currentToken);
System.out.println("更新 Token:" + currentToken);
}
String jobName = "GetWeixinAccessToken";
String triggerName = jobName;
// 每个整点执行一次
quartzManager.addJob(jobName, triggerName, WeixinAccessTokenJob.class, "0 0 */1 * * ?", wxAccesstokenManager);
}
}
获取微信 AccessToken 的办法如下:
/**
* 获取微信的 AccessToken
* @return
*/
public static WxBean getAccessToken() {
WxBean bean = null;
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type", "client_credential");
params.put("appid", Constants.WEIXIN_APPID);
params.put("secret", Constants.WEIXIN_APPSECRET);
try {
String jstoken = HttpUtils.sendGet(
"https://api.weixin.qq.com/cgi-bin/token", params);
// String access_token = JSONObject.fromObject(jstoken).getString(
// "access_token"); // 获取到 token 并赋值保存
ObjectMapper objectMapper = JsonUtils.createObjectMapper();
try {
bean = objectMapper.readValue(jstoken, WxBean.class);
} catch (JsonParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JsonMappingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bean;
}
对了,还有关键的部分,在这个 Job 里面每个整点更新 AccessToken
public class WeixinAccessTokenJob implements Job{
public WeixinAccessTokenJob() {
}
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
//打印任务详情
System.out.println( "WeixinTokenJob:" + "-" +
context.getJobDetail().getKey().getGroup()
+"——"+context.getJobDetail().getKey().getName()
+"——"+context.getTrigger().getKey().getName()
+"——"+context.getTrigger().getKey().getGroup() + new Date());
JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
WxAccesstokenManager wxAccesstokenManager = (WxAccesstokenManager)jobDataMap.get("obj");
// Todo 使用 wxAccesstokenManager 来管理数据库存放的 AccessToken
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
上一篇: 使用正则表达式提取时间中的数字
下一篇: 谈谈自己对于 AOP 的了解
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论