weixin4j-qy:新增第三方应用多个API接口
This commit is contained in:
parent
dd1fcaa598
commit
66bc364b33
@ -0,0 +1,36 @@
|
|||||||
|
package com.foxinmy.weixin4j.token;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cache存储
|
||||||
|
*
|
||||||
|
* @className CacheStorager
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月22日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public interface CacheStorager<T> {
|
||||||
|
/**
|
||||||
|
* 查找缓存中的对象
|
||||||
|
*
|
||||||
|
* @param cacheKey
|
||||||
|
* 缓存名称
|
||||||
|
* @return
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
T lookup(String cacheKey) throws WeixinException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存新的对象
|
||||||
|
*
|
||||||
|
* @param cacheKey
|
||||||
|
* 缓存名称
|
||||||
|
*
|
||||||
|
* @param t
|
||||||
|
* 将要缓存的对象
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
void caching(String cacheKey, T t) throws WeixinException;
|
||||||
|
}
|
||||||
@ -20,27 +20,29 @@ import com.foxinmy.weixin4j.xml.XmlStream;
|
|||||||
*/
|
*/
|
||||||
public class FileTokenStorager implements TokenStorager {
|
public class FileTokenStorager implements TokenStorager {
|
||||||
|
|
||||||
private final String tokenPath;
|
private final String cachePath;
|
||||||
|
|
||||||
public FileTokenStorager() {
|
public FileTokenStorager() {
|
||||||
this(ConfigUtil.getValue("token_path"));
|
this(ConfigUtil.getValue("token_path"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public FileTokenStorager(String tokenPath) {
|
public FileTokenStorager(String cachePath) {
|
||||||
this.tokenPath = tokenPath;
|
this.cachePath = cachePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Token lookupToken(String cacheKey) throws WeixinException {
|
public Token lookup(String cacheKey) throws WeixinException {
|
||||||
File token_file = new File(String.format("%s/%s.xml", tokenPath,
|
File token_file = new File(String.format("%s/%s.xml", cachePath,
|
||||||
cacheKey));
|
cacheKey));
|
||||||
try {
|
try {
|
||||||
if (token_file.exists()) {
|
if (token_file.exists()) {
|
||||||
Token token = XmlStream.fromXML(
|
Token token = XmlStream.fromXML(
|
||||||
new FileInputStream(token_file), Token.class);
|
new FileInputStream(token_file), Token.class);
|
||||||
long expire_time = token.getTime()
|
if (token.getTime() < 0) {
|
||||||
+ (token.getExpiresIn() * 1000) - 2;
|
return token;
|
||||||
if (expire_time > System.currentTimeMillis()) {
|
}
|
||||||
|
if ((token.getTime() + (token.getExpiresIn() * 1000l) - 2) > System
|
||||||
|
.currentTimeMillis()) {
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,13 +53,12 @@ public class FileTokenStorager implements TokenStorager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cachingToken(String cacheKey, Token token)
|
public void caching(String cacheKey, Token token) throws WeixinException {
|
||||||
throws WeixinException {
|
|
||||||
try {
|
try {
|
||||||
XmlStream.toXML(
|
XmlStream.toXML(
|
||||||
token,
|
token,
|
||||||
new FileOutputStream(new File(String.format("%s/%s.xml",
|
new FileOutputStream(new File(String.format("%s/%s.xml",
|
||||||
tokenPath, cacheKey))));
|
cachePath, cacheKey))));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new WeixinException(e.getMessage());
|
throw new WeixinException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,10 +44,10 @@ public final class TokenHolder {
|
|||||||
*/
|
*/
|
||||||
public Token getToken() throws WeixinException {
|
public Token getToken() throws WeixinException {
|
||||||
String cacheKey = tokenCreator.getCacheKey();
|
String cacheKey = tokenCreator.getCacheKey();
|
||||||
Token token = tokenStorager.lookupToken(cacheKey);
|
Token token = tokenStorager.lookup(cacheKey);
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
token = tokenCreator.createToken();
|
token = tokenCreator.createToken();
|
||||||
tokenStorager.cachingToken(cacheKey, token);
|
tokenStorager.caching(cacheKey, token);
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
package com.foxinmy.weixin4j.token;
|
package com.foxinmy.weixin4j.token;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
|
||||||
import com.foxinmy.weixin4j.model.Token;
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,27 +13,5 @@ import com.foxinmy.weixin4j.model.Token;
|
|||||||
* @see com.foxinmy.weixin4j.token.FileTokenStorager
|
* @see com.foxinmy.weixin4j.token.FileTokenStorager
|
||||||
* @see com.foxinmy.weixin4j.token.RedisTokenStorager
|
* @see com.foxinmy.weixin4j.token.RedisTokenStorager
|
||||||
*/
|
*/
|
||||||
public interface TokenStorager {
|
public interface TokenStorager extends CacheStorager<Token> {
|
||||||
/**
|
|
||||||
* 查找缓存的token
|
|
||||||
*
|
|
||||||
* @param cacheKey
|
|
||||||
* 缓存的名称
|
|
||||||
* @return 查找结果
|
|
||||||
* @throws WeixinException
|
|
||||||
*/
|
|
||||||
public Token lookupToken(String cacheKey) throws WeixinException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存新的token
|
|
||||||
*
|
|
||||||
* @param cacheKey
|
|
||||||
* 缓存的名称
|
|
||||||
*
|
|
||||||
* @param token
|
|
||||||
* 新产生的token
|
|
||||||
* @throws WeixinException
|
|
||||||
*/
|
|
||||||
public void cachingToken(String cacheKey, Token token)
|
|
||||||
throws WeixinException;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,8 @@ weixin4j-qy
|
|||||||
* BatchApi `批量操作API`
|
* BatchApi `批量操作API`
|
||||||
|
|
||||||
* OauthApi `oauth授权登陆API`
|
* OauthApi `oauth授权登陆API`
|
||||||
|
|
||||||
|
* SuiteApi `第三方应用API`
|
||||||
|
|
||||||
如何使用
|
如何使用
|
||||||
--------
|
--------
|
||||||
|
|||||||
@ -65,7 +65,7 @@ public class AgentApi extends QyApi {
|
|||||||
* 设置企业应用的选项设置信息,如:地理位置上报等
|
* 设置企业应用的选项设置信息,如:地理位置上报等
|
||||||
*
|
*
|
||||||
* @param agentSet
|
* @param agentSet
|
||||||
* 设置参数
|
* 设置信息
|
||||||
* @see com.foxinmy.weixin4j.qy.model.AgentSetter
|
* @see com.foxinmy.weixin4j.qy.model.AgentSetter
|
||||||
* @see <a
|
* @see <a
|
||||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E4%BC%81%E4%B8%9A%E5%8F%B7%E5%BA%94%E7%94%A8">设置企业号信息</a>
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E4%BC%81%E4%B8%9A%E5%8F%B7%E5%BA%94%E7%94%A8">设置企业号信息</a>
|
||||||
@ -81,7 +81,7 @@ public class AgentApi extends QyApi {
|
|||||||
return response.getAsJsonResult();
|
return response.getAsJsonResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ValueFilter typeFilter;
|
public static ValueFilter typeFilter;
|
||||||
static {
|
static {
|
||||||
typeFilter = new ValueFilter() {
|
typeFilter = new ValueFilter() {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -4,11 +4,9 @@ import java.io.UnsupportedEncodingException;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.parser.deserializer.ExtraProcessor;
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||||
import com.foxinmy.weixin4j.model.Consts;
|
import com.foxinmy.weixin4j.model.Consts;
|
||||||
import com.foxinmy.weixin4j.qy.model.Corpinfo;
|
|
||||||
import com.foxinmy.weixin4j.qy.model.OUserInfo;
|
import com.foxinmy.weixin4j.qy.model.OUserInfo;
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||||
|
|
||||||
@ -83,26 +81,7 @@ public class OauthApi extends QyApi {
|
|||||||
WeixinResponse response = weixinClient.post(
|
WeixinResponse response = weixinClient.post(
|
||||||
String.format(oauth_logininfo_uri, providerToken),
|
String.format(oauth_logininfo_uri, providerToken),
|
||||||
String.format("{\"auth_code\":\"%s\"}", authCode));
|
String.format("{\"auth_code\":\"%s\"}", authCode));
|
||||||
return JSON.parseObject(response.getAsString(), OUserInfo.class,
|
return JSON.parseObject(response.getAsString(), OUserInfo.class);
|
||||||
new ExtraProcessor() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void processExtra(Object object, String key,
|
|
||||||
Object value) {
|
|
||||||
if (object instanceof Corpinfo) {
|
|
||||||
Corpinfo corpinfo = (Corpinfo) object;
|
|
||||||
if (key.equalsIgnoreCase("corp_name")) {
|
|
||||||
corpinfo.setName(value.toString());
|
|
||||||
} else if (key
|
|
||||||
.equalsIgnoreCase("corp_round_logo_url")) {
|
|
||||||
corpinfo.setRoundLogoUrl(value.toString());
|
|
||||||
} else if (key
|
|
||||||
.equalsIgnoreCase("corp_square_logo_url")) {
|
|
||||||
corpinfo.setSquareLogoUrl(value.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -5,8 +5,6 @@ import java.util.ResourceBundle;
|
|||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.foxinmy.weixin4j.api.BaseApi;
|
import com.foxinmy.weixin4j.api.BaseApi;
|
||||||
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
|
||||||
import com.foxinmy.weixin4j.qy.suite.FileTicketProcessor;
|
|
||||||
import com.foxinmy.weixin4j.qy.suite.SuiteTicketProcessor;
|
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
import com.foxinmy.weixin4j.util.ConfigUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,17 +24,12 @@ public class QyApi extends BaseApi {
|
|||||||
* 默认使用weixin4j.properties文件中的企业号信息
|
* 默认使用weixin4j.properties文件中的企业号信息
|
||||||
*/
|
*/
|
||||||
public final static WeixinQyAccount DEFAULT_WEIXIN_ACCOUNT;
|
public final static WeixinQyAccount DEFAULT_WEIXIN_ACCOUNT;
|
||||||
/**
|
|
||||||
* 默认使用File的方法读取套件ticket
|
|
||||||
*/
|
|
||||||
public final static SuiteTicketProcessor DEFAULT_TICKET_PROCESSOR;
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
WEIXIN_BUNDLE = ResourceBundle
|
WEIXIN_BUNDLE = ResourceBundle
|
||||||
.getBundle("com/foxinmy/weixin4j/qy/api/weixin");
|
.getBundle("com/foxinmy/weixin4j/qy/api/weixin");
|
||||||
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
|
DEFAULT_WEIXIN_ACCOUNT = JSON.parseObject(
|
||||||
ConfigUtil.getValue("account"), WeixinQyAccount.class);
|
ConfigUtil.getValue("account"), WeixinQyAccount.class);
|
||||||
DEFAULT_TICKET_PROCESSOR = new FileTicketProcessor();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -1,12 +1,23 @@
|
|||||||
package com.foxinmy.weixin4j.qy.api;
|
package com.foxinmy.weixin4j.qy.api;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.alibaba.fastjson.TypeReference;
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
import com.foxinmy.weixin4j.http.weixin.JsonResult;
|
||||||
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||||
import com.foxinmy.weixin4j.qy.suite.SuiteTicketProcessor;
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.AgentInfo;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.AgentSetter;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.OUserInfo;
|
||||||
|
import com.foxinmy.weixin4j.qy.model.User;
|
||||||
|
import com.foxinmy.weixin4j.qy.suite.SuitePerCodeHolder;
|
||||||
|
import com.foxinmy.weixin4j.qy.suite.SuiteTicketHolder;
|
||||||
import com.foxinmy.weixin4j.qy.suite.WeixinSuitePreCodeCreator;
|
import com.foxinmy.weixin4j.qy.suite.WeixinSuitePreCodeCreator;
|
||||||
import com.foxinmy.weixin4j.qy.suite.WeixinSuiteTokenCreator;
|
import com.foxinmy.weixin4j.qy.suite.WeixinSuiteTokenCreator;
|
||||||
|
import com.foxinmy.weixin4j.qy.suite.WeixinTokenSuiteCreator;
|
||||||
|
import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
import com.foxinmy.weixin4j.token.TokenHolder;
|
||||||
import com.foxinmy.weixin4j.token.TokenStorager;
|
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||||
|
|
||||||
@ -21,12 +32,30 @@ import com.foxinmy.weixin4j.token.TokenStorager;
|
|||||||
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%88%E6%9D%83">第三方应用授权</a>
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%88%E6%9D%83">第三方应用授权</a>
|
||||||
*/
|
*/
|
||||||
public class SuiteApi extends QyApi {
|
public class SuiteApi extends QyApi {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 应用套件token
|
* 应用套件token
|
||||||
*/
|
*/
|
||||||
private final TokenHolder suiteTokenHolder;
|
private final TokenHolder suiteTokenHolder;
|
||||||
private final TokenHolder suiteTicketHolder;
|
/**
|
||||||
|
* 应用套件ticket
|
||||||
|
*/
|
||||||
|
private final SuiteTicketHolder suiteTicketHolder;
|
||||||
|
/**
|
||||||
|
* 应用套件永久授权码
|
||||||
|
*/
|
||||||
|
private final SuitePerCodeHolder suitePerCodeHolder;
|
||||||
|
/**
|
||||||
|
* 应用套件pre_code
|
||||||
|
*/
|
||||||
|
private final TokenHolder suitePreCodeHolder;
|
||||||
|
/**
|
||||||
|
* 应用套件的存储策略
|
||||||
|
*/
|
||||||
|
private final TokenStorager tokenStorager;
|
||||||
|
/**
|
||||||
|
* 应用套件ID
|
||||||
|
*/
|
||||||
|
private final String suiteId;
|
||||||
|
|
||||||
public SuiteApi() throws WeixinException {
|
public SuiteApi() throws WeixinException {
|
||||||
this(DEFAULT_WEIXIN_ACCOUNT.getSuiteId(), DEFAULT_WEIXIN_ACCOUNT
|
this(DEFAULT_WEIXIN_ACCOUNT.getSuiteId(), DEFAULT_WEIXIN_ACCOUNT
|
||||||
@ -34,8 +63,7 @@ public class SuiteApi extends QyApi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SuiteApi(String suiteId, String suiteSecret) throws WeixinException {
|
public SuiteApi(String suiteId, String suiteSecret) throws WeixinException {
|
||||||
this(suiteId, suiteSecret, DEFAULT_TICKET_PROCESSOR,
|
this(suiteId, suiteSecret, DEFAULT_TOKEN_STORAGER);
|
||||||
DEFAULT_TOKEN_STORAGER);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,19 +72,23 @@ public class SuiteApi extends QyApi {
|
|||||||
* 应用ID
|
* 应用ID
|
||||||
* @param suiteSecret
|
* @param suiteSecret
|
||||||
* 应用secret
|
* 应用secret
|
||||||
* @param ticketReader
|
* @param ticketStorager
|
||||||
* 应用ticket读取器
|
* 应用ticket存储器(用于读取)
|
||||||
* @param tokenStorager
|
* @param tokenStorager
|
||||||
* 应用token存储器
|
* 应用token存储器
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
*/
|
*/
|
||||||
public SuiteApi(String suiteId, String suiteSecret,
|
public SuiteApi(String suiteId, String suiteSecret,
|
||||||
SuiteTicketProcessor ticketReader, TokenStorager tokenStorager)
|
TokenStorager tokenStorager) throws WeixinException {
|
||||||
throws WeixinException {
|
this.suiteTicketHolder = new SuiteTicketHolder(tokenStorager);
|
||||||
this.suiteTokenHolder = new TokenHolder(new WeixinSuiteTokenCreator(
|
this.suiteTokenHolder = new TokenHolder(new WeixinSuiteTokenCreator(
|
||||||
suiteId, suiteSecret, ticketReader), tokenStorager);
|
suiteId, suiteSecret, suiteTicketHolder), tokenStorager);
|
||||||
this.suiteTicketHolder = new TokenHolder(new WeixinSuitePreCodeCreator(
|
this.suitePreCodeHolder = new TokenHolder(
|
||||||
suiteTokenHolder, suiteId), tokenStorager);
|
new WeixinSuitePreCodeCreator(suiteTokenHolder, suiteId),
|
||||||
|
tokenStorager);
|
||||||
|
this.suitePerCodeHolder = new SuitePerCodeHolder(tokenStorager);
|
||||||
|
this.tokenStorager = tokenStorager;
|
||||||
|
this.suiteId = suiteId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -73,10 +105,40 @@ public class SuiteApi extends QyApi {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public TokenHolder getTicketHolder() {
|
public SuiteTicketHolder getTicketHolder() {
|
||||||
return this.suiteTicketHolder;
|
return this.suiteTicketHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用套件永久授权码
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public SuitePerCodeHolder getPerCodeHolder() {
|
||||||
|
return this.suitePerCodeHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用套件pre_code
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public TokenHolder getPreCodeHolder() {
|
||||||
|
return this.suitePreCodeHolder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业号access_token(永久授权码)
|
||||||
|
*
|
||||||
|
* @param authCorpid
|
||||||
|
* 授权方corpid
|
||||||
|
* @return 企业号token
|
||||||
|
*/
|
||||||
|
public TokenHolder crateTokenHolder(String authCorpid) {
|
||||||
|
return new TokenHolder(new WeixinTokenSuiteCreator(suiteId, authCorpid,
|
||||||
|
suitePerCodeHolder), tokenStorager);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置套件授权配置:如果需要对某次授权进行配置,则调用本接口,目前仅可以设置哪些应用可以授权,不调用则默认允许所有应用进行授权。
|
* 设置套件授权配置:如果需要对某次授权进行配置,则调用本接口,目前仅可以设置哪些应用可以授权,不调用则默认允许所有应用进行授权。
|
||||||
*
|
*
|
||||||
@ -84,18 +146,144 @@ public class SuiteApi extends QyApi {
|
|||||||
* 允许进行授权的应用id,如1、2、3
|
* 允许进行授权的应用id,如1、2、3
|
||||||
* @return 处理结果
|
* @return 处理结果
|
||||||
* @throws WeixinException
|
* @throws WeixinException
|
||||||
* <a href=
|
* @see <a href=
|
||||||
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.AE.BE.E7.BD.AE.E6.8E.88.E6.9D.83.E9.85.8D.E7.BD.AE"
|
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.AE.BE.E7.BD.AE.E6.8E.88.E6.9D.83.E9.85.8D.E7.BD.AE"
|
||||||
* >设置套件授权配置</a>
|
* >设置套件授权配置</a>
|
||||||
*/
|
*/
|
||||||
public JsonResult setSuiteSession(int... appids) throws WeixinException {
|
public JsonResult setSuiteSession(int... appids) throws WeixinException {
|
||||||
String suite_set_session_uri = getRequestUri("suite_set_session_uri");
|
String suite_set_session_uri = getRequestUri("suite_set_session_uri");
|
||||||
JSONObject para = new JSONObject();
|
JSONObject para = new JSONObject();
|
||||||
para.put("pre_auth_code", suiteTicketHolder.getAccessToken());
|
para.put("pre_auth_code", suiteTicketHolder.lookup(suiteId));
|
||||||
para.put("session_info", appids);
|
para.put("session_info", appids);
|
||||||
WeixinResponse response = weixinClient
|
WeixinResponse response = weixinClient
|
||||||
.post(String.format(suite_set_session_uri,
|
.post(String.format(suite_set_session_uri,
|
||||||
suiteTokenHolder.getAccessToken()), para.toJSONString());
|
suiteTokenHolder.getAccessToken()), para.toJSONString());
|
||||||
return response.getAsJsonResult();
|
return response.getAsJsonResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业号的永久授权码
|
||||||
|
*
|
||||||
|
* @param authCode
|
||||||
|
* 临时授权码会在授权成功时附加在redirect_uri中跳转回应用提供商网站。
|
||||||
|
* @return 授权得到的信息
|
||||||
|
* @throws WeixinException
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.OUserInfo
|
||||||
|
* @see <a href=
|
||||||
|
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E4.BC.81.E4.B8.9A.E5.8F.B7.E7.9A.84.E6.B0.B8.E4.B9.85.E6.8E.88.E6.9D.83.E7.A0.81"
|
||||||
|
* >获取企业号的永久授权码</a>
|
||||||
|
*/
|
||||||
|
public OUserInfo exchangePermanentCode(String authCode)
|
||||||
|
throws WeixinException {
|
||||||
|
String suite_get_permanent_uri = getRequestUri("suite_get_permanent_uri");
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("suite_id", suiteId);
|
||||||
|
obj.put("auth_code", authCode);
|
||||||
|
WeixinResponse response = weixinClient.post(
|
||||||
|
String.format(suite_get_permanent_uri,
|
||||||
|
suiteTokenHolder.getAccessToken()), obj.toJSONString());
|
||||||
|
obj = response.getAsJson();
|
||||||
|
obj.put("corp_info", obj.remove("auth_corp_info"));
|
||||||
|
obj.put("user_info", obj.remove("auth_user_info"));
|
||||||
|
OUserInfo oInfo = JSON.toJavaObject(obj, OUserInfo.class);
|
||||||
|
// 缓存微信企业号access_token
|
||||||
|
TokenCreator tokenCreator = new WeixinTokenCreator(oInfo.getCorpinfo()
|
||||||
|
.getCorpid(), null);
|
||||||
|
Token token = new Token(obj.getString("access_token"));
|
||||||
|
token.setExpiresIn(obj.getIntValue("expires_in"));
|
||||||
|
token.setTime(System.currentTimeMillis());
|
||||||
|
tokenStorager.caching(tokenCreator.getCacheKey(), token);
|
||||||
|
// 缓存微信企业号永久授权码
|
||||||
|
suitePerCodeHolder.caching(suiteId, obj.getString("permanent_code"));
|
||||||
|
return oInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业号的授权信息
|
||||||
|
*
|
||||||
|
* @param authCorpid
|
||||||
|
* 授权方corpid
|
||||||
|
* @return 授权方信息
|
||||||
|
* @throws WeixinException
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.OUserInfo
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E4.BC.81.E4.B8.9A.E5.8F.B7.E7.9A.84.E6.8E.88.E6.9D.83.E4.BF.A1.E6.81.AF">获取企业号的授权信息</a>
|
||||||
|
*/
|
||||||
|
public OUserInfo getOAuthInfo(String authCorpid) throws WeixinException {
|
||||||
|
String suite_get_authinfo_uri = getRequestUri("suite_get_authinfo_uri");
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("suite_id", suiteId);
|
||||||
|
obj.put("auth_corpid", authCorpid);
|
||||||
|
obj.put("permanent_code", suitePerCodeHolder.lookup(suiteId));
|
||||||
|
WeixinResponse response = weixinClient.post(
|
||||||
|
String.format(suite_get_authinfo_uri,
|
||||||
|
suiteTokenHolder.getAccessToken()), obj.toJSONString());
|
||||||
|
return response.getAsObject(new TypeReference<OUserInfo>() {
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取企业号应用
|
||||||
|
*
|
||||||
|
* @param authCorpid
|
||||||
|
* 授权方corpid
|
||||||
|
* @param agentid
|
||||||
|
* 授权方应用id
|
||||||
|
* @return 应用信息
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.AgentInfo
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E4.BC.81.E4.B8.9A.E5.8F.B7.E5.BA.94.E7.94.A8">获取企业号应用</a>
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public AgentInfo getAgent(String authCorpid, int agentid)
|
||||||
|
throws WeixinException {
|
||||||
|
String suite_get_agent_uri = getRequestUri("suite_get_agent_uri");
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("suite_id", suiteId);
|
||||||
|
obj.put("auth_corpid", authCorpid);
|
||||||
|
obj.put("permanent_code", suitePerCodeHolder.lookup(suiteId));
|
||||||
|
obj.put("agentid", agentid);
|
||||||
|
WeixinResponse response = weixinClient.post(String.format(
|
||||||
|
suite_get_agent_uri, suiteTokenHolder.getAccessToken(),
|
||||||
|
obj.toJSONString()));
|
||||||
|
JSONObject jsonObj = response.getAsJson();
|
||||||
|
AgentInfo agent = JSON.toJavaObject(jsonObj, AgentInfo.class);
|
||||||
|
agent.setAllowUsers(JSON.parseArray(
|
||||||
|
jsonObj.getJSONObject("allow_userinfos").getString("user"),
|
||||||
|
User.class));
|
||||||
|
agent.setAllowPartys(JSON.parseArray(
|
||||||
|
jsonObj.getJSONObject("allow_partys").getString("partyid"),
|
||||||
|
Integer.class));
|
||||||
|
agent.setAllowTags(JSON.parseArray(jsonObj.getJSONObject("allow_tags")
|
||||||
|
.getString("tagid"), Integer.class));
|
||||||
|
return agent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置企业应用的选项设置信息,如:地理位置上报等
|
||||||
|
*
|
||||||
|
* @param authCorpid
|
||||||
|
* 授权方corpid
|
||||||
|
* @param agentSet
|
||||||
|
* 设置信息
|
||||||
|
* @see com.foxinmy.weixin4j.qy.model.AgentSetter
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%AE%BE%E7%BD%AE%E4%BC%81%E4%B8%9A%E5%8F%B7%E5%BA%94%E7%94%A8">设置企业号信息</a>
|
||||||
|
* @return 处理结果
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public JsonResult setAgent(String authCorpid, AgentSetter agentSet)
|
||||||
|
throws WeixinException {
|
||||||
|
String suite_set_agent_uri = getRequestUri("suite_set_agent_uri");
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("suite_id", suiteId);
|
||||||
|
obj.put("auth_corpid", authCorpid);
|
||||||
|
obj.put("permanent_code", suitePerCodeHolder.lookup(suiteId));
|
||||||
|
obj.put("agent", agentSet);
|
||||||
|
WeixinResponse response = weixinClient.post(
|
||||||
|
String.format(suite_set_agent_uri,
|
||||||
|
suiteTokenHolder.getAccessToken()),
|
||||||
|
JSON.toJSONString(obj, AgentApi.typeFilter));
|
||||||
|
return response.getAsJsonResult();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,4 +89,10 @@ suite_oauth_uri=https://qy.weixin.qq.com/cgi-bin/loginpage?suite_id=%s&pre_auth_
|
|||||||
# \u5e94\u7528\u5957\u4ef6\u8bbe\u7f6e\u6388\u6743\u914d\u7f6e
|
# \u5e94\u7528\u5957\u4ef6\u8bbe\u7f6e\u6388\u6743\u914d\u7f6e
|
||||||
suite_set_session_uri={api_base_url}/service/set_session_info?suite_access_token=%s
|
suite_set_session_uri={api_base_url}/service/set_session_info?suite_access_token=%s
|
||||||
# \u83b7\u53d6\u4f01\u4e1a\u53f7\u7684\u6c38\u4e45\u6388\u6743\u7801
|
# \u83b7\u53d6\u4f01\u4e1a\u53f7\u7684\u6c38\u4e45\u6388\u6743\u7801
|
||||||
suite_get_permanent_uri={api_base_url}/service/get_permanent_code?suite_access_token=%s
|
suite_get_permanent_uri={api_base_url}/service/get_permanent_code?suite_access_token=%s
|
||||||
|
# \u83b7\u53d6\u4f01\u4e1a\u53f7\u7684\u6388\u6743\u4fe1\u606f
|
||||||
|
suite_get_authinfo_uri={api_base_url}/service/get_auth_info?suite_access_token=%s
|
||||||
|
# \u83b7\u53d6\u4f01\u4e1a\u53f7\u5e94\u7528
|
||||||
|
suite_get_agent_uri={api_base_url}/service/get_agent?suite_access_token=%s
|
||||||
|
# \u8bbe\u7f6e\u4f01\u4e1a\u53f7\u5e94\u7528
|
||||||
|
suite_set_agent_uri={api_base_url}/service/set_agent?suite_access_token=%s
|
||||||
@ -1,5 +1,7 @@
|
|||||||
package com.foxinmy.weixin4j.qy.model;
|
package com.foxinmy.weixin4j.qy.model;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import com.foxinmy.weixin4j.qy.type.CorpType;
|
import com.foxinmy.weixin4j.qy.type.CorpType;
|
||||||
|
|
||||||
@ -12,13 +14,28 @@ import com.foxinmy.weixin4j.qy.type.CorpType;
|
|||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class Corpinfo extends AgentOverview {
|
public class Corpinfo implements Serializable {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1251033124778972419L;
|
private static final long serialVersionUID = 1251033124778972419L;
|
||||||
/**
|
/**
|
||||||
* 授权方企业号id
|
* 授权方企业号id
|
||||||
*/
|
*/
|
||||||
private String corpid;
|
private String corpid;
|
||||||
|
/**
|
||||||
|
* 授权方企业号名称
|
||||||
|
*/
|
||||||
|
@JSONField(name = "corp_name")
|
||||||
|
private String corpName;
|
||||||
|
/**
|
||||||
|
* 企业方形头像
|
||||||
|
*/
|
||||||
|
@JSONField(name = "corp_square_logo_url")
|
||||||
|
private String squareLogoUrl;
|
||||||
|
/**
|
||||||
|
* 企业圆形头像
|
||||||
|
*/
|
||||||
|
@JSONField(name = "corp_round_logo_url")
|
||||||
|
private String roundLogoUrl;
|
||||||
/**
|
/**
|
||||||
* 授权方企业号类型
|
* 授权方企业号类型
|
||||||
*/
|
*/
|
||||||
@ -28,17 +45,17 @@ public class Corpinfo extends AgentOverview {
|
|||||||
* 授权方企业号用户规模
|
* 授权方企业号用户规模
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "corp_user_max")
|
@JSONField(name = "corp_user_max")
|
||||||
private int corpUserMax;
|
private int userMax;
|
||||||
/**
|
/**
|
||||||
* 授权方企业号应用规模
|
* 授权方企业号应用规模
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "corp_agent_max")
|
@JSONField(name = "corp_agent_max")
|
||||||
private int corpAgentMax;
|
private int agentMax;
|
||||||
/**
|
/**
|
||||||
* 授权方企业号二维码
|
* 授权方企业号二维码
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "corp_wxqrcode")
|
@JSONField(name = "corp_wxqrcode")
|
||||||
private String corpWxqrcode;
|
private String wxqrcode;
|
||||||
|
|
||||||
public String getCorpid() {
|
public String getCorpid() {
|
||||||
return corpid;
|
return corpid;
|
||||||
@ -56,35 +73,60 @@ public class Corpinfo extends AgentOverview {
|
|||||||
this.corpType = corpType;
|
this.corpType = corpType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCorpUserMax() {
|
public String getCorpName() {
|
||||||
return corpUserMax;
|
return corpName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCorpUserMax(int corpUserMax) {
|
public void setCorpName(String corpName) {
|
||||||
this.corpUserMax = corpUserMax;
|
this.corpName = corpName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCorpAgentMax() {
|
public String getSquareLogoUrl() {
|
||||||
return corpAgentMax;
|
return squareLogoUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCorpAgentMax(int corpAgentMax) {
|
public void setSquareLogoUrl(String squareLogoUrl) {
|
||||||
this.corpAgentMax = corpAgentMax;
|
this.squareLogoUrl = squareLogoUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getCorpWxqrcode() {
|
public String getRoundLogoUrl() {
|
||||||
return corpWxqrcode;
|
return roundLogoUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCorpWxqrcode(String corpWxqrcode) {
|
public void setRoundLogoUrl(String roundLogoUrl) {
|
||||||
this.corpWxqrcode = corpWxqrcode;
|
this.roundLogoUrl = roundLogoUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getUserMax() {
|
||||||
|
return userMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUserMax(int userMax) {
|
||||||
|
this.userMax = userMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAgentMax() {
|
||||||
|
return agentMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAgentMax(int agentMax) {
|
||||||
|
this.agentMax = agentMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getWxqrcode() {
|
||||||
|
return wxqrcode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWxqrcode(String wxqrcode) {
|
||||||
|
this.wxqrcode = wxqrcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Corpinfo [corpid=" + corpid + ", corpType=" + corpType
|
return "Corpinfo [corpid=" + corpid + ", corpName=" + corpName
|
||||||
+ ", corpUserMax=" + corpUserMax + ", corpAgentMax="
|
+ ", squareLogoUrl=" + squareLogoUrl + ", roundLogoUrl="
|
||||||
+ corpAgentMax + ", corpWxqrcode=" + corpWxqrcode + ", "
|
+ roundLogoUrl + ", corpType=" + corpType + ", userMax="
|
||||||
+ super.toString() + "]";
|
+ userMax + ", agentMax=" + agentMax + ", wxqrcode=" + wxqrcode
|
||||||
|
+ "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,12 +3,11 @@ package com.foxinmy.weixin4j.qy.model;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.alibaba.fastjson.JSONObject;
|
|
||||||
import com.alibaba.fastjson.annotation.JSONField;
|
import com.alibaba.fastjson.annotation.JSONField;
|
||||||
import com.foxinmy.weixin4j.qy.type.AgentAuthType;
|
import com.foxinmy.weixin4j.qy.type.AgentAuthType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* oauth授权登陆信息
|
* 企业号oauth授权登陆信息&第三方应用授权信息
|
||||||
*
|
*
|
||||||
* @className OUserInfo
|
* @className OUserInfo
|
||||||
* @author jy
|
* @author jy
|
||||||
@ -48,7 +47,7 @@ public class OUserInfo implements Serializable {
|
|||||||
* 该管理员拥有的通讯录权限
|
* 该管理员拥有的通讯录权限
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "auth_info")
|
@JSONField(name = "auth_info")
|
||||||
private JSONObject authInfo;
|
private AuthInfo authInfo;
|
||||||
|
|
||||||
public boolean isSysAdmin() {
|
public boolean isSysAdmin() {
|
||||||
return isSysAdmin;
|
return isSysAdmin;
|
||||||
@ -90,11 +89,11 @@ public class OUserInfo implements Serializable {
|
|||||||
this.agentInfo = agentInfo;
|
this.agentInfo = agentInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JSONObject getAuthInfo() {
|
public AuthInfo getAuthInfo() {
|
||||||
return authInfo;
|
return authInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthInfo(JSONObject authInfo) {
|
public void setAuthInfo(AuthInfo authInfo) {
|
||||||
this.authInfo = authInfo;
|
this.authInfo = authInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -106,24 +105,78 @@ public class OUserInfo implements Serializable {
|
|||||||
+ authInfo + "]";
|
+ authInfo + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AgentItem {
|
/**
|
||||||
|
* 授权信息
|
||||||
|
*
|
||||||
|
* @className AuthInfo
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月22日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public static class AuthInfo implements Serializable {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -4290240764958942370L;
|
||||||
/**
|
/**
|
||||||
* 应用id
|
* 授权的应用信息
|
||||||
*/
|
*/
|
||||||
private int agentid;
|
@JSONField(name = "agent")
|
||||||
|
private List<AgentItem> agentItems;
|
||||||
|
/**
|
||||||
|
* 授权的通讯录部门
|
||||||
|
*/
|
||||||
|
@JSONField(name = "department")
|
||||||
|
private List<DepartmentItem> departmentItems;
|
||||||
|
|
||||||
|
public List<AgentItem> getAgentItems() {
|
||||||
|
return agentItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAgentItems(List<AgentItem> agentItems) {
|
||||||
|
this.agentItems = agentItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<DepartmentItem> getDepartmentItems() {
|
||||||
|
return departmentItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDepartmentItems(List<DepartmentItem> departmentItems) {
|
||||||
|
this.departmentItems = departmentItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AuthInfo [agentItems=" + agentItems + ", departmentItems="
|
||||||
|
+ departmentItems + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权的应用信息
|
||||||
|
*
|
||||||
|
* @className AgentItem
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月22日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public static class AgentItem extends AgentOverview {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = -1188968391623633559L;
|
||||||
/**
|
/**
|
||||||
* 管理员对应用的权限
|
* 管理员对应用的权限
|
||||||
*/
|
*/
|
||||||
@JSONField(name = "auth_type")
|
@JSONField(name = "auth_type")
|
||||||
private AgentAuthType authType;
|
private AgentAuthType authType;
|
||||||
|
/**
|
||||||
public int getAgentid() {
|
* 服务商套件中的对应应用id
|
||||||
return agentid;
|
*/
|
||||||
}
|
private String appid;
|
||||||
|
/**
|
||||||
public void setAgentid(int agentid) {
|
* 授权方应用敏感权限组,目前仅有get_location,表示是否有权限设置应用获取地理位置的开关
|
||||||
this.agentid = agentid;
|
*/
|
||||||
}
|
@JSONField(name = "api_group")
|
||||||
|
private List<String> apiGroup;
|
||||||
|
|
||||||
public AgentAuthType getAuthType() {
|
public AgentAuthType getAuthType() {
|
||||||
return authType;
|
return authType;
|
||||||
@ -138,10 +191,59 @@ public class OUserInfo implements Serializable {
|
|||||||
this.authType = null;
|
this.authType = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAppid() {
|
||||||
|
return appid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAppid(String appid) {
|
||||||
|
this.appid = appid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getApiGroup() {
|
||||||
|
return apiGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApiGroup(List<String> apiGroup) {
|
||||||
|
this.apiGroup = apiGroup;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "AgentItem [agentid=" + agentid + ", authType=" + authType
|
return "AgentItem [authType=" + authType + ", appid=" + appid
|
||||||
+ "]";
|
+ ", apiGroup=" + apiGroup + ", " + super.toString() + "]";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 授权的通讯录部门
|
||||||
|
*
|
||||||
|
* @className DepartmentItem
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月22日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public static class DepartmentItem extends Party {
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 556556672204642407L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否具有该部门的写权限
|
||||||
|
*/
|
||||||
|
private boolean writable;
|
||||||
|
|
||||||
|
public boolean isWritable() {
|
||||||
|
return writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setWritable(boolean writable) {
|
||||||
|
this.writable = writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "DepartmentItem [writable=" + writable + ", "
|
||||||
|
+ super.toString() + "]";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
package com.foxinmy.weixin4j.qy.suite;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
|
||||||
import com.foxinmy.weixin4j.util.ConfigUtil;
|
|
||||||
import com.foxinmy.weixin4j.xml.XmlStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 用file存储ticket
|
|
||||||
*
|
|
||||||
* @className FileTicketProcessor
|
|
||||||
* @author jy
|
|
||||||
* @date 2015年6月21日
|
|
||||||
* @since JDK 1.7
|
|
||||||
* @see
|
|
||||||
*/
|
|
||||||
public class FileTicketProcessor implements SuiteTicketProcessor {
|
|
||||||
|
|
||||||
private final String ticketPath;
|
|
||||||
|
|
||||||
public FileTicketProcessor() {
|
|
||||||
this.ticketPath = ConfigUtil.getValue("ticket_path");
|
|
||||||
}
|
|
||||||
|
|
||||||
public FileTicketProcessor(String ticketPath) {
|
|
||||||
this.ticketPath = ticketPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void write(SuiteTicketMessage suiteTicket) throws WeixinException {
|
|
||||||
try {
|
|
||||||
XmlStream
|
|
||||||
.toXML(suiteTicket,
|
|
||||||
new FileOutputStream(new File(String.format(
|
|
||||||
"%s/%s.xml", ticketPath,
|
|
||||||
getCacheKey(suiteTicket.getSuiteId())))));
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new WeixinException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getCacheKey(String suiteId) {
|
|
||||||
return String.format("qy_suite_ticket_%s", suiteId);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SuiteTicketMessage read(String suiteId) throws WeixinException {
|
|
||||||
File ticket_file = new File(String.format("%s/%s.xml", ticketPath,
|
|
||||||
getCacheKey(suiteId)));
|
|
||||||
try {
|
|
||||||
return XmlStream.fromXML(new FileInputStream(ticket_file),
|
|
||||||
SuiteTicketMessage.class);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new WeixinException(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -0,0 +1,58 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.suite;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用套件永久授权码的存取
|
||||||
|
*
|
||||||
|
* @className SuitePerCodeHolder
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月22日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class SuitePerCodeHolder {
|
||||||
|
|
||||||
|
public final TokenStorager tokenStorager;
|
||||||
|
|
||||||
|
public SuitePerCodeHolder(TokenStorager tokenStorager) {
|
||||||
|
this.tokenStorager = tokenStorager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存永久授权码
|
||||||
|
*
|
||||||
|
* @param suiteId
|
||||||
|
* @param permanentCode
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public void caching(String suiteId, String permanentCode)
|
||||||
|
throws WeixinException {
|
||||||
|
Token token = new Token(permanentCode);
|
||||||
|
token.setExpiresIn(-1);
|
||||||
|
tokenStorager.caching(getCacheKey(suiteId), token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取永久授权码的key
|
||||||
|
*
|
||||||
|
* @param suiteId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getCacheKey(String suiteId) {
|
||||||
|
return String.format("qy_suite_percode_%s", suiteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找永久二维码
|
||||||
|
*
|
||||||
|
* @param suiteId
|
||||||
|
* @return
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public String lookup(String suiteId) throws WeixinException {
|
||||||
|
return tokenStorager.lookup(getCacheKey(suiteId)).getAccessToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.suite;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenStorager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用套件ticket的存取
|
||||||
|
*
|
||||||
|
* @className SuiteTicketHolder
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月22日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class SuiteTicketHolder {
|
||||||
|
|
||||||
|
public final TokenStorager tokenStorager;
|
||||||
|
|
||||||
|
public SuiteTicketHolder(TokenStorager tokenStorager) {
|
||||||
|
this.tokenStorager = tokenStorager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查找ticket
|
||||||
|
*
|
||||||
|
* @param suiteId
|
||||||
|
* @return
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public String lookup(String suiteId) throws WeixinException {
|
||||||
|
return tokenStorager.lookup(getCacheKey(suiteId)).getAccessToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取ticket的key
|
||||||
|
*
|
||||||
|
* @param suiteId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getCacheKey(String suiteId) {
|
||||||
|
return String.format("qy_suite_ticket_%s", suiteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存ticket
|
||||||
|
*
|
||||||
|
* @param suiteTicket
|
||||||
|
* @throws WeixinException
|
||||||
|
*/
|
||||||
|
public void caching(SuiteTicketMessage suiteTicket) throws WeixinException {
|
||||||
|
Token token = new Token(suiteTicket.getSuiteTicket());
|
||||||
|
token.setExpiresIn(-1);
|
||||||
|
tokenStorager.caching(getCacheKey(suiteTicket.getSuiteId()), token);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,31 +0,0 @@
|
|||||||
package com.foxinmy.weixin4j.qy.suite;
|
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.exception.WeixinException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 对套件ticket的处理:写入与读取
|
|
||||||
*
|
|
||||||
* @className SuiteTicketProcessor
|
|
||||||
* @author jy
|
|
||||||
* @date 2015年6月18日
|
|
||||||
* @since JDK 1.7
|
|
||||||
* @see
|
|
||||||
*/
|
|
||||||
public interface SuiteTicketProcessor {
|
|
||||||
/**
|
|
||||||
* 写入微信推送过来的suite_ticket
|
|
||||||
*
|
|
||||||
* @param suiteTicket
|
|
||||||
* @throws WeixinException
|
|
||||||
*/
|
|
||||||
public void write(SuiteTicketMessage suiteTicket) throws WeixinException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 读取最新的suite_ticket
|
|
||||||
*
|
|
||||||
* @param suiteId
|
|
||||||
* @return 最新的ticket
|
|
||||||
* @throws WeixinException
|
|
||||||
*/
|
|
||||||
public SuiteTicketMessage read(String suiteId) throws WeixinException;
|
|
||||||
}
|
|
||||||
@ -24,7 +24,7 @@ public class WeixinSuiteTokenCreator implements TokenCreator {
|
|||||||
private final WeixinHttpClient httpClient;
|
private final WeixinHttpClient httpClient;
|
||||||
private final String suiteId;
|
private final String suiteId;
|
||||||
private final String suiteSecret;
|
private final String suiteSecret;
|
||||||
private final SuiteTicketProcessor ticketProcessor;
|
private final SuiteTicketHolder ticketHolder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
@ -32,14 +32,14 @@ public class WeixinSuiteTokenCreator implements TokenCreator {
|
|||||||
* 套件ID
|
* 套件ID
|
||||||
* @param suiteSecret
|
* @param suiteSecret
|
||||||
* 套件secret
|
* 套件secret
|
||||||
* @param ticketReader
|
* @param stringStorager
|
||||||
* 套件ticket读取器
|
* 套件ticket存取器
|
||||||
*/
|
*/
|
||||||
public WeixinSuiteTokenCreator(String suiteId, String suiteSecret,
|
public WeixinSuiteTokenCreator(String suiteId, String suiteSecret,
|
||||||
SuiteTicketProcessor ticketProcessor) {
|
SuiteTicketHolder ticketHolder) {
|
||||||
this.suiteId = suiteId;
|
this.suiteId = suiteId;
|
||||||
this.suiteSecret = suiteSecret;
|
this.suiteSecret = suiteSecret;
|
||||||
this.ticketProcessor = ticketProcessor;
|
this.ticketHolder = ticketHolder;
|
||||||
this.httpClient = new WeixinHttpClient();
|
this.httpClient = new WeixinHttpClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ public class WeixinSuiteTokenCreator implements TokenCreator {
|
|||||||
JSONObject obj = new JSONObject();
|
JSONObject obj = new JSONObject();
|
||||||
obj.put("suite_id", suiteId);
|
obj.put("suite_id", suiteId);
|
||||||
obj.put("suite_secret", suiteSecret);
|
obj.put("suite_secret", suiteSecret);
|
||||||
obj.put("suite_ticket", ticketProcessor.read(suiteId).getSuiteTicket());
|
obj.put("suite_ticket", ticketHolder.lookup(suiteId));
|
||||||
WeixinResponse response = httpClient.post(URLConsts.SUITE_TOKEN_URL,
|
WeixinResponse response = httpClient.post(URLConsts.SUITE_TOKEN_URL,
|
||||||
obj.toJSONString());
|
obj.toJSONString());
|
||||||
obj = response.getAsJson();
|
obj = response.getAsJson();
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
package com.foxinmy.weixin4j.qy.suite;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.foxinmy.weixin4j.exception.WeixinException;
|
||||||
|
import com.foxinmy.weixin4j.http.weixin.WeixinHttpClient;
|
||||||
|
import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
|
||||||
|
import com.foxinmy.weixin4j.model.Token;
|
||||||
|
import com.foxinmy.weixin4j.qy.type.URLConsts;
|
||||||
|
import com.foxinmy.weixin4j.token.TokenCreator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信企业号token创建(永久授权码)
|
||||||
|
*
|
||||||
|
* @className WeixinTokenSuiteCreator
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年6月17日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see <a
|
||||||
|
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AC%AC%E4%B8%89%E6%96%B9%E5%BA%94%E7%94%A8%E6%8E%A5%E5%8F%A3%E8%AF%B4%E6%98%8E#.E8.8E.B7.E5.8F.96.E4.BC.81.E4.B8.9A.E5.8F.B7access_token">获取企业号access_token</a>
|
||||||
|
* @see com.foxinmy.weixin4j.model.Token
|
||||||
|
*/
|
||||||
|
public class WeixinTokenSuiteCreator implements TokenCreator {
|
||||||
|
|
||||||
|
private final WeixinHttpClient httpClient;
|
||||||
|
private final String suiteId;
|
||||||
|
private final String authCorpid;
|
||||||
|
private final SuitePerCodeHolder perCodeHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param suiteId
|
||||||
|
* 应用套件ID
|
||||||
|
* @param suiteSecret
|
||||||
|
* 授权方corpid
|
||||||
|
* @param perCodeHolder
|
||||||
|
* 永久授权码
|
||||||
|
*/
|
||||||
|
public WeixinTokenSuiteCreator(String suiteId, String authCorpid,
|
||||||
|
SuitePerCodeHolder perCodeHolder) {
|
||||||
|
this.suiteId = suiteId;
|
||||||
|
this.authCorpid = authCorpid;
|
||||||
|
this.perCodeHolder = perCodeHolder;
|
||||||
|
this.httpClient = new WeixinHttpClient();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getCacheKey() {
|
||||||
|
return String.format("qy_token_suite_%s", suiteId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token createToken() throws WeixinException {
|
||||||
|
JSONObject obj = new JSONObject();
|
||||||
|
obj.put("suite_id", suiteId);
|
||||||
|
obj.put("auth_corpid", authCorpid);
|
||||||
|
obj.put("permanent_code", perCodeHolder.lookup(suiteId));
|
||||||
|
WeixinResponse response = httpClient.post(URLConsts.TOKEN_SUITE_URL,
|
||||||
|
obj.toJSONString());
|
||||||
|
obj = response.getAsJson();
|
||||||
|
Token token = new Token(obj.getString("access_token"));
|
||||||
|
token.setExpiresIn(obj.getIntValue("expires_in"));
|
||||||
|
token.setTime(System.currentTimeMillis());
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -40,4 +40,10 @@ public final class URLConsts {
|
|||||||
*/
|
*/
|
||||||
public static final String SUITE_PRE_CODE_URL = BASE_URL
|
public static final String SUITE_PRE_CODE_URL = BASE_URL
|
||||||
+ "/service/get_pre_auth_code?suite_access_token=%s";
|
+ "/service/get_pre_auth_code?suite_access_token=%s";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 企业号第三方应用套件获取企业号access_token的url
|
||||||
|
*/
|
||||||
|
public static final String TOKEN_SUITE_URL = BASE_URL
|
||||||
|
+ "/service/get_corp_token?suite_access_token=%s";
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user