1.AuthAcsessToken的获取
继续上文,上文提到了想要发送消息,就要获取授权单独的authtoken,通过这个token才能调用微信发送消息接口。有六个步骤,少一步也获取不到这个authaccesstoken。
Token生成说明 | 微信开放文档
这里需要注意的是:
weixin-java-open没有实现消息发送,就要结合
weixin-java-mp使用,才能实现发送消息。
weixin-java-mp-demo: 基于Spring Boot 和 WxJava 实现的微信公众号Java后端Demo,支持多公众号
我们看最后一步,获取token需要的参数
2.代码部分
service
package com.test.wechat.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.test.sdk.service.impl.ImServiceImpl;
import com.test.wechat.config.WechatOpenConfigStorage;
import com.test.wechat.config.WechatOpenProperties;
import com.test.wechat.handler.*;
import com.test.wechat.util.HttpClientUtil;
import com.test.wechat.consts.WechatOpenConst;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.open.api.WxOpenComponentService;
import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter;
import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl;
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
/**
* @ClassName WechatOpenService
* @Description TODO
* @Author Jiangnan Cui
* @Date 2024-01-16 15:09
* @Version 1.0
*/
@Service
@EnableConfigurationProperties({WechatOpenProperties.class})
public class WechatOpenService extends WxOpenServiceImpl {
private Logger logger = LoggerFactory.getLogger(getClass());
@Autowired
protected LogHandler logHandler;
@Autowired
protected NullHandler nullHandler;
@Autowired
protected KfSessionHandler kfSessionHandler;
@Autowired
protected StoreCheckNotifyHandler storeCheckNotifyHandler;
@Autowired
private LocationHandler locationHandler;
@Autowired
private MenuHandler menuHandler;
@Autowired
private MsgHandler msgHandler;
@Autowired
private UnsubscribeHandler unsubscribeHandler;
@Autowired
private SubscribeHandler subscribeHandler;
@Autowired
private ValueOperations<String, Object> valOps;
private WxOpenMessageRouter router;
@Autowired
private WechatOpenConfigStorage wechatOpenConfigStorage;
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private ImServiceImpl imservice;
@PostConstruct
public void init() {
super.setWxOpenConfigStorage(wechatOpenConfigStorage);
this.refreshRouter();
// wxOpenMessageRouter = new WxOpenMessageRouter(this);
// wxOpenMessageRouter.rule().handler((wxMpXmlMessage, map, wxMpService, wxSessionManager) -> {
// logger.info("\n接收到 {} 公众号请求消息,内容:{}", wxMpService.getWxMpConfigStorage().getAppId(), wxMpXmlMessage);
// return null;
// }).next();
}
private void refreshRouter() {
final WxOpenMessageRouter newRouter = new WxOpenMessageRouter(this);
// 记录所有事件的日志
newRouter.rule().handler(this.logHandler).next();
// 自定义菜单事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.MenuButtonType.CLICK).handler(
this.getMenuHandler()).end();
// 点击菜单连接事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.MenuButtonType.VIEW).handler(
this.nullHandler).end();
// 关注事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SUBSCRIBE).handler(
this.getSubscribeHandler()).end();
// 取消关注事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.UNSUBSCRIBE).handler(
this.getUnsubscribeHandler()).end();
// 上报地理位置事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.LOCATION).handler(
this.getLocationHandler()).end();
// 接收地理位置消息
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION).handler(this.getLocationHandler()).end();
// 扫码事件
newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT).event(WxConsts.EventType.SCAN).handler(
this.getScanHandler()).end();
// 默认
newRouter.rule().async(false).handler(this.getMsgHandler()).end();
this.router = newRouter;
}
public WxMpXmlOutMessage route(WxMpXmlMessage message) {
try {
if (message.getMsgId() == null) {
return this.router.route(message);
} else if (!valOps.getOperations().hasKey("wx_" + message.getToUser() + "_" + message.getFromUser() + "_" + String.valueOf(message.getMsgId()))) {
valOps.set("wx_" + message.getToUser() + "_" + message.getFromUser() + "_" + String.valueOf(message.getMsgId()), String.valueOf(message.getMsgId()), 10, TimeUnit.SECONDS);
WxMpXmlOutMessage route = this.router.route(message);
return route;
} else {
logger.info("接收到了重复的消息,不予处理,msgid:{}", message.getMsgId());
}
} catch (Exception e) {
this.logger.error(e.getMessage(), e);
}
return null;
}
public WxOpenMessageRouter getWxOpenMessageRouter() {
return router;
}
protected AbstractHandler getScanHandler() {
return null;
}
/**
* 重写token获取方法
*/
public String getAccessToken(String key, boolean forceRefresh) throws WxErrorException {
Lock lock = this.wechatOpenConfigStorage.getAccessTokenLock();
try {
lock.lock();
/**
* 从redis中获取key对应的过期时间;
* 如果该值有过期时间,就返回相应的过期时间;
* 如果该值没有设置过期时间,就返回-1;
* 如果没有该值,就返回-2;
*/
String authorAppId = this.getWechatOpenConfigStorage().getAuthorAppId();
String authorizationCode = (String) valOps.get("wxOpen:" + authorAppId);
String refreshToken = this.getWechatOpenConfigStorage().getAuthorizerRefreshToken(null);
String componentAccessToken = (String) redisTemplate.opsForValue().get("wx_open_component_token_" + key);
logger.info("是否开启强制刷新微信WxOpen AuthorizerAccessToken 功能 forceRefresh:{} ,authorAppId:{} ,authorizationCode is {} ,componentAccessToken is {} ,refreshToken:{}", forceRefresh, authorAppId, authorizationCode, componentAccessToken, refreshToken);
Long expire = redisTemplate.opsForValue().getOperations().getExpire("wx_open_token_" + this.getWechatOpenConfigStorage().getAuthorAppId());
if (expire == -1) {
logger.info("WxOpen AuthorizerAccessToken 没有设置过期时间 {}", "wx_open_token_" + this.getWechatOpenConfigStorage().getAuthorAppId());
} else if (expire == -2 || forceRefresh) {
logger.info("WxOpen AuthorizerAccessToken redis中无该值存在 {},forceRefresh is {}", "wx_open_token_" + this.getWechatOpenConfigStorage().getAuthorAppId(), forceRefresh);
String url = getWechatOpenConfigStorage().getThirdAccessTokenUrl();
logger.info("WxOpen AuthorizerAccessToken获取第三方访问令牌网址 is {}", url);
if (StringUtils.isBlank(url)) {
url = WxOpenComponentService.API_AUTHORIZER_TOKEN_URL + "?component_access_token=" + componentAccessToken;
logger.info("WxOpen AuthorizerAccessToken获取第三方访问令牌网址 为 null ,开始拼接微信官方获取token接口 is {}", url);
} else {
logger.info("WxOpen AuthorizerAccessToken调用token管理中心url:{}", url);
}
int retryTimes = 0;
int maxRetryTimes = 10;
do {
try {
HttpPost httpPost = new HttpPost(url);
if (this.getRequestHttpProxy() != null) {
RequestConfig config = RequestConfig.custom().setConnectTimeout(180 * 1000).setProxy(
this.getRequestHttpProxy()).build();
httpPost.setConfig(config);
}
JSONObject jsonObject = new JSONObject();
//第三方appid
jsonObject.put("component_appid", this.getWechatOpenConfigStorage().getComponentAppId());
//被授权的appid
jsonObject.put("authorizer_appid", authorAppId);
//刷新Token,需要保存,否则需要重新授权
jsonObject.put("authorizer_refresh_token", refreshToken);
httpPost.setEntity(new StringEntity(JSONObject.toJSONString(jsonObject), "application/json", "utf-8"));
try (CloseableHttpResponse response = getRequestHttpClient().execute(httpPost)) {
String resultContent = new BasicResponseHandler().handleResponse(response);
WxError error = WxError.fromJson(resultContent);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
}
WxOpenAuthorizerAccessToken accessToken = WxOpenAuthorizerAccessToken.fromJson(resultContent);
logger.info("WxOpen AuthorizerAccessToken重新获取到微信官方token信息 is {}", accessToken);
this.getWechatOpenConfigStorage().updateAccessToken(accessToken.getAuthorizerAccessToken(),
accessToken.getExpiresIn(), this.getWechatOpenConfigStorage().getAuthorAppId(), redisTemplate, valOps, null);
// 直接返回token;
return accessToken.getAuthorizerAccessToken();
} finally {
httpPost.releaseConnection();
}
} catch (Exception e) {
if (retryTimes + 1 > maxRetryTimes) {
logger.info("WxOpen AuthorizerAccessToken token获取达到最大次数【{}】", maxRetryTimes);
// 最后一次重试失败后,直接抛出异常,不再等待
WxError error = WxError.builder().errorCode(42002).errorMsg(
"token获取达到最大次数【" + maxRetryTimes + "】,调用地址:" + url).build();
e.printStackTrace();
throw new WxErrorException(error, e);
}
// -1 系统繁忙, 1000ms后重试
try {
logger.info("WxOpen AuthorizerAccessToken token获取失败,1000 ms 后重试(第{}次)", retryTimes + 1);
Thread.sleep(1000);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
}
} while (retryTimes++ < maxRetryTimes);
} else {
logger.info("WxOpen AuthorizerAccessToken redis中剩余微信官方token is {},过期时间为{}", "wx_open_token_" + this.getWechatOpenConfigStorage().getAuthorAppId(), expire);
}
} finally {
lock.unlock();
}
return String.valueOf(redisTemplate.opsForValue().get("wx_open_token_" + this.getWechatOpenConfigStorage().getAuthorAppId()));
}
public WechatOpenConfigStorage getWechatOpenConfigStorage() {
return wechatOpenConfigStorage;
}
public String getComponentAccessToken(String key, String componentVerifyTicket) throws WxErrorException {
Lock lock = this.wechatOpenConfigStorage.getComponentTokenLock();
try {
lock.lock();
Long expire = redisTemplate.opsForValue().getOperations().getExpire("wx_open_component_token_" + key);
logger.info("是否开启强制刷新微信开放平台ComponentAccessToken功能 key:{} expire:{}", key, expire);
if (expire == -1) {
logger.info("微信开放平台ComponentAccessToken没有设置过期时间 {}", "wx_open_component_token_" + key);
} else if (expire == -2) {
JSONObject params = new JSONObject();
//第三方平台的appid、appsecret
params.put("component_appid", this.wechatOpenConfigStorage.getComponentAppId());
params.put("component_appsecret", this.wechatOpenConfigStorage.getComponentAppSecret());
if (StringUtils.isBlank(componentVerifyTicket)) {
throw new RuntimeException("微信开放平台ComponentAccessToken,第三方平台获取【验证票据】失败");
}
params.put("component_verify_ticket", componentVerifyTicket);
int retryTimes = 0;
int maxRetryTimes = 10;
do {
try {
JSONObject data = JSONObject.parseObject(HttpClientUtil.httpPost(WxOpenComponentService.API_COMPONENT_TOKEN_URL, JSON.toJSONString(params)));
if (data.containsKey("component_access_token")) {
String componentAccessToken = data.getString("component_access_token");
Integer componentExpiresIn = data.getInteger("expires_in");
//将component_access_token存入redis中,并设置2个小时的过期时间
//redisTemplate.opsForValue().set(WechatOpenConst.COMPONENT_ACCESS_TOKEN+key, componentAccessToken, 60 * 60 * 2);
//valOps.getOperations().opsForHash().put(WechatOpenConst.COMPONENT_ACCESS_TOKEN + key, WechatOpenConst.COMPONENT_ACCESS_TOKEN_KEY, componentAccessToken);
this.wechatOpenConfigStorage.updateComponentToken(componentAccessToken,
componentExpiresIn, null, redisTemplate, valOps, key);
return componentAccessToken;
}
} catch (Exception e) {
if (retryTimes + 1 > maxRetryTimes) {
logger.info("微信开放平台ComponentAccessToken获取达到最大次数【{}】", maxRetryTimes);
// 最后一次重试失败后,直接抛出异常,不再等待
WxError error = WxError.builder().errorCode(42002).errorMsg(
"微信开放平台ComponentAccessToken获取达到最大次数【" + maxRetryTimes + "】,调用地址:" + WxOpenComponentService.API_COMPONENT_TOKEN_URL).build();
throw new WxErrorException(error, e);
}
// -1 系统繁忙, 1000ms后重试
try {
logger.info("微信开放平台ComponentAccessToken获取失败,1000 ms 后重试(第{}次)", retryTimes + 1);
Thread.sleep(1000);
} catch (InterruptedException e1) {
throw new RuntimeException(e1);
}
}
} while (retryTimes++ < maxRetryTimes);
} else {
logger.info("微信开放平台redis中剩余微信官方ComponentAccessToken is{},过期时间 为{}", "wx_open_component_token_" + key, expire);
}
} finally {
lock.unlock();
}
return String.valueOf(redisTemplate.opsForValue().get("wx_open_component_token_" + key));
}
public LogHandler getLogHandler() {
return logHandler;
}
public void setLogHandler(LogHandler logHandler) {
this.logHandler = logHandler;
}
public NullHandler getNullHandler() {
return nullHandler;
}
public void setNullHandler(NullHandler nullHandler) {
this.nullHandler = nullHandler;
}
public LocationHandler getLocationHandler() {
return locationHandler;
}
public void setLocationHandler(LocationHandler locationHandler) {
this.locationHandler = locationHandler;
}
public MenuHandler getMenuHandler() {
return menuHandler;
}
public void setMenuHandler(MenuHandler menuHandler) {
this.menuHandler = menuHandler;
}
public MsgHandler getMsgHandler() {
return msgHandler;
}
public void setMsgHandler(MsgHandler msgHandler) {
this.msgHandler = msgHandler;
}
public UnsubscribeHandler getUnsubscribeHandler() {
return unsubscribeHandler;
}
public void setUnsubscribeHandler(UnsubscribeHandler unsubscribeHandler) {
this.unsubscribeHandler = unsubscribeHandler;
}
public SubscribeHandler getSubscribeHandler() {
return subscribeHandler;
}
public void setSubscribeHandler(SubscribeHandler subscribeHandler) {
this.subscribeHandler = subscribeHandler;
}
public void updateAuthAccount(String key, String authorizationCode) {
try {
String authorAppId = this.getWechatOpenConfigStorage().getAuthorAppId();
if (StringUtils.isEmpty(authorizationCode)) {
authorizationCode = (String) valOps.get("wxOpen:" + authorAppId);
}
String refreshToken = this.getWechatOpenConfigStorage().getAuthorizerRefreshToken(null);
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("snsId", key);
jsonObject1.put("authorizationCode", authorizationCode);
jsonObject1.put("refreshToken", refreshToken);
Imservice.getMessageApi().sendAuthMessage(JSONObject.toJSONString(jsonObject1));
} catch (Exception e) {
logger.error("getMessageApi().sendAuthMessage error:{}", e);
}
}
}
wechatopenstorage代码
package com.test.wechat.config;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import com.test.wechat.consts.WechatOpenConst;
import com.test.wechat.util.ServletUtil;
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.open.api.WxOpenConfigStorage;
import me.chanjar.weixin.open.bean.WxOpenAuthorizerAccessToken;
import me.chanjar.weixin.open.bean.WxOpenComponentAccessToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
/**
* 〈一句话功能简述〉<br>
* 〈〉
*
* @author jinxin
* @create 2019-04-17
* @since 1.0.0
*/
@Component
public class WechatOpenConfigStorage implements WxOpenConfigStorage {
private final static String ACCESS_TOKEN = "access_token";
private final static String ACCESS_TOKEN_EXPIRES_TIME = "access_token_expires_time";
private final static String AUTHORIZER_REFRESH_TOKEN = "authorizer_refresh_token";
private final static String COMPONENT_TOKEN = "component_access_token";
private final static String COMPONENT_TOKEN_EXPIRES_TIME = "component_access_token_expires_time";
@Autowired
private SnsProperties snsProperties;
@Autowired
private HttpProxyConfig httpProxyConfig;
@Autowired
private ValueOperations<String, Object> valOps;
@Autowired
private Lock accessTokenLock;
@Autowired
private Lock componentTokenLock;
@Autowired
RedisTemplate redisTemplate;
private SnsProperties.SnsConfiguration getSns() {
return snsProperties.getConfig().get(ServletUtil.getKey());
}
private String getKeyField() {
return "wxOpen:" + ServletUtil.getKey();
}
public Lock getComponentTokenLock() {
return componentTokenLock;
}
public void setComponentTokenLock(Lock componentTokenLock) {
this.componentTokenLock = componentTokenLock;
}
//作为第三方平台appid
@Override
public String getComponentAppId() {
return getSns().getWechatAppId();
}
@Override
public void setComponentAppId(String s) {
}
//第三方开放平台secret
@Override
public String getComponentAppSecret() {
return getSns().getWechatAppSecret();
}
@Override
public void setComponentAppSecret(String s) {
}
//第三方平台Token
@Override
public String getComponentToken() {
return getSns().getWechatToken();
}
@Override
public void setComponentToken(String s) {
}
//第三方消息加解密Key
@Override
public String getComponentAesKey() {
return getSns().getWechatAesKey();
}
@Override
public void setComponentAesKey(String s) {
}
@Override
public String getComponentVerifyTicket() {
return null;
}
@Override
public void setComponentVerifyTicket(String s) {
}
@Override
public String getComponentAccessToken() {
return valOps.getOperations().opsForHash().get(WechatOpenConst.COMPONENT_ACCESS_TOKEN+ServletUtil.getKey(),WechatOpenConst.COMPONENT_ACCESS_TOKEN_KEY)+"";
}
@Override
public boolean isComponentAccessTokenExpired() {
return false;
}
@Override
public void expireComponentAccessToken() {
}
@Override
public void updateComponentAccessTokent(WxOpenComponentAccessToken wxOpenComponentAccessToken) {
}
@Override
public String getHttpProxyHost() {
return httpProxyConfig.getHttpProxyHost();
}
@Override
public int getHttpProxyPort() {
return httpProxyConfig.getHttpProxyPort();
}
@Override
public String getHttpProxyUsername() {
return httpProxyConfig.getHttpProxyUsername();
}
@Override
public String getHttpProxyPassword() {
return httpProxyConfig.getHttpProxyPassword();
}
@Override
public ApacheHttpClientBuilder getApacheHttpClientBuilder() {
return null;
}
@Override
public WxMpConfigStorage getWxMpConfigStorage(String s) {
return null;
}
@Override
public WxMaConfig getWxMaConfig(String s) {
return null;
}
@Override
public void updateComponentAccessTokent(String s, int i) {
}
@Override
public boolean autoRefreshToken() {
return false;
}
@Override
public String getAuthorizerRefreshToken(String s) {
return (String) valOps.getOperations().opsForHash().get(getKeyField(), AUTHORIZER_REFRESH_TOKEN);
}
@Override
public void setAuthorizerRefreshToken(String s, String s1) {
valOps.getOperations().opsForHash().put(getKeyField(), AUTHORIZER_REFRESH_TOKEN, s1);
}
@Override
public String getAuthorizerAccessToken(String s) {
return null;
}
@Override
public boolean isAuthorizerAccessTokenExpired(String s) {
return false;
}
@Override
public void expireAuthorizerAccessToken(String s) {
}
@Override
public void updateAuthorizerAccessToken(String s, WxOpenAuthorizerAccessToken wxOpenAuthorizerAccessToken) {
}
@Override
public void updateAuthorizerAccessToken(String s, String s1, int expireTimes) {
valOps.getOperations().opsForHash().put(getKeyField(), ACCESS_TOKEN, s1);
valOps.getOperations().opsForHash().put(getKeyField(), ACCESS_TOKEN_EXPIRES_TIME, System.currentTimeMillis() + (expireTimes - 200) * 1000L);
}
@Override
public String getJsapiTicket(String s) {
return null;
}
@Override
public boolean isJsapiTicketExpired(String s) {
return false;
}
@Override
public void expireJsapiTicket(String s) {
}
@Override
public void updateJsapiTicket(String s, String s1, int i) {
}
@Override
public String getCardApiTicket(String s) {
return null;
}
@Override
public boolean isCardApiTicketExpired(String s) {
return false;
}
@Override
public void expireCardApiTicket(String s) {
}
@Override
public void updateCardApiTicket(String s, String s1, int i) {
}
public Lock getAccessTokenLock() {
return this.accessTokenLock;
}
//第三方授权appId
public String getAuthorAppId() {
return getSns().getDataformat();
}
public String getThirdAccessTokenUrl() {
return getSns().getThirdAccessTokenUrl();
}
public void updateAccessToken(String accessToken, int expiresInSeconds, String appId, RedisTemplate<String, Object> redisTemplate, ValueOperations<String, Object> valOps, String snsUuid) {
//为提供获取微信官方token接口单独存入redis
redisTemplate.opsForValue().set("wx_open_token_" + appId, accessToken, (expiresInSeconds - 3600), TimeUnit.SECONDS);
if ("wx:null".equals(getKeyField())) {
valOps.getOperations().opsForHash().put("wxOpen:" + snsUuid, ACCESS_TOKEN, accessToken);
valOps.getOperations().opsForHash().put("wxOpen:" + snsUuid, ACCESS_TOKEN_EXPIRES_TIME, System.currentTimeMillis() + (expiresInSeconds - 3600) * 1000L);
} else {
valOps.getOperations().opsForHash().put(getKeyField(), ACCESS_TOKEN, accessToken);
valOps.getOperations().opsForHash().put(getKeyField(), ACCESS_TOKEN_EXPIRES_TIME, System.currentTimeMillis() + (expiresInSeconds - 3600) * 1000L);
}
}
public void updateComponentToken(String accessToken, int expiresInSeconds, String appId, RedisTemplate<String, Object> redisTemplate, ValueOperations<String, Object> valOps, String snsUuid) {
//为提供获取微信官方token接口单独存入redis
redisTemplate.opsForValue().set("wx_open_component_token_" + snsUuid, accessToken, (expiresInSeconds - 3600), TimeUnit.SECONDS);
if (ServletUtil.getKey()==null) {
valOps.getOperations().opsForHash().put(WechatOpenConst.COMPONENT_ACCESS_TOKEN + snsUuid, COMPONENT_TOKEN, accessToken);
valOps.getOperations().opsForHash().put(WechatOpenConst.COMPONENT_ACCESS_TOKEN + snsUuid, COMPONENT_TOKEN_EXPIRES_TIME, System.currentTimeMillis() + (expiresInSeconds - 3600) * 1000L);
} else {
valOps.getOperations().opsForHash().put(WechatOpenConst.COMPONENT_ACCESS_TOKEN+ServletUtil.getKey(), COMPONENT_TOKEN, accessToken);
valOps.getOperations().opsForHash().put(WechatOpenConst.COMPONENT_ACCESS_TOKEN+ServletUtil.getKey(), COMPONENT_TOKEN_EXPIRES_TIME, System.currentTimeMillis() + (expiresInSeconds - 3600) * 1000L);
}
}
}
介绍一个msghandler,这部分参考weixin-java-mp模块。
package com.test.wechat.handler;
import com.test.sdk.exception.ImccErrorException;
import com.test.sdk.service.impl.ImccServiceImpl;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Map;
/**
* @author Binary Wang
*/
@Component
public class MenuHandler extends AbstractHandler {
@Autowired
private ImccServiceImpl imccservice;
@Override
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
WxSessionManager sessionManager) {
// WechatService weixinService = (WechatService) wxMpService;
String key = wxMessage.getEventKey();
String event = wxMessage.getEvent();
switch (event.toLowerCase()) {
case WxConsts.MenuButtonType.CLICK:
//case WxConsts.BUTTON_VIEW :
try {
imccservice.getMessageApi().sendClickMsg(wxMessage.getToUser(), wxMessage.getFromUser(),
wxMessage.getCreateTime(), key);
} catch (ImccErrorException e) {
return WxMpXmlOutMessage.TEXT().content("服务器未响应,请稍后再试").fromUser(wxMessage.getToUser()).toUser(
wxMessage.getFromUser()).build();
}
return null;
default:
return WxMpXmlOutMessage.TEXT().content("此菜单未定义").fromUser(wxMessage.getToUser()).toUser(
wxMessage.getFromUser()).build();
}
// WxMenuKey menuKey = null;
// try {
// menuKey = JSON.parseObject(key, WxMenuKey.class);
// } catch (Exception e) {
// return WxMpXmlOutMessage.TEXT().content(key)
// .fromUser(wxMessage.getToUser())
// .toUser(wxMessage.getFromUser()).build();
// }
//
// WeChatAbstractBuilder builder = null;
// switch (menuKey.getType()) {
// case WxConsts.XML_MSG_TEXT:
// builder = new WeChatTextBuilder();
// break;
// case WxConsts.XML_MSG_IMAGE:
// builder = new WeChatImageBuilder();
// break;
// case WxConsts.XML_MSG_VOICE:
// break;
// case WxConsts.XML_MSG_VIDEO:
// break;
// case WxConsts.XML_MSG_NEWS:
// break;
// default:
// break;
// }
//
if (builder != null) {
try {
return builder.build(menuKey.getContent(), wxMessage, weixinService);
} catch (Exception e) {
this.logger.error(e.getMessage(), e);
}
}
//
// return null;
}
}
注,其中redis实现使用自己项目中的即可。
ps:下节继续看消息如何发送。