顺便说一下微信公共测试号的申请,不需要准备任何材料,除了部分需要认证的接口,大部分都可以调用,提供一下链接点我获取
官方文档点击查看
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配置
扫描二维码关注公众号,回复:
497564 查看本文章
<!-- 定时器 --> <task:annotation-driven /> <bean class="com.phil.common.task.SpringTaskController" />