WeixinComponentProxy.java
package com.foxinmy.weixin4j.mp;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.cache.FileCacheStorager;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.mp.api.ComponentApi;
import com.foxinmy.weixin4j.mp.model.WeixinMpAccount;
import com.foxinmy.weixin4j.mp.type.URLConsts;
import com.foxinmy.weixin4j.token.TicketManager;
import com.foxinmy.weixin4j.util.Consts;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
/**
* 微信第三方应用接口实现
*
* @className WeixinComponentProxy
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月5日
* @since JDK 1.6
* @see com.foxinmy.weixin4j.mp.api.ComponentApi
* @see <a href=
* "https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419318292&token=&lang=zh_CN">
* 公众号第三方应用</a>
*/
public class WeixinComponentProxy {
/**
* 每个组件授权不一样 componentId - componentApi
*/
private Map<String, ComponentApi> componentMap;
/**
* 微信账号信息
*/
private final WeixinMpAccount weixinMpAccount;
/**
* 微信第三方组件接口实现(使用weixin4j.properties配置的account#components账号信息,
* 使用FileCacheStorager文件方式缓存TOKEN)
*/
public WeixinComponentProxy() {
this(new FileCacheStorager<Token>());
}
/**
* 微信第三方组件接口实现(使用weixin4j.properties配置的account#components账号信息)
*
* @param cacheStorager
* token管理
*/
public WeixinComponentProxy(CacheStorager<Token> cacheStorager) {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), WeixinMpAccount.class), cacheStorager);
}
/**
* 微信第三方组件接口实现
*
* @param weixinMpAccount
* 账号信息
* @param cacheStorager
* token管理
*/
public WeixinComponentProxy(WeixinMpAccount weixinMpAccount, CacheStorager<Token> cacheStorager) {
if (weixinMpAccount == null) {
throw new IllegalArgumentException("weixinMpAccount must not be empty");
}
if (cacheStorager == null) {
throw new IllegalArgumentException("cacheStorager must not be empty");
}
this.weixinMpAccount = weixinMpAccount;
this.componentMap = new HashMap<String, ComponentApi>(weixinMpAccount.getComponents().size());
for (WeixinAccount component : weixinMpAccount.getComponents()) {
this.componentMap.put(component.getId(),
new ComponentApi(new TicketManager(component.getId(), component.getSecret(), cacheStorager)));
}
this.componentMap.put(null, componentMap.get(weixinMpAccount.getComponents().get(0).getId()));
}
/**
* 获取微信账号信息
*
* @return
*/
public WeixinMpAccount getWeixinMpAccount() {
return this.weixinMpAccount;
}
/**
* 获取组接口对象(只关注第一个组件
*
* @see com.foxinmy.weixin4j.mp.api.ComponentApi
* @return API实例
*/
public ComponentApi component() {
return this.componentMap.get(null);
}
/**
* 获取套件接口对象(多个组件
*
* @see com.foxinmy.weixin4j.mp.api.ComponentApi
* @param componentId
* 组件ID
* @return API实例
*/
public ComponentApi component(String componentId) {
return this.componentMap.get(componentId);
}
/**
* 获取组件的预授权码 <font color="red">需先缓存ticket</font>
*
* @param componentId
* 组件ID
* @return 预授权码
* @see #cacheComponentTicket(String, String)
* @see com.foxinmy.weixin4j.mp.api.ComponentApi
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#getTicketManager()
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#getPreCodeManager()
* @throws WeixinException
*/
public String getPreComponentTicket(String componentId) throws WeixinException {
ComponentApi component = component(componentId);
Token token = component.getTicketManager().getTicket();
if (token == null || StringUtil.isBlank(token.getAccessToken())) {
throw new WeixinException("maybe oauth first?");
}
return component.getPreCodeManager().getAccessToken();
}
/**
* 缓存组件ticket
*
* @param componentId
* 组件ID
* @param componentTicket
* 组件ticket内容
* @throws WeixinException
*/
public void cacheComponentTicket(String componentId, String componentTicket) throws WeixinException {
component(componentId).getTicketManager().cachingTicket(componentTicket);
}
/**
* 应用组件授权 <font color="red">需先缓存ticket</font>
* <li>redirectUri默认填写weixin4j.properties#component.oauth.redirect.uri
* <li>state默认填写state
*
* @param componentId
* 组件ID
* @see {@link #getComponentAuthorizationURL(String, String,String)}
* @return 请求授权的URL
* @throws WeixinException
*/
public String getComponentAuthorizationURL(String componentId) throws WeixinException {
String redirectUri = Weixin4jConfigUtil.getValue("component.oauth.redirect.uri");
return getComponentAuthorizationURL(componentId, redirectUri, "state");
}
/**
* 应用组件授权 <font color="red">需先缓存ticket,在授权完成之后需要调用ComponentApi#
* exchangeAuthorizerToken方法 ,否则无法缓存token相关导致后续的组件接口调用失败</font>
*
* @param componentId
* 组件ID
* @param redirectUri
* 授权后重定向url
* @param state
* 回调后原样返回
* @see #cacheComponentTicket(String, String)
* @see com.foxinmy.weixin4j.mp.api.ComponentApi
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#getTicketManager()
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#getPreCodeManager()
* @see com.foxinmy.weixin4j.mp.api.ComponentApi#exchangeAuthorizerToken(String)
* @see <a href=
* "https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1453779503&token=&lang=zh_CN">
* 应用组件授权</a>
* @return 请求授权的URL
* @throws WeixinException
*/
public String getComponentAuthorizationURL(String componentId, String redirectUri, String state)
throws WeixinException {
try {
return String.format(URLConsts.COMPONENT_OAUTH_URL, componentId, getPreComponentTicket(componentId),
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state);
} catch (UnsupportedEncodingException e) {
;
}
return "";
}
/**
* 创建WeixinProxy对象
*
* @param componentId
* 组件ID
* @param authAppId
* 已授权的appid
* @see com.foxinmy.weixin4j.mp.WeixinProxy
* @return
*/
public WeixinProxy getWeixinProxy(String componentId, String authAppId) {
return new WeixinProxy(component(componentId).getRefreshTokenManager(authAppId),
component(componentId).getTokenManager());
}
public final static String VERSION = Consts.VERSION;
}