`

Java微信公众平台开发之AccessToken获取

阅读更多

顺便说一下微信公共测试号的申请,不需要准备任何材料,除了部分需要认证的接口,大部分都可以调用,提供一下链接点我获取

官方文档点击查看

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

调用接口时,请登录“微信公众平台-开发-基本配置”提前将服务器IP地址添加到IP白名单中,点击查看设置方法,否则将无法调用成功

可以用redis、mc这种去缓存,或者直接保存到数据库,或者直接保存为application

提供个保存到数据库的方法,redis缓存,目前我已经弃用数据库保存了,连定时任务都不需要了

一、access_token实体类

package com.phil.wechatauth.entity;

import com.phil.common.entity.AbstractEntity;

/**
 * 微信的access_token
 * @author phil
 * @date  2017年7月9日
 *
 */
public class WechatAccessToken extends AbstractEntity {
	/**
	 * 
	 */
	private static final long serialVersionUID = 123771404997810930L;
	
	private String token;

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}
}

 

二、获取并保存

 

package com.phil.wechatauth.service.impl;

import java.util.TreeMap;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.phil.common.config.WechatConfig;
import com.phil.common.util.DateTimeUtil;
import com.phil.common.util.HttpReqUtil;
import com.phil.common.util.JsonUtil;
import com.phil.common.util.UUIDGenerator;
import com.phil.wechatauth.dao.WechatAccessTokenMapper;
import com.phil.wechatauth.entity.WechatAccessToken;
import com.phil.wechatauth.model.resp.AccessToken;
import com.phil.wechatauth.service.AuthTokenService;

/**
 * AuthToken Service
 * @author phil
 * @date 2017年7月9日
 *
 */
@Service
public class AuthTokenServiceImpl implements AuthTokenService {

	private static final Logger logger = Logger.getLogger(AuthTokenServiceImpl.class);

	@Autowired
	private WechatAccessTokenMapper wechatAccessTokenMapper;

	@Transactional(readOnly=true)
	public String findlastestToken() {
		String accessToken = wechatAccessTokenMapper.findlastestToken();
		if(StringUtils.isNotBlank(accessToken)){
			logger.info("accessToken of search is " + accessToken.substring(0, 10) + "...");
		}
		return accessToken;
	}
	
	@Override
	@Transactional(readOnly=false)
	public void saveToken() throws Exception {
		TreeMap<String, String> map = new TreeMap<String, String>();
		map.put("grant_type", "client_credential");
		map.put("appid", WechatConfig.APP_ID);
		map.put("secret", WechatConfig.APP_SECRET);
		String result = HttpReqUtil.HttpsDefaultExecute(HttpReqUtil.GET_METHOD, WechatConfig.TOKEN_PATH, map, "");
		AccessToken accessToken = JsonUtil.fromJson(result, AccessToken.class);
		try {
			if(accessToken.getAccess_token()==null){
				throw new Exception("");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		WechatAccessToken wechatAccessToken = new WechatAccessToken();
		wechatAccessToken.setId(UUIDGenerator.generate().toString());
		wechatAccessToken.setToken(accessToken.getAccess_token());
		wechatAccessToken.setCreateTime(DateTimeUtil.currentTime());
		wechatAccessTokenMapper.saveToken(wechatAccessToken);
	}
}

 

三、项目启动初始化

package com.phil.common.listener;

import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import com.phil.wechatauth.service.AuthTokenService;

/**
 * 初始化生成微信token
 * 
 * @author phil
 * @date 2017年7月9日
 *
 */
@Component
public class InitWechatAuthListener implements ApplicationListener<ContextRefreshedEvent> {

	private static final Logger logger = Logger.getLogger(InitWechatAuthListener.class);

	@Autowired
	private RedisTemplate<String, Object> redisTemplate;

	@Autowired
	private AuthTokenService authTokenService;

	private static boolean isStart = false; // 防止二次调用

	@Override
	public void onApplicationEvent(ContextRefreshedEvent event) {
		if (!isStart) {
			isStart = true;
			String token = authTokenService.findlastestToken();
			if (StringUtils.isBlank(token)) {
				logger.info("token is null in db");
				try {
					authTokenService.saveToken();
					token = authTokenService.findlastestToken();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			// 添加一个 key
			ValueOperations<String, Object> value = redisTemplate.opsForValue();
			value.set("phil_token", token, 7200, TimeUnit.SECONDS); // 7200秒有效期
		}
	}
}

 

四、定时刷新

package com.phil.common.task;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.phil.wechatauth.service.AuthTokenService;

/**
 * Spring调度,指定时间执行 利用了spring中使用注解的方式来进行任务调度。
 * @author phil
 * @date  2017年7月9日
 *
 */
@Component
@Lazy(false)
public class SpringTaskController {
	
	private static final Logger logger = Logger.getLogger(SpringTaskController.class);
	
	@Autowired
	private AuthTokenService authTokenService;
	
	/**
	 * 每小时抓取一次
	 */
	@Scheduled(cron = "0 0 0/1 * * ? ")
	public void scheduleSaveToken(){
	
		try {
			authTokenService.saveToken();
		} catch (Exception e) {
			logger.info("抓取失败,please check");
			/**** 发邮件/电话 ****/
			e.printStackTrace();
		}
	}
}

spring配置

<!-- 定时器 -->
<task:annotation-driven />
<bean class="com.phil.common.task.SpringTaskController" />

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics