定時獲取微信的AccessToken

使用Quartz 2.2.3開啟定時任務谭期,每個整點獲取一次仅炊,如下:

String jobName = "GetWeixinAccessToken";
String triggerName = jobName;
// 每個整點執(zhí)行一次
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();
            // 任務名跑杭,任務組嚷那,任務執(zhí)行類
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
                    .withIdentity(jobName).build();
            jobDetail.getJobDataMap().put("obj", obj);
            // 觸發(fā)器
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder
                    .newTrigger();
            // 觸發(fā)器名
            triggerBuilder.withIdentity(triggerName);
            triggerBuilder.startNow();
            // 觸發(fā)器時間設定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 創(chuàng)建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 觸發(fā)器名 
         * @param triggerGroupName 觸發(fā)器組名 
         * @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();  
                // 任務名压真,任務組,任務執(zhí)行類
                JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();

                // 觸發(fā)器  
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 觸發(fā)器名,觸發(fā)器組  
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 觸發(fā)器時間設定  
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 創(chuàng)建Trigger對象
                CronTrigger trigger = (CronTrigger) triggerBuilder.build();

                // 調度容器設置JobDetail和Trigger
                sched.scheduleJob(jobDetail, trigger);  

                // 啟動  
                if (!sched.isShutdown()) {  
                    sched.start();  
                }  
            } catch (Exception e) {  
                throw new RuntimeException(e);  
            }  
        }  

    /**
     * 修改任務的觸發(fā)時間
     * @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 開始 */
                // 觸發(fā)器
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder
                        .newTrigger();
                // 觸發(fā)器名,觸發(fā)器組
                triggerBuilder.withIdentity(triggerName);
                triggerBuilder.startNow();
                // 觸發(fā)器時間設定
                triggerBuilder.withSchedule(CronScheduleBuilder
                        .cronSchedule(cron));
                // 創(chuàng)建Trigger對象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一個任務的觸發(fā)時間
                sched.rescheduleJob(triggerKey, trigger);
                /** 方式一 :調用 rescheduleJob 結束 */

                /** 方式二:先刪除蘑险,然后在創(chuàng)建一個新的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);
                /** 方式二 :先刪除滴肿,然后在創(chuàng)建一個新的Job */
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
        /** 
         * @Description: 修改一個任務的觸發(fā)時間
         *  
         * @param jobName 
         * @param jobGroupName
         * @param triggerName 觸發(fā)器名
         * @param triggerGroupName 觸發(fā)器組名 
         * @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 開始 */
                    // 觸發(fā)器  
                    TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                    // 觸發(fā)器名,觸發(fā)器組  
                    triggerBuilder.withIdentity(triggerName, triggerGroupName);
                    triggerBuilder.startNow();
                    // 觸發(fā)器時間設定  
                    triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                    // 創(chuàng)建Trigger對象
                    trigger = (CronTrigger) triggerBuilder.build();
                    // 方式一 :修改一個任務的觸發(fā)時間
                    sched.rescheduleJob(triggerKey, trigger);
                    /** 方式一 :調用 rescheduleJob 結束 */

                    /** 方式二:先刪除佃迄,然后在創(chuàng)建一個新的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); 
                    /** 方式二 :先刪除泼差,然后在創(chuàng)建一個新的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);// 停止觸發(fā)器
            sched.unscheduleJob(triggerKey);// 移除觸發(fā)器
            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);// 停止觸發(fā)器  
                sched.unscheduleJob(triggerKey);// 移除觸發(fā)器  
                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是否在執(zhí)行隊列中
         * @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到數(shù)據(jù)庫中。實現(xiàn)如下:

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;
        // 每個整點執(zhí)行一次
        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來管理數(shù)據(jù)庫存放的AccessToken
    }
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子缀皱,更是在濱河造成了極大的恐慌斗这,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啤斗,死亡現(xiàn)場離奇詭異表箭,居然都是意外死亡,警方通過查閱死者的電腦和手機钮莲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門免钻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人崔拥,你說我怎么就攤上這事伯襟。” “怎么了握童?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵姆怪,是天一觀的道長。 經常有香客問我澡绩,道長稽揭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任肥卡,我火速辦了婚禮溪掀,結果婚禮上,老公的妹妹穿的比我還像新娘步鉴。我一直安慰自己揪胃,他們只是感情好,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布氛琢。 她就那樣靜靜地躺著喊递,像睡著了一般。 火紅的嫁衣襯著肌膚如雪阳似。 梳的紋絲不亂的頭發(fā)上骚勘,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天,我揣著相機與錄音撮奏,去河邊找鬼俏讹。 笑死,一個胖子當著我的面吹牛畜吊,可吹牛的內容都是我干的泽疆。 我是一名探鬼主播,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼玲献,長吁一口氣:“原來是場噩夢啊……” “哼殉疼!你這毒婦竟也來了梯浪?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤株依,失蹤者是張志新(化名)和其女友劉穎驱证,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體恋腕,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡抹锄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了荠藤。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片伙单。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖哈肖,靈堂內的尸體忽然破棺而出吻育,到底是詐尸還是另有隱情,我是刑警寧澤淤井,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布布疼,位于F島的核電站,受9級特大地震影響币狠,放射性物質發(fā)生泄漏游两。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一漩绵、第九天 我趴在偏房一處隱蔽的房頂上張望贱案。 院中可真熱鬧,春花似錦止吐、人聲如沸宝踪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瘩燥。三九已至,卻和暖如春蕴忆,著一層夾襖步出監(jiān)牢的瞬間颤芬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工套鹅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人汰具。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓卓鹿,卻偏偏與公主長得像,于是被迫代替她去往敵國和親留荔。 傳聞我的和親對象是個殘疾皇子吟孙,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354

推薦閱讀更多精彩內容

  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,810評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理澜倦,服務發(fā)現(xiàn),斷路器杰妓,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • spring官方文檔:http://docs.spring.io/spring/docs/current/spri...
    牛馬風情閱讀 1,679評論 0 3
  • 她和她第一次見面是在食堂藻治。 盛夏的雨天。 為了能夠方便區(qū)分巷挥,我們把她稱為紅衣的她桩卵,把她稱為黑衣的她。再簡單一點倍宾,把...
    W曉花閱讀 641評論 0 3
  • 1.感賞兒子繼續(xù)做到不玩游戲,學習效率特別高,自制力越來越好!感賞兒子百度查東西高职,用語音輸入钩乍,比我的習慣打字快多了...
    玫瑰鏗鏘閱讀 255評論 2 9