重构Cache实现

This commit is contained in:
jinyu 2016-05-28 11:33:05 +08:00
parent bc93a22563
commit b797580384
116 changed files with 1932 additions and 1313 deletions

View File

@ -702,3 +702,7 @@
+ weixin4j-base:修改Memcached-Java-Client的依赖 + weixin4j-base:修改Memcached-Java-Client的依赖
+ weixin4j-base:系统配置类抽象化 + weixin4j-base:系统配置类抽象化
* 2016-05-28
+ 重构Cache实现

View File

@ -42,7 +42,7 @@
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>2.6.0</version> <version>2.8.1</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -632,7 +632,8 @@ public class PayApi extends MchApi {
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt", String fileName = String.format("weixin4j_bill_%s_%s_%s.txt",
formatBillDate, billType.name().toLowerCase(), formatBillDate, billType.name().toLowerCase(),
weixinAccount.getId()); weixinAccount.getId());
File file = new File(String.format("%s/%s", billPath, fileName)); File file = new File(String.format("%s%s%s", billPath, File.separator,
fileName));
if (file.exists()) { if (file.exists()) {
return file; return file;
} }

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.token; package com.foxinmy.weixin4j.cache;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
@ -11,7 +11,7 @@ import com.foxinmy.weixin4j.exception.WeixinException;
* @since JDK 1.6 * @since JDK 1.6
* @see * @see
*/ */
public interface CacheCreator<T> { public interface CacheCreator<T extends Cacheable> {
/** /**
* CacheKey * CacheKey
* *

View File

@ -0,0 +1,69 @@
package com.foxinmy.weixin4j.cache;
import com.foxinmy.weixin4j.exception.WeixinException;
/**
* 缓存管理类
*
* @className CacheManager
* @author jinyu(foxinmy@gmail.com)
* @date 2016年5月27日
* @since JDK 1.7
* @see
*/
public class CacheManager<T extends Cacheable> {
protected final CacheCreator<T> cacheCreator;
protected final CacheStorager<T> cacheStorager;
public CacheManager(CacheCreator<T> cacheCreator,
CacheStorager<T> cacheStorager) {
this.cacheCreator = cacheCreator;
this.cacheStorager = cacheStorager;
}
/**
* 获取缓存对象
*
* @return 缓存对象
* @throws WeixinException
*/
public T getCache() throws WeixinException {
String cacheKey = cacheCreator.key();
T cache = cacheStorager.lookup(cacheKey);
if (cache == null) {
cache = cacheCreator.create();
cacheStorager.caching(cacheKey, cache);
}
return cache;
}
/**
* 刷新缓存对象
*
* @return 缓存对象
* @throws WeixinException
*/
public T refreshCache() throws WeixinException {
String cacheKey = cacheCreator.key();
T cache = cacheCreator.create();
cacheStorager.caching(cacheKey, cache);
return cache;
}
/**
* 移除缓存
*
* @return 被移除的缓存对象
*/
public T evictCache() {
String cacheKey = cacheCreator.key();
return cacheStorager.evict(cacheKey);
}
/**
* 清除所有的缓存(<font color="red">请慎重</font>)
*/
public void clearCache() {
cacheStorager.clear();
}
}

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.token; package com.foxinmy.weixin4j.cache;
/** /**
* Cache的存储 * Cache的存储
@ -9,7 +9,17 @@ package com.foxinmy.weixin4j.token;
* @since JDK 1.6 * @since JDK 1.6
* @see * @see
*/ */
public interface CacheStorager<T> { public interface CacheStorager<T extends Cacheable> {
/**
* 考虑到临界情况,实际缓存的有效时间减去该毫秒数(60秒)
*/
long CUTMS = 60 * 1000l;
/**
* 所有的缓存KEY
*/
String ALLKEY = "weixin4j_cache_keys";
/** /**
* 查找缓存中的对象 * 查找缓存中的对象
* *
@ -42,8 +52,6 @@ public interface CacheStorager<T> {
/** /**
* 清除所有缓存对象(<font color="red">请慎重</font>) * 清除所有缓存对象(<font color="red">请慎重</font>)
* *
* @param prefix
* 缓存key的前缀
*/ */
void clear(String prefix); void clear();
} }

View File

@ -0,0 +1,28 @@
package com.foxinmy.weixin4j.cache;
import java.io.Serializable;
/**
* 可缓存的对象
*
* @className Cacheable
* @author jinyu(foxinmy@gmail.com)
* @date 2016年5月26日
* @since JDK 1.6
* @see
*/
public interface Cacheable extends Serializable {
/**
* 过期时间(单位:毫秒),值小于0时视为永不过期
*
* @return 缓存过期时间
*/
public long getExpires();
/**
* 创建时间(单位:毫秒)
*
* @return 缓存对象创建时间
*/
public long getCreateTime();
}

View File

@ -0,0 +1,87 @@
package com.foxinmy.weixin4j.cache;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.foxinmy.weixin4j.util.SerializationUtils;
/**
* 用File保存缓存对象
*
* @className FileCacheStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2016年5月27日
* @since JDK 1.6
* @see
*/
public class FileCacheStorager<T extends Cacheable> implements CacheStorager<T> {
private final File tmpdir;
private final String SEPARATOR = File.separator;
public FileCacheStorager(String cachePath) {
this.tmpdir = new File(String.format("%s%sweixin4j_token_temp",
cachePath, SEPARATOR));
this.tmpdir.mkdirs();
}
@Override
public T lookup(String cacheKey) {
File cacheFile = new File(String.format("%s%s%s",
tmpdir.getAbsolutePath(), SEPARATOR, cacheKey));
try {
if (cacheFile.exists()) {
T cache = SerializationUtils.deserialize(new FileInputStream(
cacheFile));
if (cache.getCreateTime() < 0) {
return cache;
}
if ((cache.getCreateTime() + cache.getExpires() - CUTMS) > System
.currentTimeMillis()) {
return cache;
}
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void caching(String cacheKey, T cache) {
try {
SerializationUtils.serialize(
cache,
new FileOutputStream(new File(String.format("%s%s%s",
tmpdir.getAbsolutePath(), SEPARATOR, cacheKey))));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public T evict(String cacheKey) {
T cache = null;
File cacheFile = new File(String.format("%s%s%s",
tmpdir.getAbsolutePath(), SEPARATOR, cacheKey));
try {
if (cacheFile.exists()) {
cache = SerializationUtils.deserialize(new FileInputStream(
cacheFile));
cacheFile.delete();
}
} catch (IOException e) {
; // ingore
}
return cache;
}
@Override
public void clear() {
for (File cache : tmpdir.listFiles()) {
cache.delete();
}
}
}

View File

@ -1,61 +1,82 @@
package com.foxinmy.weixin4j.token; package com.foxinmy.weixin4j.cache;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import com.foxinmy.weixin4j.model.Token;
import com.whalin.MemCached.MemCachedClient; import com.whalin.MemCached.MemCachedClient;
import com.whalin.MemCached.SockIOPool; import com.whalin.MemCached.SockIOPool;
/** /**
* 用Memcache保存Token信息(推荐使用) * 用Memcache保存缓存对象(推荐使用)
* *
* @className MemcacheTokenStorager * @className MemcacheCacheStorager
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2016年5月11日 * @date 2016年5月11日
* @since JDK 1.6 * @since JDK 1.6
* @see * @see
*/ */
public class MemcacheTokenStorager extends TokenStorager { public class MemcacheCacheStorager<T extends Cacheable> implements
CacheStorager<T> {
private final MemCachedClient mc; private final MemCachedClient mc;
public MemcacheTokenStorager(MemcachePoolConfig poolConfig) { public MemcacheCacheStorager() {
this(new MemcachePoolConfig());
}
public MemcacheCacheStorager(MemcachePoolConfig poolConfig) {
mc = new MemCachedClient(); mc = new MemCachedClient();
poolConfig.initSocketIO(); poolConfig.initSocketIO();
mc.set(ALLKEY, new HashSet<String>());
} }
@SuppressWarnings("unchecked")
@Override @Override
public Token lookup(String cacheKey) { public T lookup(String cacheKey) {
return (Token) mc.get(cacheKey); return (T) mc.get(cacheKey);
} }
@SuppressWarnings("unchecked")
@Override @Override
public void caching(String cacheKey, Token token) { public void caching(String cacheKey, T cache) {
if (token.getExpiresIn() > 0) { if (cache.getCreateTime() > 0l) {
mc.set(cacheKey, token, mc.set(cacheKey,
new Date(token.getCreateTime() + token.getExpiresIn() cache,
* 1000 - ms())); new Date(cache.getCreateTime() + cache.getExpires() - CUTMS));
} else { } else {
mc.set(cacheKey, token); mc.set(cacheKey, cache);
} }
Set<String> all = (Set<String>) mc.get(ALLKEY);
all.add(cacheKey);
mc.set(ALLKEY, all);
} }
@SuppressWarnings("unchecked")
@Override @Override
public Token evict(String cacheKey) { public T evict(String cacheKey) {
Token token = lookup(cacheKey); T cache = lookup(cacheKey);
mc.delete(cacheKey); mc.delete(cacheKey);
return token; Set<String> all = (Set<String>) mc.get(ALLKEY);
all.remove(cacheKey);
mc.set(ALLKEY, all);
return cache;
} }
@SuppressWarnings("unchecked")
@Override @Override
public void clear(String prefix) { public void clear() {
throw new UnsupportedOperationException(); Set<String> all = (Set<String>) mc.get(ALLKEY);
for (String key : all) {
mc.delete(key);
}
mc.delete(ALLKEY);
} }
public static class MemcachePoolConfig { public static class MemcachePoolConfig {
public final static String HOST = "localhost"; public final static String HOST = "127.0.0.1";
public final static int PORT = 11211; public final static int PORT = 11211;
public final static int WEIGHT = 1; public final static int WEIGHT = 1;

View File

@ -0,0 +1,50 @@
package com.foxinmy.weixin4j.cache;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
* 用内存保存缓存对象(不推荐使用)
*
* @className MemoryCacheStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2016年1月24日
* @since JDK 1.6
* @see
*/
public class MemoryCacheStorager<T extends Cacheable> implements
CacheStorager<T> {
private final Map<String, T> CONMAP;
public MemoryCacheStorager() {
this.CONMAP = new ConcurrentHashMap<String, T>();
}
@Override
public T lookup(String cacheKey) {
T cache = this.CONMAP.get(cacheKey);
if (cache != null) {
if ((cache.getCreateTime() + cache.getExpires() - CUTMS) > System
.currentTimeMillis()) {
return cache;
}
}
return null;
}
@Override
public void caching(String cacheKey, T cache) {
this.CONMAP.put(cacheKey, cache);
}
@Override
public T evict(String cacheKey) {
return this.CONMAP.remove(cacheKey);
}
@Override
public void clear() {
this.CONMAP.clear();
}
}

View File

@ -0,0 +1,13 @@
### CACHE的实现
* CacheCreator 负责创建新的缓存对象
* CacheStorager 负责查找已缓存的对象或者缓存新的对象
* TokenManager 负责对缓存对象的管理(屏蔽细节)
* FileCacheStorager 是系统默认的缓存存储策略实现
* RedisCacheStorager(RedisClusterCacheStorager) 使用redis保存缓存对象(需要自行添加客户端包,[jedis](https://github.com/xetorthio/jedis))
* MemcacheCacheStorager 使用memcache保存缓存对象(需要自行添加客户端包,[Memcached-Java-Client](https://github.com/gwhalin/Memcached-Java-Client))

View File

@ -0,0 +1,128 @@
package com.foxinmy.weixin4j.cache;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.SerializationUtils;
/**
* 用Redis保存缓存对象(推荐使用)
*
* @className RedisCacheStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2015年1月9日
* @since JDK 1.6
*/
public class RedisCacheStorager<T extends Cacheable> implements
CacheStorager<T> {
private JedisPool jedisPool;
private final static String HOST = "127.0.0.1";
private final static int PORT = 6379;
private final static int TIMEOUT = 5000;
private final static int MAX_TOTAL = 50;
private final static int MAX_IDLE = 5;
private final static int MAX_WAIT_MILLIS = 5000;
private final static boolean TEST_ON_BORROW = false;
private final static boolean TEST_ON_RETURN = true;
public RedisCacheStorager() {
this(HOST, PORT, TIMEOUT);
}
public RedisCacheStorager(String host, int port, int timeout) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(MAX_TOTAL);
jedisPoolConfig.setMaxIdle(MAX_IDLE);
jedisPoolConfig.setMaxWaitMillis(MAX_WAIT_MILLIS);
jedisPoolConfig.setTestOnBorrow(TEST_ON_BORROW);
jedisPoolConfig.setTestOnReturn(TEST_ON_RETURN);
this.jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout);
}
public RedisCacheStorager(JedisPoolConfig jedisPoolConfig) {
this(new JedisPool(jedisPoolConfig, HOST, PORT, TIMEOUT));
}
public RedisCacheStorager(String host, int port, int timeout,
JedisPoolConfig jedisPoolConfig) {
this(new JedisPool(jedisPoolConfig, host, port, timeout));
}
public RedisCacheStorager(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
@SuppressWarnings("unchecked")
@Override
public T lookup(String cacheKey) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
byte[] value = jedis.get(cacheKey.getBytes(Consts.UTF_8));
return value != null ? (T) SerializationUtils.deserialize(value)
: null;
} finally {
if (jedis != null) {
jedis.close();
}
}
}
@Override
public void caching(String cacheKey, T cache) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
byte[] key = cacheKey.getBytes(Consts.UTF_8);
byte[] value = SerializationUtils.serialize(cache);
jedis.set(key, value);
if (cache.getExpires() > 0) {
jedis.expire(key, (int) (cache.getExpires() - CUTMS) / 1000);
}
jedis.sadd(ALLKEY, cacheKey);
} finally {
if (jedis != null) {
jedis.close();
}
}
}
@Override
public T evict(String cacheKey) {
T cache = lookup(cacheKey);
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.del(cacheKey);
jedis.srem(ALLKEY, cacheKey);
} finally {
if (jedis != null) {
jedis.close();
}
}
return cache;
}
@Override
public void clear() {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
Set<String> cacheKeys = jedis.smembers(ALLKEY);
if (!cacheKeys.isEmpty()) {
cacheKeys.add(ALLKEY);
jedis.del(cacheKeys.toArray(new String[cacheKeys.size()]));
}
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}

View File

@ -0,0 +1,94 @@
package com.foxinmy.weixin4j.cache;
import java.util.Set;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.SerializationUtils;
/**
* 用Redis(集群)保存缓存对象(推荐使用)
*
* @className RedisCacheStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2015年1月9日
* @since JDK 1.6
*/
public class RedisClusterCacheStorager<T extends Cacheable> implements
CacheStorager<T> {
private final static int CONNECTION_TIMEOUT = 5000;
private final static int SO_TIMEOUT = 5000;
private final static int MAX_REDIRECTIONS = 5;
private final static int MAX_TOTAL = 50;
private final static int MAX_IDLE = 5;
private final static int MAX_WAIT_MILLIS = 5000;
private final static boolean TEST_ON_BORROW = false;
private final static boolean TEST_ON_RETURN = true;
private final JedisCluster jedisCluster;
public RedisClusterCacheStorager(Set<HostAndPort> nodes) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(MAX_TOTAL);
jedisPoolConfig.setMaxIdle(MAX_IDLE);
jedisPoolConfig.setMaxWaitMillis(MAX_WAIT_MILLIS);
jedisPoolConfig.setTestOnBorrow(TEST_ON_BORROW);
jedisPoolConfig.setTestOnReturn(TEST_ON_RETURN);
this.jedisCluster = new JedisCluster(nodes, CONNECTION_TIMEOUT,
SO_TIMEOUT, MAX_REDIRECTIONS, jedisPoolConfig);
}
public RedisClusterCacheStorager(Set<HostAndPort> nodes,
JedisPoolConfig poolConfig) {
this(nodes, CONNECTION_TIMEOUT, SO_TIMEOUT, MAX_REDIRECTIONS,
poolConfig);
}
public RedisClusterCacheStorager(Set<HostAndPort> nodes,
int connectionTimeout, int soTimeout, int maxRedirections,
JedisPoolConfig poolConfig) {
this(new JedisCluster(nodes, connectionTimeout, soTimeout,
maxRedirections, poolConfig));
}
public RedisClusterCacheStorager(JedisCluster jedisCluster) {
this.jedisCluster = jedisCluster;
}
@SuppressWarnings("unchecked")
@Override
public T lookup(String cacheKey) {
byte[] value = jedisCluster.get(cacheKey.getBytes(Consts.UTF_8));
return value != null ? (T) SerializationUtils.deserialize(value) : null;
}
@Override
public void caching(String cacheKey, T cache) {
byte[] key = cacheKey.getBytes(Consts.UTF_8);
byte[] value = SerializationUtils.serialize(cache);
jedisCluster.set(key, value);
if (cache.getExpires() > 0) {
jedisCluster.expire(key, (int) (cache.getExpires() - CUTMS) / 1000);
}
jedisCluster.sadd(ALLKEY, cacheKey);
}
@Override
public T evict(String cacheKey) {
T cache = lookup(cacheKey);
jedisCluster.del(cacheKey);
jedisCluster.srem(ALLKEY, cacheKey);
return cache;
}
@Override
public void clear() {
Set<String> cacheKeys = jedisCluster.smembers(ALLKEY);
if (!cacheKeys.isEmpty()) {
cacheKeys.add(ALLKEY);
jedisCluster.del(cacheKeys.toArray(new String[cacheKeys.size()]));
}
}
}

View File

@ -1431,6 +1431,10 @@
<code>81003</code> <code>81003</code>
<text>邀请额度已用完</text> <text>邀请额度已用完</text>
</error> </error>
<error>
<code>81004</code>
<text>部门数量超过上限</text>
</error>
<error> <error>
<code>82001</code> <code>82001</code>
<text>发送消息或者邀请的参数全部为空或者全部不合法</text> <text>发送消息或者邀请的参数全部为空或者全部不合法</text>

View File

@ -7,7 +7,7 @@ import java.util.Set;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.DigestUtil;
import com.foxinmy.weixin4j.util.MapUtil; import com.foxinmy.weixin4j.util.MapUtil;
@ -25,17 +25,17 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
* @see * @see
*/ */
public class JSSDKConfigurator { public class JSSDKConfigurator {
private final TokenHolder ticketTokenHolder; private final TokenManager ticketTokenManager;
private JSONObject config; private JSONObject config;
private Set<JSSDKAPI> apis; private Set<JSSDKAPI> apis;
/** /**
* ticket保存类 可调用WeixinProxy#getTicketHolder获取 * ticket保存类 可调用WeixinProxy#getTicketManager获取
* *
* @param ticketTokenHolder * @param ticketTokenManager
*/ */
public JSSDKConfigurator(TokenHolder ticketTokenHolder) { public JSSDKConfigurator(TokenManager ticketTokenManager) {
this.ticketTokenHolder = ticketTokenHolder; this.ticketTokenManager = ticketTokenManager;
this.config = new JSONObject(); this.config = new JSONObject();
this.apis = new HashSet<JSSDKAPI>(); this.apis = new HashSet<JSSDKAPI>();
} }
@ -113,7 +113,7 @@ public class JSSDKConfigurator {
String noncestr = RandomUtil.generateString(24); String noncestr = RandomUtil.generateString(24);
signMap.put("timestamp", timestamp); signMap.put("timestamp", timestamp);
signMap.put("noncestr", noncestr); signMap.put("noncestr", noncestr);
signMap.put("jsapi_ticket", this.ticketTokenHolder.getAccessToken()); signMap.put("jsapi_ticket", this.ticketTokenManager.getAccessToken());
signMap.put("url", url); signMap.put("url", url);
String sign = DigestUtil.SHA1(MapUtil.toJoinString(signMap, false, String sign = DigestUtil.SHA1(MapUtil.toJoinString(signMap, false,
false)); false));

View File

@ -6,6 +6,7 @@ import java.util.Arrays;
import java.util.List; import java.util.List;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.ButtonType; import com.foxinmy.weixin4j.type.ButtonType;
/** /**
@ -38,13 +39,20 @@ public class Button implements Serializable {
/** /**
* 菜单KEY值,根据type的类型而定</p> 通过公众平台设置的自定义菜单</br> <li>text:保存文字 <li> * 菜单KEY值,根据type的类型而定</p> 通过公众平台设置的自定义菜单</br> <li>text:保存文字 <li>
* imgvoice保存媒体ID <li>video保存视频URL <li> * imgvoice保存媒体ID <li>video保存视频URL <li>
* news保存图文消息:List#com.foxinmy.weixin4j.tuple.MpArticle# <li>view保存链接URL * news保存图文消息媒体ID <li>view保存链接URL
* <p>使用API设置的自定义菜单</p> <li> * <p>
* 使用API设置的自定义菜单
* </p> <li>
* clickscancode_pushscancode_waitmsgpic_sysphotopic_photo_or_album * clickscancode_pushscancode_waitmsgpic_sysphotopic_photo_or_album
* pic_weixinlocation_select保存key <li>view保存链接URL; <li> * pic_weixinlocation_select保存key <li>view保存链接URL; <li>
* media_idview_limited保存媒体ID * media_idview_limited保存媒体ID
*/ */
private Serializable content; private String content;
/**
* 图文列表 只有在公众平台设置的菜单才有
*/
@JSONField(serialize = false, deserialize = false)
private List<MpArticle> articles;
/** /**
* 二级菜单数组个数应为1~5个 * 二级菜单数组个数应为1~5个
*/ */
@ -101,14 +109,27 @@ public class Button implements Serializable {
this.type = type; this.type = type;
} }
public Serializable getContent() { public String getContent() {
return content; return content;
} }
public void setContent(Serializable content) { public void setContent(String content) {
this.content = content; this.content = content;
} }
public List<MpArticle> getArticles() {
return articles;
}
/**
* <font color="red">创建菜单设置无效</font>
*
* @param articles
*/
public void setArticles(List<MpArticle> articles) {
this.articles = articles;
}
public List<Button> getSubs() { public List<Button> getSubs() {
return subs; return subs;
} }
@ -125,6 +146,6 @@ public class Button implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "Button [name=" + name + ", type=" + type + ", content=" return "Button [name=" + name + ", type=" + type + ", content="
+ content + ", subs=" + subs + "]"; + content + ", articles=" + articles + ", subs=" + subs + "]";
} }
} }

View File

@ -1,12 +1,10 @@
package com.foxinmy.weixin4j.model; package com.foxinmy.weixin4j.model;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import com.foxinmy.weixin4j.type.MediaType;
/** /**
* 媒体文件上传结果 * 媒体文件上传结果
* *
@ -27,11 +25,8 @@ public class MediaUploadResult implements Serializable {
*/ */
private String url; private String url;
@JSONCreator public MediaUploadResult(String mediaId, MediaType mediaType,
public MediaUploadResult(@JSONField(name = "media_id") String mediaId, Date createdAt, String url) {
@JSONField(name = "type") MediaType mediaType,
@JSONField(name = "created_at") Date createdAt,
@JSONField(name = "url") String url) {
this.mediaId = mediaId; this.mediaId = mediaId;
this.mediaType = mediaType; this.mediaType = mediaType;
this.createdAt = createdAt; this.createdAt = createdAt;

View File

@ -1,8 +1,9 @@
package com.foxinmy.weixin4j.model; package com.foxinmy.weixin4j.model;
import java.io.Serializable; import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.cache.Cacheable;
/** /**
* access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token,正常情况下access_token有效期为7200秒, * access_token是公众号的全局唯一票据,公众号调用各接口时都需使用access_token,正常情况下access_token有效期为7200秒,
@ -17,75 +18,95 @@ import com.alibaba.fastjson.annotation.JSONField;
* @see <a * @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8">微信企业号的主动模式</a> * href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%B8%BB%E5%8A%A8%E8%B0%83%E7%94%A8">微信企业号的主动模式</a>
*/ */
public class Token implements Serializable { public class Token implements Cacheable {
private static final long serialVersionUID = -7564855472419104084L; private static final long serialVersionUID = -7564855472419104084L;
/** /**
* 获取到的凭证 * 获取到的凭证
*/ */
@JSONField(name = "access_token")
private String accessToken; private String accessToken;
/** /**
* 凭证有效时间单位 * 凭证有效时间单位
*/ */
@JSONField(name = "expires_in") private long expires;
private int expiresIn;
/** /**
* token创建的时间,单位毫秒 * token创建的时间,单位毫秒
*/ */
@JSONField(name = "create_time")
private long createTime; private long createTime;
/** /**
* 请求返回的原始结果 * 扩展信息
*/ */
@JSONField(name = "original_result") private Map<String, String> extra;
private String originalResult;
protected Token() { /**
// jaxb required * 永不过期创建时间为当前时间戳的token对象
*
* @param accessToken
* 凭证字符串
*/
public Token(String accessToken) {
this(accessToken, -1);
} }
public Token(String accessToken) { /**
* 有过期时间创建时间为当前时间戳的token对象
*
* @param accessToken
* 凭证字符串
* @param expires
* 过期时间 单位毫秒
*/
public Token(String accessToken, long expires) {
this(accessToken, expires, System.currentTimeMillis());
}
/**
*
* @param accessToken
* 凭证字符串
* @param expires
* 过期时间 单位毫秒
* @param createTime
* 创建时间戳 单位毫秒
*/
public Token(String accessToken, long expires, long createTime) {
this.accessToken = accessToken; this.accessToken = accessToken;
this.createTime = System.currentTimeMillis(); this.expires = expires;
this.createTime = createTime;
this.extra = new HashMap<String, String>();
} }
public String getAccessToken() { public String getAccessToken() {
return accessToken; return accessToken;
} }
public void setAccessToken(String accessToken) { @Override
this.accessToken = accessToken; public long getExpires() {
} return expires;
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
} }
@Override
public long getCreateTime() { public long getCreateTime() {
return createTime; return createTime;
} }
public void setCreateTime(long createTime) { public Map<String, String> getExtra() {
this.createTime = createTime; return extra;
} }
public String getOriginalResult() { public void setExtra(Map<String, String> extra) {
return originalResult; this.extra = extra;
} }
public void setOriginalResult(String originalResult) { public Token pushExtra(String name, String value) {
this.originalResult = originalResult; this.extra.put(name, value);
return this;
} }
@Override @Override
public String toString() { public String toString() {
return "Token [accessToken=" + accessToken + ", expiresIn=" + expiresIn return "Token [accessToken=" + accessToken + ", expires=" + expires
+ ", createTime=" + createTime + "]"; + ", createTime=" + createTime + ", extra=" + extra + "]";
} }
} }

View File

@ -1,8 +1,6 @@
package com.foxinmy.weixin4j.setting; package com.foxinmy.weixin4j.setting;
import com.foxinmy.weixin4j.http.HttpParams; import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.token.FileTokenStorager;
import com.foxinmy.weixin4j.token.TokenStorager;
/** /**
* 系统配置相关 * 系统配置相关
@ -22,10 +20,6 @@ public abstract class SystemSettings<T> {
* Http参数 * Http参数
*/ */
private HttpParams httpParams; private HttpParams httpParams;
/**
* token存储方式 默认为FileTokenStorager
*/
private TokenStorager tokenStorager;
/** /**
* 系统临时目录 * 系统临时目录
*/ */
@ -59,17 +53,6 @@ public abstract class SystemSettings<T> {
public abstract String getTmpdir0(); public abstract String getTmpdir0();
public TokenStorager getTokenStorager() {
return tokenStorager;
}
public TokenStorager getTokenStorager0() {
if (tokenStorager == null) {
return new FileTokenStorager(getTmpdir0());
}
return tokenStorager;
}
public void setHttpParams(HttpParams httpParams) { public void setHttpParams(HttpParams httpParams) {
this.httpParams = httpParams; this.httpParams = httpParams;
} }
@ -78,13 +61,9 @@ public abstract class SystemSettings<T> {
this.tmpdir = tmpdir; this.tmpdir = tmpdir;
} }
public void setTokenStorager(TokenStorager tokenStorager) {
this.tokenStorager = tokenStorager;
}
@Override @Override
public String toString() { public String toString() {
return "account=" + account + ", httpParams=" + httpParams return "account=" + account + ", httpParams=" + httpParams
+ ",tokenStorager=" + tokenStorager + ", tmpdir=" + tmpdir; + ", tmpdir=" + tmpdir;
} }
} }

View File

@ -1,6 +1,9 @@
package com.foxinmy.weixin4j.setting; package com.foxinmy.weixin4j.setting;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.cache.FileCacheStorager;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.model.WeixinPayAccount;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
@ -20,6 +23,10 @@ public class Weixin4jSettings extends SystemSettings<WeixinAccount> {
* 微信支付账号信息 * 微信支付账号信息
*/ */
private WeixinPayAccount weixinPayAccount; private WeixinPayAccount weixinPayAccount;
/**
* Token的存储方式 默认为FileCacheStorager
*/
private CacheStorager<Token> cacheStorager;
/** /**
* 支付接口需要的证书文件(*.p12) * 支付接口需要的证书文件(*.p12)
*/ */
@ -81,6 +88,21 @@ public class Weixin4jSettings extends SystemSettings<WeixinAccount> {
return getTmpdir(); return getTmpdir();
} }
public CacheStorager<Token> getCacheStorager() {
return cacheStorager;
}
public CacheStorager<Token> getCacheStorager0() {
if (cacheStorager == null) {
return new FileCacheStorager<Token>(getTmpdir0());
}
return cacheStorager;
}
public void setCacheStorager(CacheStorager<Token> cacheStorager) {
this.cacheStorager = cacheStorager;
}
public String getCertificateFile() { public String getCertificateFile() {
return certificateFile; return certificateFile;
} }

View File

@ -15,8 +15,9 @@ public abstract class AbstractWeixinSignature implements WeixinSignature {
/** /**
* 是否编码 * 是否编码
* *
* @return * @return 默认false不进行编码
*/ */
@Override
public boolean encoder() { public boolean encoder() {
return false; return false;
} }
@ -24,8 +25,9 @@ public abstract class AbstractWeixinSignature implements WeixinSignature {
/** /**
* 是否转换小写 * 是否转换小写
* *
* @return * @return 默认false不转换小写
*/ */
@Override
public boolean lowerCase() { public boolean lowerCase() {
return false; return false;
} }

View File

@ -1,95 +0,0 @@
package com.foxinmy.weixin4j.token;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.FileUtil;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 用File形式保存Token信息
*
* @className FileTokenStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2015年1月9日
* @since JDK 1.6
*/
public class FileTokenStorager extends TokenStorager {
private final String cachePath;
public FileTokenStorager(String cachePath) {
this.cachePath = cachePath;
}
@Override
public Token lookup(String cacheKey) {
File token_file = new File(String.format("%s/%s.xml", cachePath,
cacheKey));
try {
if (token_file.exists()) {
Token token = XmlStream.fromXML(
new FileInputStream(token_file), Token.class);
if (token.getCreateTime() < 0) {
return token;
}
if ((token.getCreateTime() + (token.getExpiresIn() * 1000l) - ms()) > System
.currentTimeMillis()) {
return token;
}
}
return null;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void caching(String cacheKey, Token token) {
try {
XmlStream.toXML(
token,
new FileOutputStream(new File(String.format("%s/%s.xml",
cachePath, cacheKey))));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public Token evict(String cacheKey) {
Token token = null;
File token_file = new File(String.format("%s/%s.xml", cachePath,
cacheKey));
try {
if (token_file.exists()) {
token = XmlStream.fromXML(new FileInputStream(token_file),
Token.class);
token_file.delete();
}
} catch (IOException e) {
; // ingore
}
return token;
}
@Override
public void clear(final String prefix) {
File[] files = new File(cachePath).listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isFile()
&& file.getName().startsWith(prefix)
&& "xml".equals(FileUtil.getFileExtension(file
.getName()));
}
});
for (File token : files) {
token.delete();
}
}
}

View File

@ -1,51 +0,0 @@
package com.foxinmy.weixin4j.token;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.foxinmy.weixin4j.model.Token;
/**
* 用内存保存Token信息(不推荐使用)
*
* @className MemoryTokenStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2016年1月24日
* @since JDK 1.6
* @see
*/
public class MemoryTokenStorager extends TokenStorager {
private final Map<String, Token> CONMAP;
public MemoryTokenStorager() {
this.CONMAP = new ConcurrentHashMap<String, Token>();
}
@Override
public Token lookup(String cacheKey) {
Token token = this.CONMAP.get(cacheKey);
if (token != null) {
if ((token.getCreateTime() + (token.getExpiresIn() * 1000l) - ms()) > System
.currentTimeMillis()) {
return token;
}
}
return null;
}
@Override
public void caching(String cacheKey, Token token) {
this.CONMAP.put(cacheKey, token);
}
@Override
public Token evict(String cacheKey) {
return this.CONMAP.remove(cacheKey);
}
@Override
public void clear(String prefix) {
this.CONMAP.clear();
}
}

View File

@ -1,13 +0,0 @@
### TOKEN的实现
* TokenCreator 负责创建新的token
* TokenStorager 负责查找已缓存的token或者缓存新的token
* TokenHolder 负责获取token(屏蔽了获取细节)
* FileTokenStorager 是系统默认的token存储策略实现
* RedisTokenStorager 使用redis保存token(需要自行添加客户端包,[jedis](https://github.com/xetorthio/jedis))
* MemcacheTokenStorager 使用memcache保存token(需要自行添加客户端包,[Memcached-Java-Client](https://github.com/gwhalin/Memcached-Java-Client))

View File

@ -1,147 +0,0 @@
package com.foxinmy.weixin4j.token;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import com.foxinmy.weixin4j.model.Token;
/**
* 用Redis保存Token信息(推荐使用)
*
* @className RedisTokenStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2015年1月9日
* @since JDK 1.6
*/
public class RedisTokenStorager extends TokenStorager {
private JedisPool jedisPool;
public final static String HOST = "localhost";
public final static int PORT = 6379;
public final static int MAX_TOTAL = 50;
public final static int MAX_IDLE = 5;
public final static int MAX_WAIT_MILLIS = 3000;
public final static boolean TEST_ON_BORROW = false;
public final static boolean TEST_ON_RETURN = true;
public RedisTokenStorager() {
this(HOST, PORT);
}
public RedisTokenStorager(String host, int port) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(MAX_TOTAL);
jedisPoolConfig.setMaxIdle(MAX_IDLE);
jedisPoolConfig.setMaxWaitMillis(MAX_WAIT_MILLIS);
jedisPoolConfig.setTestOnBorrow(TEST_ON_BORROW);
jedisPoolConfig.setTestOnReturn(TEST_ON_RETURN);
this.jedisPool = new JedisPool(jedisPoolConfig, host, port);
}
public RedisTokenStorager(String host, int port,
JedisPoolConfig jedisPoolConfig) {
this(new JedisPool(jedisPoolConfig, host, port));
}
public RedisTokenStorager(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
@Override
public Token lookup(String cacheKey) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
Map<String, String> map = jedis.hgetAll(cacheKey);
if (map != null && !map.isEmpty()) {
return map2token(map);
}
} finally {
if (jedis != null) {
jedis.close();
}
}
return null;
}
@Override
public void caching(String cacheKey, Token token) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.hmset(cacheKey, token2map(token));
if (token.getExpiresIn() > 0) {
jedis.expire(cacheKey, token.getExpiresIn()
- (int) (ms() / 1000l));
}
} finally {
if (jedis != null) {
jedis.close();
}
}
}
private final static String ACCESSTOKEN_KEY = "accessToken";
private final static String EXPIRESIN_KEY = "expiresIn";
private final static String CREATETIME_KEY = "createTime";
private final static String ORIGINAL_KEY = "originalResult";
protected Map<String, String> token2map(Token token) {
Map<String, String> map = new HashMap<String, String>();
map.put(ACCESSTOKEN_KEY, token.getAccessToken());
map.put(EXPIRESIN_KEY, Integer.toString(token.getExpiresIn()));
map.put(CREATETIME_KEY, Long.toString(token.getCreateTime()));
map.put(ORIGINAL_KEY, token.getOriginalResult());
return map;
}
protected Token map2token(Map<String, String> map) {
Token token = new Token(map.get(ACCESSTOKEN_KEY));
token.setExpiresIn(Integer.parseInt(map.get(EXPIRESIN_KEY)));
token.setCreateTime(Long.parseLong(map.get(CREATETIME_KEY)));
token.setOriginalResult(map.get(ORIGINAL_KEY));
return token;
}
@Override
public Token evict(String cacheKey) {
Token token = lookup(cacheKey);
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
jedis.del(cacheKey);
} finally {
if (jedis != null) {
jedis.close();
}
}
return token;
}
@Override
public void clear(String prefix) {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
Set<String> cacheKeys = jedis.keys(String.format("%s*", prefix));
if (!cacheKeys.isEmpty()) {
Pipeline pipeline = jedis.pipelined();
for (String cacheKey : cacheKeys) {
pipeline.del(cacheKey);
}
pipeline.sync();
}
} finally {
if (jedis != null) {
jedis.close();
}
}
}
}

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.token; package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.cache.CacheCreator;
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
@ -14,21 +15,17 @@ import com.foxinmy.weixin4j.model.Token;
*/ */
public abstract class TokenCreator implements CacheCreator<Token> { public abstract class TokenCreator implements CacheCreator<Token> {
/**
* 缓存KEY前缀
*/
public final static String CACHEKEY_PREFIX = "weixin4j_";
protected final WeixinRequestExecutor weixinExecutor; protected final WeixinRequestExecutor weixinExecutor;
public TokenCreator() { public TokenCreator() {
this.weixinExecutor = new WeixinRequestExecutor(); this.weixinExecutor = new WeixinRequestExecutor();
} }
/**
* 缓存key的前缀
*
* @return 默认为weixin4j_
*/
public String prefix() {
return "weixin4j_";
}
/** /**
* 缓存key:附加key前缀 * 缓存key:附加key前缀
* *
@ -36,7 +33,7 @@ public abstract class TokenCreator implements CacheCreator<Token> {
*/ */
@Override @Override
public String key() { public String key() {
return String.format("%s%s", prefix(), key0()); return String.format("%s%s", CACHEKEY_PREFIX, key0());
} }
/** /**

View File

@ -1,95 +0,0 @@
package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
/**
* 对token的缓存获取
*
* @className TokenHolder
* @author jinyu(foxinmy@gmail.com)
* @date 2015年6月12日
* @since JDK 1.6
* @see TokenCreator
* @see TokenStorager
*/
public class TokenHolder {
/**
* token的创建
*/
private final TokenCreator tokenCreator;
/**
* token的存储
*/
private final TokenStorager tokenStorager;
/**
*
* @param tokenCreator
* token创建器
* @param tokenStorager
* token保存器
*/
public TokenHolder(TokenCreator tokenCreator, TokenStorager tokenStorager) {
this.tokenCreator = tokenCreator;
this.tokenStorager = tokenStorager;
}
/**
* 获取token对象
*
* @return
* @throws WeixinException
*/
public Token getToken() throws WeixinException {
String cacheKey = tokenCreator.key();
Token token = tokenStorager.lookup(cacheKey);
if (token == null) {
token = tokenCreator.create();
tokenStorager.caching(cacheKey, token);
}
return token;
}
/**
* 获取token字符串
*
* @return
* @throws WeixinException
*/
public String getAccessToken() throws WeixinException {
return getToken().getAccessToken();
}
/**
* 手动刷新token
*
* @return 刷新后的token
* @throws WeixinException
*/
public Token refreshToken() throws WeixinException {
String cacheKey = tokenCreator.key();
Token token = tokenCreator.create();
tokenStorager.caching(cacheKey, token);
return token;
}
/**
* 移除token
*
* @return 被移除的token
*/
public Token evictToken() {
String cacheKey = tokenCreator.key();
return tokenStorager.evict(cacheKey);
}
/**
* 清除所有的token(<font color="red">请慎重</font>)
*/
public void clearToken() {
String prefix = tokenCreator.prefix();
tokenStorager.clear(prefix);
}
}

View File

@ -0,0 +1,41 @@
package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.cache.CacheManager;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token;
/**
* 对token的缓存获取
*
* @className TokenManager
* @author jinyu(foxinmy@gmail.com)
* @date 2015年6月12日
* @since JDK 1.6
* @see TokenCreator
* @see com.foxinmy.weixin4j.cache.CacheStorager
*/
public class TokenManager extends CacheManager<Token> {
/**
*
* @param tokenCreator
* 负责微信各种token的创建
* @param cacheStorager
* 负责token的存储
*/
public TokenManager(TokenCreator tokenCreator,
CacheStorager<Token> cacheStorager) {
super(tokenCreator, cacheStorager);
}
/**
* 获取token字符串
*
* @return
* @throws WeixinException
*/
public String getAccessToken() throws WeixinException {
return super.getCache().getAccessToken();
}
}

View File

@ -1,27 +0,0 @@
package com.foxinmy.weixin4j.token;
import com.foxinmy.weixin4j.model.Token;
/**
* Token的存储
*
* @className TokenStorager
* @author jinyu(foxinmy@gmail.com)
* @date 2014年9月27日
* @since JDK 1.6
* @see com.foxinmy.weixin4j.model.Token
* @see MemoryTokenStorager
* @see FileTokenStorager
* @see RedisTokenStorager
* @see MemcacheTokenStorager
*/
public abstract class TokenStorager implements CacheStorager<Token> {
/**
* 考虑到临界情况,实际token的有效时间减去该毫秒数
*
* @return 默认为60秒
*/
public long ms() {
return 60 * 1000l;
}
}

View File

@ -43,6 +43,17 @@ public class Article implements Serializable {
@XmlElement(name = "Url") @XmlElement(name = "Url")
private String url; private String url;
/**
*
* @param title
* 标题
* @param desc
* 描述
* @param picUrl
* 图片链接
* @param url
* 跳转URL
*/
@JSONCreator @JSONCreator
public Article(@JSONField(name = "title") String title, public Article(@JSONField(name = "title") String title,
@JSONField(name = "desc") String desc, @JSONField(name = "desc") String desc,

View File

@ -2,12 +2,12 @@ package com.foxinmy.weixin4j.tuple;
import java.io.Serializable; import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
/** /**
* 群发消息图文(消息内容存储在微信后台) * 群发消息图文(消息内容存储在微信后台)
* *
* @className MpArticle
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年4月26日 * @date 2014年4月26日
* @since JDK 1.6 * @since JDK 1.6
@ -22,7 +22,7 @@ public class MpArticle implements Serializable {
@JSONField(name = "thumb_media_id") @JSONField(name = "thumb_media_id")
private String thumbMediaId; private String thumbMediaId;
/** /**
* 图文消息的封面图片的地址第三方开发者也可以使用这个URL下载图片到自己服务器中然后显示在自己网站上 * 图文消息的封面图片的地址(不一定有请关注thumbMediaId)
*/ */
@JSONField(name = "thumb_url") @JSONField(name = "thumb_url")
private String thumbUrl; private String thumbUrl;
@ -34,6 +34,10 @@ public class MpArticle implements Serializable {
* 图文消息的标题 非空 * 图文消息的标题 非空
*/ */
private String title; private String title;
/**
* 图文页的URL 获取图文消息时
*/
private String url;
/** /**
* 在图文消息页面点击阅读原文后的页面 可为空 * 在图文消息页面点击阅读原文后的页面 可为空
*/ */
@ -52,50 +56,40 @@ public class MpArticle implements Serializable {
*/ */
@JSONField(name = "show_cover_pic") @JSONField(name = "show_cover_pic")
private String showCoverPic; private String showCoverPic;
/**
* 正文的URL 可为空
*/
@JSONField(name = "content_url")
private String contentUrl;
/**
* 封面图片的URL 可为空
*/
@JSONField(name = "cover_url")
private String coverUrl;
protected MpArticle() {
}
/**
* @param thumbMediaId
* 缩略图
* @param title
* 标题
* @param content
* 内容
*/
public MpArticle(String thumbMediaId, String title, String content) { public MpArticle(String thumbMediaId, String title, String content) {
this.thumbMediaId = thumbMediaId; this.thumbMediaId = thumbMediaId;
this.title = title; this.title = title;
this.content = content; this.content = content;
} }
@JSONCreator
public MpArticle(@JSONField(name = "thumbMediaId") String thumbMediaId,
@JSONField(name = "thumbUrl") String thumbUrl,
@JSONField(name = "author") String author,
@JSONField(name = "title") String title,
@JSONField(name = "sourceUrl") String sourceUrl,
@JSONField(name = "content") String content,
@JSONField(name = "digest") String digest,
@JSONField(name = "showCoverPic") String showCoverPic,
@JSONField(name = "contentUrl") String contentUrl,
@JSONField(name = "coverUrl") String coverUrl) {
this.thumbMediaId = thumbMediaId;
this.thumbUrl = thumbUrl;
this.author = author;
this.title = title;
this.sourceUrl = sourceUrl;
this.content = content;
this.digest = digest;
this.showCoverPic = showCoverPic;
this.contentUrl = contentUrl;
this.coverUrl = coverUrl;
}
public String getThumbMediaId() { public String getThumbMediaId() {
return thumbMediaId; return thumbMediaId;
} }
public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}
public String getThumbUrl() {
return thumbUrl;
}
public void setThumbUrl(String thumbUrl) {
this.thumbUrl = thumbUrl;
}
public String getAuthor() { public String getAuthor() {
return author; return author;
} }
@ -108,6 +102,18 @@ public class MpArticle implements Serializable {
return title; return title;
} }
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getSourceUrl() { public String getSourceUrl() {
return sourceUrl; return sourceUrl;
} }
@ -120,6 +126,10 @@ public class MpArticle implements Serializable {
return content; return content;
} }
public void setContent(String content) {
this.content = content;
}
public String getDigest() { public String getDigest() {
return digest; return digest;
} }
@ -132,36 +142,25 @@ public class MpArticle implements Serializable {
return showCoverPic; return showCoverPic;
} }
public void setShowCoverPic(String showCoverPic) {
this.showCoverPic = showCoverPic;
}
public void setShowCoverPic(boolean showCoverPic) { public void setShowCoverPic(boolean showCoverPic) {
this.showCoverPic = showCoverPic ? "1" : "0"; this.showCoverPic = showCoverPic ? "1" : "0";
} }
public String getContentUrl() { @JSONField(serialize = false)
return contentUrl; public boolean getFormatShowCoverPic() {
} return this.showCoverPic != null && this.showCoverPic.equals("1");
public void setContentUrl(String contentUrl) {
this.contentUrl = contentUrl;
}
public String getCoverUrl() {
return coverUrl;
}
public void setCoverUrl(String coverUrl) {
this.coverUrl = coverUrl;
}
public String getThumbUrl() {
return thumbUrl;
} }
@Override @Override
public String toString() { public String toString() {
return "MpArticle [thumbMediaId=" + thumbMediaId + ",thumbUrl=" return "MpArticle [thumbMediaId=" + thumbMediaId + ", thumbUrl="
+ thumbUrl + ", author=" + author + ", title=" + title + thumbUrl + ", author=" + author + ", title=" + title
+ ", sourceUrl=" + sourceUrl + ", content=" + content + ", sourceUrl=" + sourceUrl + ", content=" + content
+ ", digest=" + digest + ", showCoverPic=" + showCoverPic + ", url=" + url + ", digest=" + digest + ", showCoverPic="
+ ", contentUrl=" + contentUrl + ", coverUrl=" + coverUrl + "]"; + showCoverPic + "]";
} }
} }

View File

@ -1,19 +1,21 @@
package com.foxinmy.weixin4j.tuple; package com.foxinmy.weixin4j.tuple;
import java.util.Arrays;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlTransient;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
/** /**
* 图文对象(mpnews消息与news消息类似不同的是图文消息内容存储在微信后台并且支持保密选项每个应用每天最多可以发送100次) * 图文对象(mpnews消息与news消息类似不同的是图文消息内容存储在微信后台并且支持保密选项每个应用每天最多可以发送100次)
* <p> * <p>
* <font color="red">可用于群发消息(其中mediaId与articles请至少保持一个有值)企业号的客服消息</font> * <font color="red">可用于公众平台的群发消息客服消息</font>
* </p> * </p>
* <li>当用于发送公众平台的群发消息和客服消息时其中mediaId与articles请至少保持一个有值 <li>
* 当用于发送企业号的客服消息时其中articles必须有值
* *
* @className MpNews * @className MpNews
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
@ -47,16 +49,35 @@ public class MpNews implements MassTuple, NotifyTuple {
@XmlTransient @XmlTransient
private LinkedList<MpArticle> articles; private LinkedList<MpArticle> articles;
public MpNews() { /**
this(null); * 群发消息客服消息 预先上传List#MpArticle得到mediaId
} *
* @param mediaId
@JSONCreator * 群发素材的媒体ID
public MpNews(@JSONField(name = "mediaId") String mediaId) { */
public MpNews(String mediaId) {
this.mediaId = mediaId; this.mediaId = mediaId;
this.articles = new LinkedList<MpArticle>(); this.articles = new LinkedList<MpArticle>();
} }
/**
* 群发消息 自动上传List#MpArticle得到mediaId
*
* @param articles
* 文章列表
*/
public MpNews(MpArticle... articles) {
this.articles = new LinkedList<MpArticle>(Arrays.asList(articles));
}
/**
* @param thumbMediaId
* 缩略图
* @param title
* 标题
* @param content
* 内容
*/
public MpNews addArticle(String thumbMediaId, String title, String content) { public MpNews addArticle(String thumbMediaId, String title, String content) {
return addArticle(new MpArticle(thumbMediaId, title, content)); return addArticle(new MpArticle(thumbMediaId, title, content));
} }

View File

@ -55,10 +55,32 @@ public class Music implements NotifyTuple {
@XmlElement(name = "ThumbMediaId") @XmlElement(name = "ThumbMediaId")
private String thumbMediaId; private String thumbMediaId;
/**
*
* @param musicUrl
* 音乐链接
* @param hqMusicUrl
* 高品质音乐链接
* @param thumbMediaId
* 缩略图
*/
public Music(String musicUrl, String hqMusicUrl, String thumbMediaId) { public Music(String musicUrl, String hqMusicUrl, String thumbMediaId) {
this(null, null, musicUrl, hqMusicUrl, thumbMediaId); this(null, null, musicUrl, hqMusicUrl, thumbMediaId);
} }
/**
*
* @param title
* 标题
* @param desc
* 描述
* @param musicUrl
* 音乐链接
* @param hqMusicUrl
* 高品质音乐链接
* @param thumbMediaId
* 缩略图
*/
public Music(@JSONField(name = "title") String title, public Music(@JSONField(name = "title") String title,
@JSONField(name = "desc") String desc, @JSONField(name = "desc") String desc,
@JSONField(name = "musicUrl") String musicUrl, @JSONField(name = "musicUrl") String musicUrl,

View File

@ -47,6 +47,17 @@ public class News implements NotifyTuple {
this.articles = new LinkedList<Article>(); this.articles = new LinkedList<Article>();
} }
/**
*
* @param title
* 标题
* @param desc
* 描述
* @param picUrl
* 图片链接
* @param url
* 跳转URL
*/
public News addArticle(String title, String desc, String picUrl, String url) { public News addArticle(String title, String desc, String picUrl, String url) {
return addArticle(new Article(title, desc, picUrl, url)); return addArticle(new Article(title, desc, picUrl, url));
} }

View File

@ -65,6 +65,18 @@ public class Video implements NotifyTuple {
this(mediaId, null, title, desc); this(mediaId, null, title, desc);
} }
/**
* 公众平台发送视频消息
*
* @param mediaId
* 视频媒体文件id可以调用上传临时素材或者永久素材接口获取
* @param thumbMediaId
* 视频缩略图
* @param title
* 视频标题
* @param desc
* 视频描述
*/
@JSONCreator @JSONCreator
public Video(@JSONField(name = "mediaId") String mediaId, public Video(@JSONField(name = "mediaId") String mediaId,
@JSONField(name = "thumbMediaId") String thumbMediaId, @JSONField(name = "thumbMediaId") String thumbMediaId,

View File

@ -0,0 +1,339 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.foxinmy.weixin4j.util;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamClass;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* <p>Assists with the serialization process and performs additional functionality based
* on serialization.</p>
*
* <ul>
* <li>Deep clone using serialization
* <li>Serialize managing finally and IOException
* <li>Deserialize managing finally and IOException
* </ul>
*
* <p>This class throws exceptions for invalid {@code null} inputs.
* Each method documents its behaviour in more detail.</p>
*
* <p>#ThreadSafe#</p>
* @since 1.0
* @version $Id: SerializationUtils.java 1583482 2014-03-31 22:54:57Z niallp $
*/
public class SerializationUtils {
/**
* <p>SerializationUtils instances should NOT be constructed in standard programming.
* Instead, the class should be used as {@code SerializationUtils.clone(object)}.</p>
*
* <p>This constructor is public to permit tools that require a JavaBean instance
* to operate.</p>
* @since 2.0
*/
public SerializationUtils() {
super();
}
// Clone
//-----------------------------------------------------------------------
/**
* <p>Deep clone an {@code Object} using serialization.</p>
*
* <p>This is many times slower than writing clone methods by hand
* on all objects in your object graph. However, for complex object
* graphs, or for those that don't support deep cloning this can
* be a simple alternative implementation. Of course all the objects
* must be {@code Serializable}.</p>
*
* @param <T> the type of the object involved
* @param object the {@code Serializable} object to clone
* @return the cloned object
* @throws SerializationException (runtime) if the serialization fails
*/
public static <T extends Serializable> T clone(final T object) {
if (object == null) {
return null;
}
final byte[] objectData = serialize(object);
final ByteArrayInputStream bais = new ByteArrayInputStream(objectData);
ClassLoaderAwareObjectInputStream in = null;
try {
// stream closed in the finally
in = new ClassLoaderAwareObjectInputStream(bais, object.getClass().getClassLoader());
/*
* when we serialize and deserialize an object,
* it is reasonable to assume the deserialized object
* is of the same type as the original serialized object
*/
@SuppressWarnings("unchecked") // see above
final
T readObject = (T) in.readObject();
return readObject;
} catch (final ClassNotFoundException ex) {
throw new RuntimeException("ClassNotFoundException while reading cloned object data", ex);
} catch (final IOException ex) {
throw new RuntimeException("IOException while reading cloned object data", ex);
} finally {
try {
if (in != null) {
in.close();
}
} catch (final IOException ex) {
throw new RuntimeException("IOException on closing cloned object data InputStream.", ex);
}
}
}
/**
* Performs a serialization roundtrip. Serializes and deserializes the given object, great for testing objects that
* implement {@link Serializable}.
*
* @param <T>
* the type of the object involved
* @param msg
* the object to roundtrip
* @return the serialized and deseralized object
* @since 3.3
*/
public static <T extends Serializable> T roundtrip(final T msg) {
return SerializationUtils.deserialize(SerializationUtils.serialize(msg));
}
// Serialize
//-----------------------------------------------------------------------
/**
* <p>Serializes an {@code Object} to the specified stream.</p>
*
* <p>The stream will be closed once the object is written.
* This avoids the need for a finally clause, and maybe also exception
* handling, in the application code.</p>
*
* <p>The stream passed in is not buffered internally within this method.
* This is the responsibility of your application if desired.</p>
*
* @param obj the object to serialize to bytes, may be null
* @param outputStream the stream to write to, must not be null
* @throws IllegalArgumentException if {@code outputStream} is {@code null}
* @throws SerializationException (runtime) if the serialization fails
*/
public static void serialize(final Serializable obj, final OutputStream outputStream) {
if (outputStream == null) {
throw new IllegalArgumentException("The OutputStream must not be null");
}
ObjectOutputStream out = null;
try {
// stream closed in the finally
out = new ObjectOutputStream(outputStream);
out.writeObject(obj);
} catch (final IOException ex) {
throw new RuntimeException(ex);
} finally {
try {
if (out != null) {
out.close();
}
} catch (final IOException ex) { // NOPMD
// ignore close exception
}
}
}
/**
* <p>Serializes an {@code Object} to a byte array for
* storage/serialization.</p>
*
* @param obj the object to serialize to bytes
* @return a byte[] with the converted Serializable
* @throws SerializationException (runtime) if the serialization fails
*/
public static byte[] serialize(final Serializable obj) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream(512);
serialize(obj, baos);
return baos.toByteArray();
}
// Deserialize
//-----------------------------------------------------------------------
/**
* <p>
* Deserializes an {@code Object} from the specified stream.
* </p>
*
* <p>
* The stream will be closed once the object is written. This avoids the need for a finally clause, and maybe also
* exception handling, in the application code.
* </p>
*
* <p>
* The stream passed in is not buffered internally within this method. This is the responsibility of your
* application if desired.
* </p>
*
* <p>
* If the call site incorrectly types the return value, a {@link ClassCastException} is thrown from the call site.
* Without Generics in this declaration, the call site must type cast and can cause the same ClassCastException.
* Note that in both cases, the ClassCastException is in the call site, not in this method.
* </p>
*
* @param <T> the object type to be deserialized
* @param inputStream
* the serialized object input stream, must not be null
* @return the deserialized object
* @throws IllegalArgumentException
* if {@code inputStream} is {@code null}
* @throws SerializationException
* (runtime) if the serialization fails
*/
public static <T> T deserialize(final InputStream inputStream) {
if (inputStream == null) {
throw new IllegalArgumentException("The InputStream must not be null");
}
ObjectInputStream in = null;
try {
// stream closed in the finally
in = new ObjectInputStream(inputStream);
@SuppressWarnings("unchecked") // may fail with CCE if serialised form is incorrect
final T obj = (T) in.readObject();
return obj;
} catch (final ClassCastException ex) {
throw new RuntimeException(ex);
} catch (final ClassNotFoundException ex) {
throw new RuntimeException(ex);
} catch (final IOException ex) {
throw new RuntimeException(ex);
} finally {
try {
if (in != null) {
in.close();
}
} catch (final IOException ex) { // NOPMD
// ignore close exception
}
}
}
/**
* <p>
* Deserializes a single {@code Object} from an array of bytes.
* </p>
*
* <p>
* If the call site incorrectly types the return value, a {@link ClassCastException} is thrown from the call site.
* Without Generics in this declaration, the call site must type cast and can cause the same ClassCastException.
* Note that in both cases, the ClassCastException is in the call site, not in this method.
* </p>
*
* @param <T> the object type to be deserialized
* @param objectData
* the serialized object, must not be null
* @return the deserialized object
* @throws IllegalArgumentException
* if {@code objectData} is {@code null}
* @throws SerializationException
* (runtime) if the serialization fails
*/
public static <T> T deserialize(final byte[] objectData) {
if (objectData == null) {
throw new IllegalArgumentException("The byte[] must not be null");
}
return SerializationUtils.<T>deserialize(new ByteArrayInputStream(objectData));
}
/**
* <p>Custom specialization of the standard JDK {@link java.io.ObjectInputStream}
* that uses a custom <code>ClassLoader</code> to resolve a class.
* If the specified <code>ClassLoader</code> is not able to resolve the class,
* the context classloader of the current thread will be used.
* This way, the standard deserialization work also in web-application
* containers and application servers, no matter in which of the
* <code>ClassLoader</code> the particular class that encapsulates
* serialization/deserialization lives. </p>
*
* <p>For more in-depth information about the problem for which this
* class here is a workaround, see the JIRA issue LANG-626. </p>
*/
static class ClassLoaderAwareObjectInputStream extends ObjectInputStream {
private static final Map<String, Class<?>> primitiveTypes =
new HashMap<String, Class<?>>();
private final ClassLoader classLoader;
/**
* Constructor.
* @param in The <code>InputStream</code>.
* @param classLoader classloader to use
* @throws IOException if an I/O error occurs while reading stream header.
* @see java.io.ObjectInputStream
*/
public ClassLoaderAwareObjectInputStream(final InputStream in, final ClassLoader classLoader) throws IOException {
super(in);
this.classLoader = classLoader;
primitiveTypes.put("byte", byte.class);
primitiveTypes.put("short", short.class);
primitiveTypes.put("int", int.class);
primitiveTypes.put("long", long.class);
primitiveTypes.put("float", float.class);
primitiveTypes.put("double", double.class);
primitiveTypes.put("boolean", boolean.class);
primitiveTypes.put("char", char.class);
primitiveTypes.put("void", void.class);
}
/**
* Overriden version that uses the parametrized <code>ClassLoader</code> or the <code>ClassLoader</code>
* of the current <code>Thread</code> to resolve the class.
* @param desc An instance of class <code>ObjectStreamClass</code>.
* @return A <code>Class</code> object corresponding to <code>desc</code>.
* @throws IOException Any of the usual Input/Output exceptions.
* @throws ClassNotFoundException If class of a serialized object cannot be found.
*/
@Override
protected Class<?> resolveClass(final ObjectStreamClass desc) throws IOException, ClassNotFoundException {
final String name = desc.getName();
try {
return Class.forName(name, false, classLoader);
} catch (final ClassNotFoundException ex) {
try {
return Class.forName(name, false, Thread.currentThread().getContextClassLoader());
} catch (final ClassNotFoundException cnfe) {
final Class<?> cls = primitiveTypes.get(name);
if (cls != null) {
return cls;
} else {
throw cnfe;
}
}
}
}
}
}

View File

@ -4,6 +4,7 @@ import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.model.WeixinAccount;
/** /**
@ -23,7 +24,7 @@ public class Weixin4jConfigUtil {
CLASSPATH_VALUE = Thread.currentThread().getContextClassLoader() CLASSPATH_VALUE = Thread.currentThread().getContextClassLoader()
.getResource("").getPath(); .getResource("").getPath();
try { try {
weixinBundle = ResourceBundle.getBundle("weixin4j"); weixinBundle = ResourceBundle.getBundle(Consts.WEIXIN4J);
} catch (MissingResourceException e) { } catch (MissingResourceException e) {
; ;
} }

View File

@ -84,5 +84,10 @@
<version>1.9.1</version> <version>1.9.1</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.9.1.RELEASE</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -51,7 +51,7 @@ import com.foxinmy.weixin4j.mp.type.DatacubeType;
import com.foxinmy.weixin4j.mp.type.IndustryType; import com.foxinmy.weixin4j.mp.type.IndustryType;
import com.foxinmy.weixin4j.mp.type.Lang; import com.foxinmy.weixin4j.mp.type.Lang;
import com.foxinmy.weixin4j.setting.Weixin4jSettings; import com.foxinmy.weixin4j.setting.Weixin4jSettings;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MassTuple; import com.foxinmy.weixin4j.tuple.MassTuple;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.MpVideo; import com.foxinmy.weixin4j.tuple.MpVideo;
@ -121,7 +121,7 @@ public class WeixinProxy {
/** /**
* token实现 * token实现
*/ */
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
/** /**
* 配置信息 * 配置信息
*/ */
@ -141,9 +141,9 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.setting.Weixin4jSettings * @see com.foxinmy.weixin4j.setting.Weixin4jSettings
*/ */
public WeixinProxy(Weixin4jSettings settings) { public WeixinProxy(Weixin4jSettings settings) {
this(new TokenHolder(new WeixinTokenCreator(settings.getAccount() this(new TokenManager(new WeixinTokenCreator(settings.getAccount()
.getId(), settings.getAccount().getSecret()), .getId(), settings.getAccount().getSecret()),
settings.getTokenStorager0())); settings.getCacheStorager0()));
this.settings = settings; this.settings = settings;
} }
@ -151,22 +151,22 @@ public class WeixinProxy {
* 注意TokenCreator 需为 <font color="red">WeixinTokenCreator</font> * 注意TokenCreator 需为 <font color="red">WeixinTokenCreator</font>
* *
* @see com.foxinmy.weixin4j.mp.token.WeixinTokenCreator * @see com.foxinmy.weixin4j.mp.token.WeixinTokenCreator
* @param tokenHolder * @param tokenManager
*/ */
private WeixinProxy(TokenHolder tokenHolder) { private WeixinProxy(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
this.mediaApi = new MediaApi(tokenHolder); this.mediaApi = new MediaApi(tokenManager);
this.notifyApi = new NotifyApi(tokenHolder); this.notifyApi = new NotifyApi(tokenManager);
this.customApi = new CustomApi(tokenHolder); this.customApi = new CustomApi(tokenManager);
this.massApi = new MassApi(tokenHolder); this.massApi = new MassApi(tokenManager);
this.userApi = new UserApi(tokenHolder); this.userApi = new UserApi(tokenManager);
this.groupApi = new GroupApi(tokenHolder); this.groupApi = new GroupApi(tokenManager);
this.menuApi = new MenuApi(tokenHolder); this.menuApi = new MenuApi(tokenManager);
this.qrApi = new QrApi(tokenHolder); this.qrApi = new QrApi(tokenManager);
this.tmplApi = new TmplApi(tokenHolder); this.tmplApi = new TmplApi(tokenManager);
this.helperApi = new HelperApi(tokenHolder); this.helperApi = new HelperApi(tokenManager);
this.dataApi = new DataApi(tokenHolder); this.dataApi = new DataApi(tokenManager);
this.tagApi = new TagApi(tokenHolder); this.tagApi = new TagApi(tokenManager);
} }
/** /**
@ -179,25 +179,25 @@ public class WeixinProxy {
} }
/** /**
* token获取 * token管理
* *
* @return * @return
*/ */
public TokenHolder getTokenHolder() { public TokenManager getTokenManager() {
return this.tokenHolder; return this.tokenManager;
} }
/** /**
* 获取JSSDK Ticket的tokenHolder * 获取JSSDK Ticket的tokenManager
* *
* @param ticketType * @param ticketType
* 票据类型 * 票据类型
* @return * @return
*/ */
public TokenHolder getTicketHolder(TicketType ticketType) { public TokenManager getTicketManager(TicketType ticketType) {
return new TokenHolder(new WeixinTicketCreator(getWeixinAccount() return new TokenManager(new WeixinTicketCreator(getWeixinAccount()
.getId(), ticketType, this.tokenHolder), .getId(), ticketType, this.tokenManager),
this.settings.getTokenStorager0()); this.settings.getCacheStorager0());
} }
/** /**

View File

@ -20,7 +20,7 @@ import com.foxinmy.weixin4j.mp.model.KfAccount;
import com.foxinmy.weixin4j.mp.model.KfChatRecord; import com.foxinmy.weixin4j.mp.model.KfChatRecord;
import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.mp.model.KfSession;
import com.foxinmy.weixin4j.mp.model.KfSession.KfSessionCounter; import com.foxinmy.weixin4j.mp.model.KfSession.KfSessionCounter;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.DigestUtil;
import com.foxinmy.weixin4j.util.FileUtil; import com.foxinmy.weixin4j.util.FileUtil;
import com.foxinmy.weixin4j.util.ObjectId; import com.foxinmy.weixin4j.util.ObjectId;
@ -37,10 +37,10 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class CustomApi extends MpApi { public class CustomApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public CustomApi(TokenHolder tokenHolder) { public CustomApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -62,7 +62,7 @@ public class CustomApi extends MpApi {
public List<KfChatRecord> getKfChatRecord(Date startTime, Date endTime, Pageable pageable) throws WeixinException { public List<KfChatRecord> getKfChatRecord(Date startTime, Date endTime, Pageable pageable) throws WeixinException {
List<KfChatRecord> records = new ArrayList<KfChatRecord>(); List<KfChatRecord> records = new ArrayList<KfChatRecord>();
String kf_chatrecord_uri = getRequestUri("kf_chatrecord_uri"); String kf_chatrecord_uri = getRequestUri("kf_chatrecord_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("starttime", startTime.getTime() / 1000); obj.put("starttime", startTime.getTime() / 1000);
obj.put("endtime", endTime.getTime() / 1000); obj.put("endtime", endTime.getTime() / 1000);
@ -100,7 +100,7 @@ public class CustomApi extends MpApi {
* @throws WeixinException * @throws WeixinException
*/ */
public List<KfAccount> listKfAccount(boolean isOnline) throws WeixinException { public List<KfAccount> listKfAccount(boolean isOnline) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String text = ""; String text = "";
if (isOnline) { if (isOnline) {
String kf_onlinelist_uri = getRequestUri("kf_onlinelist_uri"); String kf_onlinelist_uri = getRequestUri("kf_onlinelist_uri");
@ -136,7 +136,7 @@ public class CustomApi extends MpApi {
obj.put("nickname", name); obj.put("nickname", name);
obj.put("password", DigestUtil.MD5(pwd)); obj.put("password", DigestUtil.MD5(pwd));
String kf_create_uri = getRequestUri("kf_create_uri"); String kf_create_uri = getRequestUri("kf_create_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format(kf_create_uri, token.getAccessToken()), WeixinResponse response = weixinExecutor.post(String.format(kf_create_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -164,7 +164,7 @@ public class CustomApi extends MpApi {
obj.put("nickname", name); obj.put("nickname", name);
obj.put("password", DigestUtil.MD5(pwd)); obj.put("password", DigestUtil.MD5(pwd));
String kf_update_uri = getRequestUri("kf_update_uri"); String kf_update_uri = getRequestUri("kf_update_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format(kf_update_uri, token.getAccessToken()), WeixinResponse response = weixinExecutor.post(String.format(kf_update_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -190,7 +190,7 @@ public class CustomApi extends MpApi {
obj.put("kf_account", kfAccount); obj.put("kf_account", kfAccount);
obj.put("invite_wx", inviteAccount); obj.put("invite_wx", inviteAccount);
String kf_invite_uri = getRequestUri("kf_invite_uri"); String kf_invite_uri = getRequestUri("kf_invite_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format(kf_invite_uri, token.getAccessToken()), WeixinResponse response = weixinExecutor.post(String.format(kf_invite_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -218,7 +218,7 @@ public class CustomApi extends MpApi {
if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) { if (StringUtil.isBlank(FileUtil.getFileExtension(fileName))) {
fileName = String.format("%s.jpg", fileName); fileName = String.format("%s.jpg", fileName);
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kf_avatar_uri = getRequestUri("kf_avatar_uri"); String kf_avatar_uri = getRequestUri("kf_avatar_uri");
WeixinResponse response = weixinExecutor.post(String.format(kf_avatar_uri, token.getAccessToken(), accountId), WeixinResponse response = weixinExecutor.post(String.format(kf_avatar_uri, token.getAccessToken(), accountId),
new FormBodyPart("media", new InputStreamBody(is, ContentType.IMAGE_JPG.getMimeType(), fileName))); new FormBodyPart("media", new InputStreamBody(is, ContentType.IMAGE_JPG.getMimeType(), fileName)));
@ -238,7 +238,7 @@ public class CustomApi extends MpApi {
* 删除客服账号</a> * 删除客服账号</a>
*/ */
public JsonResult deleteKfAccount(String id) throws WeixinException { public JsonResult deleteKfAccount(String id) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kf_delete_uri = getRequestUri("kf_delete_uri"); String kf_delete_uri = getRequestUri("kf_delete_uri");
WeixinResponse response = weixinExecutor.get(String.format(kf_delete_uri, token.getAccessToken(), id)); WeixinResponse response = weixinExecutor.get(String.format(kf_delete_uri, token.getAccessToken(), id));
@ -265,7 +265,7 @@ public class CustomApi extends MpApi {
* 创建会话</a> * 创建会话</a>
*/ */
public JsonResult createKfSession(String userOpenId, String kfAccount, String text) throws WeixinException { public JsonResult createKfSession(String userOpenId, String kfAccount, String text) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kfsession_create_uri = getRequestUri("kfsession_create_uri"); String kfsession_create_uri = getRequestUri("kfsession_create_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("openid", userOpenId); obj.put("openid", userOpenId);
@ -293,7 +293,7 @@ public class CustomApi extends MpApi {
* 关闭会话</a> * 关闭会话</a>
*/ */
public JsonResult closeKfSession(String userOpenId, String kfAccount, String text) throws WeixinException { public JsonResult closeKfSession(String userOpenId, String kfAccount, String text) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kfsession_close_uri = getRequestUri("kfsession_close_uri"); String kfsession_close_uri = getRequestUri("kfsession_close_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("openid", userOpenId); obj.put("openid", userOpenId);
@ -318,7 +318,7 @@ public class CustomApi extends MpApi {
* 获取会话状态</a> * 获取会话状态</a>
*/ */
public KfSession getKfSession(String userOpenId) throws WeixinException { public KfSession getKfSession(String userOpenId) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kfsession_get_uri = getRequestUri("kfsession_get_uri"); String kfsession_get_uri = getRequestUri("kfsession_get_uri");
WeixinResponse response = weixinExecutor WeixinResponse response = weixinExecutor
.get(String.format(kfsession_get_uri, token.getAccessToken(), userOpenId)); .get(String.format(kfsession_get_uri, token.getAccessToken(), userOpenId));
@ -342,7 +342,7 @@ public class CustomApi extends MpApi {
* 获取客服的会话列表</a> * 获取客服的会话列表</a>
*/ */
public List<KfSession> listKfSession(String kfAccount) throws WeixinException { public List<KfSession> listKfSession(String kfAccount) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kfsession_list_uri = getRequestUri("kfsession_list_uri"); String kfsession_list_uri = getRequestUri("kfsession_list_uri");
WeixinResponse response = weixinExecutor WeixinResponse response = weixinExecutor
.get(String.format(kfsession_list_uri, token.getAccessToken(), kfAccount)); .get(String.format(kfsession_list_uri, token.getAccessToken(), kfAccount));
@ -364,7 +364,7 @@ public class CustomApi extends MpApi {
* 获取客服的会话列表</a> * 获取客服的会话列表</a>
*/ */
public KfSessionCounter listKfWaitSession() throws WeixinException { public KfSessionCounter listKfWaitSession() throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String kfsession_wait_uri = getRequestUri("kfsession_wait_uri"); String kfsession_wait_uri = getRequestUri("kfsession_wait_uri");
WeixinResponse response = weixinExecutor.get(String.format(kfsession_wait_uri, token.getAccessToken())); WeixinResponse response = weixinExecutor.get(String.format(kfsession_wait_uri, token.getAccessToken()));

View File

@ -10,7 +10,7 @@ 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.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.type.DatacubeType; import com.foxinmy.weixin4j.mp.type.DatacubeType;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.DateUtil;
/** /**
@ -27,10 +27,10 @@ import com.foxinmy.weixin4j.util.DateUtil;
* @see * @see
*/ */
public class DataApi extends MpApi { public class DataApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public DataApi(TokenHolder tokenHolder) { public DataApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -119,7 +119,7 @@ public class DataApi extends MpApi {
public List<?> datacube(DatacubeType datacubeType, Date beginDate, public List<?> datacube(DatacubeType datacubeType, Date beginDate,
Date endDate) throws WeixinException { Date endDate) throws WeixinException {
String datacube_uri = getRequestUri("datacube_uri"); String datacube_uri = getRequestUri("datacube_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("begin_date", DateUtil.fortmat2yyyy_MM_dd(beginDate)); obj.put("begin_date", DateUtil.fortmat2yyyy_MM_dd(beginDate));
obj.put("end_date", DateUtil.fortmat2yyyy_MM_dd(endDate)); obj.put("end_date", DateUtil.fortmat2yyyy_MM_dd(endDate));

View File

@ -9,7 +9,7 @@ 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.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.Group; import com.foxinmy.weixin4j.mp.model.Group;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 分组相关API * 分组相关API
@ -22,10 +22,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
*/ */
public class GroupApi extends MpApi { public class GroupApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public GroupApi(TokenHolder tokenHolder) { public GroupApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -42,7 +42,7 @@ public class GroupApi extends MpApi {
*/ */
public Group createGroup(String name) throws WeixinException { public Group createGroup(String name) throws WeixinException {
String group_create_uri = getRequestUri("group_create_uri"); String group_create_uri = getRequestUri("group_create_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
Group group = new Group(name); Group group = new Group(name);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(group_create_uri, token.getAccessToken()), String.format(group_create_uri, token.getAccessToken()),
@ -62,7 +62,7 @@ public class GroupApi extends MpApi {
*/ */
public List<Group> getGroups() throws WeixinException { public List<Group> getGroups() throws WeixinException {
String group_get_uri = getRequestUri("group_get_uri"); String group_get_uri = getRequestUri("group_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(group_get_uri, WeixinResponse response = weixinExecutor.get(String.format(group_get_uri,
token.getAccessToken())); token.getAccessToken()));
@ -83,7 +83,7 @@ public class GroupApi extends MpApi {
*/ */
public int getGroupByOpenId(String openId) throws WeixinException { public int getGroupByOpenId(String openId) throws WeixinException {
String group_getid_uri = getRequestUri("group_getid_uri"); String group_getid_uri = getRequestUri("group_getid_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(group_getid_uri, token.getAccessToken()), String.format(group_getid_uri, token.getAccessToken()),
String.format("{\"openid\":\"%s\"}", openId)); String.format("{\"openid\":\"%s\"}", openId));
@ -107,7 +107,7 @@ public class GroupApi extends MpApi {
public JsonResult modifyGroup(int groupId, String name) public JsonResult modifyGroup(int groupId, String name)
throws WeixinException { throws WeixinException {
String group_modify_uri = getRequestUri("group_modify_uri"); String group_modify_uri = getRequestUri("group_modify_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
Group group = new Group(groupId, name); Group group = new Group(groupId, name);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
@ -131,7 +131,7 @@ public class GroupApi extends MpApi {
public JsonResult moveGroup(int groupId, String openId) public JsonResult moveGroup(int groupId, String openId)
throws WeixinException { throws WeixinException {
String group_move_uri = getRequestUri("group_move_uri"); String group_move_uri = getRequestUri("group_move_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format(group_move_uri, WeixinResponse response = weixinExecutor.post(String.format(group_move_uri,
token.getAccessToken()), String.format( token.getAccessToken()), String.format(
"{\"openid\":\"%s\",\"to_groupid\":%d}", openId, groupId)); "{\"openid\":\"%s\",\"to_groupid\":%d}", openId, groupId));
@ -154,7 +154,7 @@ public class GroupApi extends MpApi {
public JsonResult moveGroup(int groupId, String... openIds) public JsonResult moveGroup(int groupId, String... openIds)
throws WeixinException { throws WeixinException {
String group_batchmove_uri = getRequestUri("group_batchmove_uri"); String group_batchmove_uri = getRequestUri("group_batchmove_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("to_groupid", groupId); obj.put("to_groupid", groupId);
obj.put("openid_list", openIds); obj.put("openid_list", openIds);
@ -177,7 +177,7 @@ public class GroupApi extends MpApi {
*/ */
public JsonResult deleteGroup(int groupId) throws WeixinException { public JsonResult deleteGroup(int groupId) throws WeixinException {
String group_delete_uri = getRequestUri("group_delete_uri"); String group_delete_uri = getRequestUri("group_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(group_delete_uri, token.getAccessToken()), String.format(group_delete_uri, token.getAccessToken()),
String.format("{\"group\":{\"id\":%d}}", groupId)); String.format("{\"group\":{\"id\":%d}}", groupId));

View File

@ -17,9 +17,10 @@ import com.foxinmy.weixin4j.mp.model.AutoReplySetting;
import com.foxinmy.weixin4j.mp.model.MenuSetting; import com.foxinmy.weixin4j.mp.model.MenuSetting;
import com.foxinmy.weixin4j.mp.model.SemQuery; import com.foxinmy.weixin4j.mp.model.SemQuery;
import com.foxinmy.weixin4j.mp.model.SemResult; import com.foxinmy.weixin4j.mp.model.SemResult;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.ButtonType; import com.foxinmy.weixin4j.type.ButtonType;
import com.foxinmy.weixin4j.util.ReflectionUtil;
/** /**
* 辅助相关API * 辅助相关API
@ -32,10 +33,10 @@ import com.foxinmy.weixin4j.type.ButtonType;
*/ */
public class HelperApi extends MpApi { public class HelperApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public HelperApi(TokenHolder tokenHolder) { public HelperApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -50,7 +51,7 @@ public class HelperApi extends MpApi {
*/ */
public String getShorturl(String url) throws WeixinException { public String getShorturl(String url) throws WeixinException {
String shorturl_uri = getRequestUri("shorturl_uri"); String shorturl_uri = getRequestUri("shorturl_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("action", "long2short"); obj.put("action", "long2short");
obj.put("long_url", url); obj.put("long_url", url);
@ -75,7 +76,7 @@ public class HelperApi extends MpApi {
*/ */
public SemResult semantic(SemQuery semQuery) throws WeixinException { public SemResult semantic(SemQuery semQuery) throws WeixinException {
String semantic_uri = getRequestUri("semantic_uri"); String semantic_uri = getRequestUri("semantic_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(semantic_uri, token.getAccessToken()), String.format(semantic_uri, token.getAccessToken()),
semQuery.toJson()); semQuery.toJson());
@ -93,7 +94,7 @@ public class HelperApi extends MpApi {
*/ */
public List<String> getWechatServerIp() throws WeixinException { public List<String> getWechatServerIp() throws WeixinException {
String getcallbackip_uri = getRequestUri("getcallbackip_uri"); String getcallbackip_uri = getRequestUri("getcallbackip_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(String.format(
getcallbackip_uri, token.getAccessToken())); getcallbackip_uri, token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("ip_list"), return JSON.parseArray(response.getAsJson().getString("ip_list"),
@ -115,7 +116,7 @@ public class HelperApi extends MpApi {
*/ */
public MenuSetting getMenuSetting() throws WeixinException { public MenuSetting getMenuSetting() throws WeixinException {
String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri"); String menu_get_selfmenu_uri = getRequestUri("menu_get_selfmenu_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
menu_get_selfmenu_uri, token.getAccessToken())); menu_get_selfmenu_uri, token.getAccessToken()));
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
@ -151,14 +152,18 @@ public class HelperApi extends MpApi {
JSONObject article = null; JSONObject article = null;
for (int i = 0; i < news.size(); i++) { for (int i = 0; i < news.size(); i++) {
article = news.getJSONObject(i); article = news.getJSONObject(i);
article.put("showCoverPic", article.remove("show_cover")); article.put("show_cover_pic", article.remove("show_cover"));
article.put("coverUrl", article.remove("cover_url")); article.put("thumb_url", article.remove("cover_url"));
article.put("contentUrl", article.remove("content_url")); article.put("url", article.remove("content_url"));
article.put("sourceUrl", article.remove("source_url")); article.put("content_source_url",
newsList.add(JSON.parseObject(article.toJSONString(), article.remove("source_url"));
MpArticle.class)); newsList.add(JSON.toJavaObject(article, MpArticle.class));
} }
if (ReflectionUtil.getAccessibleField(object, "articles") != null) {
JSONPath.set(object, "$.articles", newsList);
} else {
JSONPath.set(object, "$.content", newsList); JSONPath.set(object, "$.content", newsList);
}
} else { } else {
JSONPath.set(object, "$.content", value); JSONPath.set(object, "$.content", value);
} }
@ -175,11 +180,12 @@ public class HelperApi extends MpApi {
*/ */
public AutoReplySetting getAutoReplySetting() throws WeixinException { public AutoReplySetting getAutoReplySetting() throws WeixinException {
String autoreply_setting_get_uri = getRequestUri("autoreply_setting_get_uri"); String autoreply_setting_get_uri = getRequestUri("autoreply_setting_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
autoreply_setting_get_uri, token.getAccessToken())); autoreply_setting_get_uri, token.getAccessToken()));
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
AutoReplySetting replySetting = JSON.toJavaObject(result, AutoReplySetting replySetting = JSON.toJavaObject(result,
AutoReplySetting.class); AutoReplySetting.class);
List<AutoReplySetting.Rule> ruleList = null; List<AutoReplySetting.Rule> ruleList = null;

View File

@ -10,7 +10,7 @@ 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.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MassTuple; import com.foxinmy.weixin4j.tuple.MassTuple;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.MpNews; import com.foxinmy.weixin4j.tuple.MpNews;
@ -27,10 +27,10 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class MassApi extends MpApi { public class MassApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public MassApi(TokenHolder tokenHolder) { public MassApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -48,7 +48,7 @@ public class MassApi extends MpApi {
public String uploadArticle(List<MpArticle> articles) public String uploadArticle(List<MpArticle> articles)
throws WeixinException { throws WeixinException {
String article_upload_uri = getRequestUri("article_upload_uri"); String article_upload_uri = getRequestUri("article_upload_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("articles", articles); obj.put("articles", articles);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
@ -110,7 +110,7 @@ public class MassApi extends MpApi {
obj.put(msgtype, JSON.toJSON(tuple)); obj.put(msgtype, JSON.toJSON(tuple));
obj.put("msgtype", msgtype); obj.put("msgtype", msgtype);
String mass_group_uri = getRequestUri("mass_group_uri"); String mass_group_uri = getRequestUri("mass_group_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(mass_group_uri, token.getAccessToken()), String.format(mass_group_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -180,7 +180,7 @@ public class MassApi extends MpApi {
obj.put(msgtype, JSON.toJSON(tuple)); obj.put(msgtype, JSON.toJSON(tuple));
obj.put("msgtype", msgtype); obj.put("msgtype", msgtype);
String mass_openid_uri = getRequestUri("mass_openid_uri"); String mass_openid_uri = getRequestUri("mass_openid_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(mass_openid_uri, token.getAccessToken()), String.format(mass_openid_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -228,7 +228,7 @@ public class MassApi extends MpApi {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("msgid", msgid); obj.put("msgid", msgid);
String mass_delete_uri = getRequestUri("mass_delete_uri"); String mass_delete_uri = getRequestUri("mass_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(mass_delete_uri, token.getAccessToken()), String.format(mass_delete_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -260,7 +260,7 @@ public class MassApi extends MpApi {
obj.put(msgtype, JSON.toJSON(tuple)); obj.put(msgtype, JSON.toJSON(tuple));
obj.put("msgtype", msgtype); obj.put("msgtype", msgtype);
String mass_preview_uri = getRequestUri("mass_preview_uri"); String mass_preview_uri = getRequestUri("mass_preview_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(mass_preview_uri, token.getAccessToken()), String.format(mass_preview_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -282,7 +282,7 @@ public class MassApi extends MpApi {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("msg_id", msgId); obj.put("msg_id", msgId);
String mass_get_uri = getRequestUri("mass_get_uri"); String mass_get_uri = getRequestUri("mass_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(mass_get_uri, token.getAccessToken()), String.format(mass_get_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());

View File

@ -35,7 +35,7 @@ import com.foxinmy.weixin4j.model.MediaRecord;
import com.foxinmy.weixin4j.model.MediaUploadResult; import com.foxinmy.weixin4j.model.MediaUploadResult;
import com.foxinmy.weixin4j.model.Pageable; import com.foxinmy.weixin4j.model.Pageable;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.MpVideo; import com.foxinmy.weixin4j.tuple.MpVideo;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
@ -55,10 +55,10 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class MediaApi extends MpApi { public class MediaApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public MediaApi(TokenHolder tokenHolder) { public MediaApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -81,7 +81,7 @@ public class MediaApi extends MpApi {
fileName = String.format("%s.jpg", fileName); fileName = String.format("%s.jpg", fileName);
} }
String image_upload_uri = getRequestUri("image_upload_uri"); String image_upload_uri = getRequestUri("image_upload_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(String.format(
image_upload_uri, token.getAccessToken()), image_upload_uri, token.getAccessToken()),
new FormBodyPart("media", new InputStreamBody(is, new FormBodyPart("media", new InputStreamBody(is,
@ -114,7 +114,7 @@ public class MediaApi extends MpApi {
obj.put("title", title); obj.put("title", title);
obj.put("description", description); obj.put("description", description);
String video_upload_uri = getRequestUri("video_upload_uri"); String video_upload_uri = getRequestUri("video_upload_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(video_upload_uri, token.getAccessToken()), String.format(video_upload_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -180,7 +180,7 @@ public class MediaApi extends MpApi {
throw new WeixinException( throw new WeixinException(
"please invoke uploadMaterialVideo method"); "please invoke uploadMaterialVideo method");
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = null; WeixinResponse response = null;
try { try {
if (isMaterial) { if (isMaterial) {
@ -238,7 +238,7 @@ public class MediaApi extends MpApi {
*/ */
public MediaDownloadResult downloadMedia(String mediaId, boolean isMaterial) public MediaDownloadResult downloadMedia(String mediaId, boolean isMaterial)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
try { try {
HttpRequest request = null; HttpRequest request = null;
if (isMaterial) { if (isMaterial) {
@ -310,7 +310,7 @@ public class MediaApi extends MpApi {
*/ */
public String uploadMaterialArticle(List<MpArticle> articles) public String uploadMaterialArticle(List<MpArticle> articles)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_article_upload_uri = getRequestUri("material_article_upload_uri"); String material_article_upload_uri = getRequestUri("material_article_upload_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("articles", articles); obj.put("articles", articles);
@ -357,7 +357,7 @@ public class MediaApi extends MpApi {
*/ */
public JsonResult updateMaterialArticle(String mediaId, int index, public JsonResult updateMaterialArticle(String mediaId, int index,
MpArticle article) throws WeixinException { MpArticle article) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_article_update_uri = getRequestUri("material_article_update_uri"); String material_article_update_uri = getRequestUri("material_article_update_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("articles", article); obj.put("articles", article);
@ -382,7 +382,7 @@ public class MediaApi extends MpApi {
*/ */
public JsonResult deleteMaterialMedia(String mediaId) public JsonResult deleteMaterialMedia(String mediaId)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_media_del_uri = getRequestUri("material_media_del_uri"); String material_media_del_uri = getRequestUri("material_media_del_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("media_id", mediaId); obj.put("media_id", mediaId);
@ -418,7 +418,7 @@ public class MediaApi extends MpApi {
fileName = String.format("%s.mp4", fileName); fileName = String.format("%s.mp4", fileName);
} }
String material_media_upload_uri = getRequestUri("material_media_upload_uri"); String material_media_upload_uri = getRequestUri("material_media_upload_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
try { try {
JSONObject description = new JSONObject(); JSONObject description = new JSONObject();
description.put("title", title); description.put("title", title);
@ -454,7 +454,7 @@ public class MediaApi extends MpApi {
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738733&token=&lang=zh_CN">获取素材总数</a> * href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1444738733&token=&lang=zh_CN">获取素材总数</a>
*/ */
public MediaCounter countMaterialMedia() throws WeixinException { public MediaCounter countMaterialMedia() throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_media_count_uri = getRequestUri("material_media_count_uri"); String material_media_count_uri = getRequestUri("material_media_count_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
material_media_count_uri, token.getAccessToken())); material_media_count_uri, token.getAccessToken()));
@ -482,7 +482,7 @@ public class MediaApi extends MpApi {
*/ */
public MediaRecord listMaterialMedia(MediaType mediaType, Pageable pageable) public MediaRecord listMaterialMedia(MediaType mediaType, Pageable pageable)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_media_list_uri = getRequestUri("material_media_list_uri"); String material_media_list_uri = getRequestUri("material_media_list_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("type", mediaType.name()); obj.put("type", mediaType.name());

View File

@ -17,7 +17,7 @@ import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.Menu; import com.foxinmy.weixin4j.mp.model.Menu;
import com.foxinmy.weixin4j.mp.model.MenuMatchRule; import com.foxinmy.weixin4j.mp.model.MenuMatchRule;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.type.ButtonType; import com.foxinmy.weixin4j.type.ButtonType;
/** /**
@ -30,10 +30,10 @@ import com.foxinmy.weixin4j.type.ButtonType;
*/ */
public class MenuApi extends MpApi { public class MenuApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public MenuApi(TokenHolder tokenHolder) { public MenuApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -58,7 +58,7 @@ public class MenuApi extends MpApi {
private WeixinResponse createMenu0(String url, JSONObject data) private WeixinResponse createMenu0(String url, JSONObject data)
throws WeixinException { throws WeixinException {
return weixinExecutor.post( return weixinExecutor.post(
String.format(url, tokenHolder.getAccessToken()), String.format(url, tokenManager.getAccessToken()),
JSON.toJSONString(data, new NameFilter() { JSON.toJSONString(data, new NameFilter() {
@Override @Override
public String process(Object object, String name, public String process(Object object, String name,
@ -98,7 +98,7 @@ public class MenuApi extends MpApi {
private JSONObject getMenu0() throws WeixinException { private JSONObject getMenu0() throws WeixinException {
String menu_get_uri = getRequestUri("menu_get_uri"); String menu_get_uri = getRequestUri("menu_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
menu_get_uri, token.getAccessToken())); menu_get_uri, token.getAccessToken()));
return response.getAsJson(); return response.getAsJson();
@ -150,7 +150,7 @@ public class MenuApi extends MpApi {
*/ */
public JsonResult deleteMenu() throws WeixinException { public JsonResult deleteMenu() throws WeixinException {
String menu_delete_uri = getRequestUri("menu_delete_uri"); String menu_delete_uri = getRequestUri("menu_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
menu_delete_uri, token.getAccessToken())); menu_delete_uri, token.getAccessToken()));
@ -192,7 +192,7 @@ public class MenuApi extends MpApi {
*/ */
public JsonResult deleteCustomMenu(String menuId) throws WeixinException { public JsonResult deleteCustomMenu(String menuId) throws WeixinException {
String menu_delete_uri = getRequestUri("menu_delete_custom_uri"); String menu_delete_uri = getRequestUri("menu_delete_custom_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("menuid", menuId); obj.put("menuid", menuId);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
@ -216,7 +216,7 @@ public class MenuApi extends MpApi {
*/ */
public List<Button> matchCustomMenu(String userId) throws WeixinException { public List<Button> matchCustomMenu(String userId) throws WeixinException {
String menu_trymatch_uri = getRequestUri("menu_trymatch_uri"); String menu_trymatch_uri = getRequestUri("menu_trymatch_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("user_id", userId); obj.put("user_id", userId);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(

View File

@ -1,12 +1,16 @@
package com.foxinmy.weixin4j.mp.api; package com.foxinmy.weixin4j.mp.api;
import java.util.List;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
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.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.message.NotifyMessage; import com.foxinmy.weixin4j.mp.message.NotifyMessage;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.tuple.MpNews;
import com.foxinmy.weixin4j.tuple.NotifyTuple; import com.foxinmy.weixin4j.tuple.NotifyTuple;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
@ -20,10 +24,12 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class NotifyApi extends MpApi { public class NotifyApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
private final MassApi massApi;
public NotifyApi(TokenHolder tokenHolder) { public NotifyApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
this.massApi = new MassApi(tokenManager);
} }
/** /**
@ -61,6 +67,17 @@ public class NotifyApi extends MpApi {
public JsonResult sendNotify(NotifyMessage notify, String kfAccount) public JsonResult sendNotify(NotifyMessage notify, String kfAccount)
throws WeixinException { throws WeixinException {
NotifyTuple tuple = notify.getTuple(); NotifyTuple tuple = notify.getTuple();
if (tuple instanceof MpNews) {
MpNews _news = (MpNews) tuple;
List<MpArticle> _articles = _news.getArticles();
if (StringUtil.isBlank(_news.getMediaId())) {
if (_articles.isEmpty()) {
throw new WeixinException(
"notify fail:mediaId or articles is required");
}
tuple = new MpNews(massApi.uploadArticle(_articles));
}
}
String msgtype = tuple.getMessageType(); String msgtype = tuple.getMessageType();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("touser", notify.getTouser()); obj.put("touser", notify.getTouser());
@ -72,7 +89,7 @@ public class NotifyApi extends MpApi {
obj.put("customservice", kf); obj.put("customservice", kf);
} }
String custom_notify_uri = getRequestUri("custom_notify_uri"); String custom_notify_uri = getRequestUri("custom_notify_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(custom_notify_uri, token.getAccessToken()), String.format(custom_notify_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());

View File

@ -3,6 +3,7 @@ package com.foxinmy.weixin4j.mp.api;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
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;
@ -110,9 +111,14 @@ public class OauthApi extends MpApi {
String user_token_uri = getRequestUri("sns_user_token_uri"); String user_token_uri = getRequestUri("sns_user_token_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_token_uri, account.getId(), account.getSecret(), code)); user_token_uri, account.getId(), account.getSecret(), code));
JSONObject result = response.getAsJson();
return response.getAsObject(new TypeReference<OauthToken>() { OauthToken token = new OauthToken(result.getString("access_token"),
}); result.getLongValue("expires_in") * 1000l);
token.setUnionId(result.getString("unionid"));
token.setOpenId(result.getString("openid"));
token.setScope(result.getString("scope"));
token.setRefreshToken(result.getString("refresh_token"));
return token;
} }
/** /**

View File

@ -25,6 +25,8 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.Feature;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.cache.FileCacheStorager;
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.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
@ -42,9 +44,7 @@ import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.payment.PayRequest; import com.foxinmy.weixin4j.payment.PayRequest;
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
import com.foxinmy.weixin4j.sign.WeixinSignature; import com.foxinmy.weixin4j.sign.WeixinSignature;
import com.foxinmy.weixin4j.token.FileTokenStorager; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.token.TokenHolder;
import com.foxinmy.weixin4j.token.TokenStorager;
import com.foxinmy.weixin4j.type.BillType; import com.foxinmy.weixin4j.type.BillType;
import com.foxinmy.weixin4j.type.IdQuery; import com.foxinmy.weixin4j.type.IdQuery;
import com.foxinmy.weixin4j.type.RefundType; import com.foxinmy.weixin4j.type.RefundType;
@ -69,7 +69,7 @@ import com.foxinmy.weixin4j.xml.ListsuffixResultDeserializer;
public class PayOldApi extends MpApi { public class PayOldApi extends MpApi {
private final WeixinOldPayAccount weixinAccount; private final WeixinOldPayAccount weixinAccount;
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
private final WeixinSignature weixinMD5Signature; private final WeixinSignature weixinMD5Signature;
private final WeixinOldPaymentSignature weixinOldSignature; private final WeixinOldPaymentSignature weixinOldSignature;
@ -78,28 +78,28 @@ public class PayOldApi extends MpApi {
*/ */
public PayOldApi() { public PayOldApi() {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinOldPayAccount.class), new FileTokenStorager( WeixinOldPayAccount.class), new FileCacheStorager<Token>(
Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir", Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
System.getProperty("java.io.tmpdir")))); System.getProperty("java.io.tmpdir"))));
} }
public PayOldApi(WeixinOldPayAccount payAccount) { public PayOldApi(WeixinOldPayAccount payAccount) {
this(payAccount, new FileTokenStorager( this(payAccount, new FileCacheStorager<Token>(
Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir", Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
System.getProperty("java.io.tmpdir")))); System.getProperty("java.io.tmpdir"))));
} }
public PayOldApi(TokenStorager tokenStorager) { public PayOldApi(CacheStorager<Token> cacheStorager) {
this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"), this(JSON.parseObject(Weixin4jConfigUtil.getValue("account"),
WeixinOldPayAccount.class), tokenStorager); WeixinOldPayAccount.class), cacheStorager);
} }
public PayOldApi(WeixinOldPayAccount weixinAccount, public PayOldApi(WeixinOldPayAccount weixinAccount,
TokenStorager tokenStorager) { CacheStorager<Token> cacheStorager) {
this.weixinAccount = weixinAccount; this.weixinAccount = weixinAccount;
this.tokenHolder = new TokenHolder(new WeixinTokenCreator( this.tokenManager = new TokenManager(new WeixinTokenCreator(
weixinAccount.getId(), weixinAccount.getSecret()), weixinAccount.getId(), weixinAccount.getSecret()),
tokenStorager); cacheStorager);
this.weixinMD5Signature = new WeixinPaymentSignature( this.weixinMD5Signature = new WeixinPaymentSignature(
weixinAccount.getPartnerKey()); weixinAccount.getPartnerKey());
this.weixinOldSignature = new WeixinOldPaymentSignature(); this.weixinOldSignature = new WeixinOldPaymentSignature();
@ -109,7 +109,7 @@ public class PayOldApi extends MpApi {
return this.weixinAccount; return this.weixinAccount;
} }
public WeixinOldPaymentSignature getWeixinPaymentSignature(){ public WeixinOldPaymentSignature getWeixinPaymentSignature() {
return this.weixinOldSignature; return this.weixinOldSignature;
} }
@ -130,9 +130,9 @@ public class PayOldApi extends MpApi {
*/ */
public String createPayJsRequestJson(String body, String outTradeNo, public String createPayJsRequestJson(String body, String outTradeNo,
double totalFee, String notifyUrl, String createIp) { double totalFee, String notifyUrl, String createIp) {
PayPackageV2 payPackage = new PayPackageV2(weixinAccount PayPackageV2 payPackage = new PayPackageV2(
.getPartnerId(), body, outTradeNo, totalFee, notifyUrl, weixinAccount.getPartnerId(), body, outTradeNo, totalFee,
createIp); notifyUrl, createIp);
return createPayJsRequestJson(payPackage); return createPayJsRequestJson(payPackage);
} }
@ -145,8 +145,8 @@ public class PayOldApi extends MpApi {
*/ */
public String createPayJsRequestJson(PayPackageV2 payPackage) { public String createPayJsRequestJson(PayPackageV2 payPackage) {
PayRequest payRequest = new PayRequest(weixinAccount.getId(), PayRequest payRequest = new PayRequest(weixinAccount.getId(),
weixinOldSignature.sign(payPackage, weixinAccount weixinOldSignature.sign(payPackage,
.getPartnerKey())); weixinAccount.getPartnerKey()));
payRequest.setPaySign(weixinOldSignature.sign(payRequest, payRequest.setPaySign(weixinOldSignature.sign(payRequest,
weixinAccount.getPaySignKey())); weixinAccount.getPaySignKey()));
payRequest.setSignType(SignType.SHA1); payRequest.setSignType(SignType.SHA1);
@ -187,7 +187,7 @@ public class PayOldApi extends MpApi {
*/ */
public OrderV2 queryOrder(IdQuery idQuery) throws WeixinException { public OrderV2 queryOrder(IdQuery idQuery) throws WeixinException {
String orderquery_uri = getRequestUri("orderquery_old_uri"); String orderquery_uri = getRequestUri("orderquery_old_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append(idQuery.getType().getName()).append("=") sb.append(idQuery.getType().getName()).append("=")
.append(idQuery.getId()); .append(idQuery.getId());
@ -286,9 +286,10 @@ public class PayOldApi extends MpApi {
SSLContext ctx = null; SSLContext ctx = null;
KeyStore ks = null; KeyStore ks = null;
String jksPwd = ""; String jksPwd = "";
File jksFile = new File(String.format("%s/tenpay_cacert.jks", File jksFile = new File(String.format("%s%stenpay_cacert.jks",
Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir", Weixin4jConfigUtil.getClassPathValue("weixin4j.tmpdir",
System.getProperty("java.io.tmpdir")))); System.getProperty("java.io.tmpdir")),
File.separator));
// create jks ca // create jks ca
if (!jksFile.exists()) { if (!jksFile.exists()) {
CertificateFactory cf = CertificateFactory CertificateFactory cf = CertificateFactory
@ -450,9 +451,10 @@ public class PayOldApi extends MpApi {
} }
String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate); String formatBillDate = DateUtil.fortmat2yyyyMMdd(billDate);
String fileName = String.format("weixin4j_bill_%s_%s_%s.txt", String fileName = String.format("weixin4j_bill_%s_%s_%s.txt",
formatBillDate, billType.name().toLowerCase(), weixinAccount formatBillDate, billType.name().toLowerCase(),
.getId()); weixinAccount.getId());
File file = new File(String.format("%s/%s", billPath, fileName)); File file = new File(String.format("%s%s%s", billPath, File.separator,
fileName));
if (file.exists()) { if (file.exists()) {
return file; return file;
} }
@ -543,7 +545,7 @@ public class PayOldApi extends MpApi {
String outTradeNo, boolean status, String statusMsg) String outTradeNo, boolean status, String statusMsg)
throws WeixinException { throws WeixinException {
String delivernotify_uri = getRequestUri("delivernotify_old_uri"); String delivernotify_uri = getRequestUri("delivernotify_old_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
Map<String, String> map = new HashMap<String, String>(); Map<String, String> map = new HashMap<String, String>();
map.put("appid", weixinAccount.getId()); map.put("appid", weixinAccount.getId());
@ -576,7 +578,7 @@ public class PayOldApi extends MpApi {
public JsonResult updateFeedback(String openId, String feedbackId) public JsonResult updateFeedback(String openId, String feedbackId)
throws WeixinException { throws WeixinException {
String payfeedback_uri = getRequestUri("payfeedback_old_uri"); String payfeedback_uri = getRequestUri("payfeedback_old_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
payfeedback_uri, token.getAccessToken(), openId, feedbackId)); payfeedback_uri, token.getAccessToken(), openId, feedbackId));
return response.getAsJsonResult(); return response.getAsJsonResult();

View File

@ -8,7 +8,7 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.QRParameter; import com.foxinmy.weixin4j.mp.model.QRParameter;
import com.foxinmy.weixin4j.mp.model.QRResult; import com.foxinmy.weixin4j.mp.model.QRResult;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.IOUtil; import com.foxinmy.weixin4j.util.IOUtil;
/** /**
@ -21,10 +21,10 @@ import com.foxinmy.weixin4j.util.IOUtil;
*/ */
public class QrApi extends MpApi { public class QrApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public QrApi(TokenHolder tokenHolder) { public QrApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -40,7 +40,7 @@ public class QrApi extends MpApi {
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542&token=&lang=zh_CN">生成二维码</a> * href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1443433542&token=&lang=zh_CN">生成二维码</a>
*/ */
public QRResult createQR(QRParameter parameter) throws WeixinException { public QRResult createQR(QRParameter parameter) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String qr_uri = getRequestUri("qr_ticket_uri"); String qr_uri = getRequestUri("qr_ticket_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(qr_uri, token.getAccessToken()), String.format(qr_uri, token.getAccessToken()),

View File

@ -11,7 +11,7 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.mp.model.Following; import com.foxinmy.weixin4j.mp.model.Following;
import com.foxinmy.weixin4j.mp.model.Tag; import com.foxinmy.weixin4j.mp.model.Tag;
import com.foxinmy.weixin4j.mp.model.User; import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 标签相关API * 标签相关API
@ -23,12 +23,12 @@ import com.foxinmy.weixin4j.token.TokenHolder;
* @see com.foxinmy.weixin4j.mp.model.Tag * @see com.foxinmy.weixin4j.mp.model.Tag
*/ */
public class TagApi extends MpApi { public class TagApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
private final UserApi userApi; private final UserApi userApi;
public TagApi(TokenHolder tokenHolder) { public TagApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
this.userApi = new UserApi(tokenHolder); this.userApi = new UserApi(tokenManager);
} }
/** /**
@ -45,7 +45,7 @@ public class TagApi extends MpApi {
public Tag createTag(String name) throws WeixinException { public Tag createTag(String name) throws WeixinException {
String tag_create_uri = getRequestUri("tag_create_uri"); String tag_create_uri = getRequestUri("tag_create_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_create_uri, tokenHolder.getAccessToken()), String.format(tag_create_uri, tokenManager.getAccessToken()),
String.format("{\"tag\":{\"name\":\"%s\"}}", name)); String.format("{\"tag\":{\"name\":\"%s\"}}", name));
return JSON.parseObject(response.getAsJson().getString("tag"), return JSON.parseObject(response.getAsJson().getString("tag"),
@ -64,7 +64,7 @@ public class TagApi extends MpApi {
public List<Tag> listTags() throws WeixinException { public List<Tag> listTags() throws WeixinException {
String tag_get_uri = getRequestUri("tag_get_uri"); String tag_get_uri = getRequestUri("tag_get_uri");
WeixinResponse response = weixinExecutor.get(String.format(tag_get_uri, WeixinResponse response = weixinExecutor.get(String.format(tag_get_uri,
tokenHolder.getAccessToken())); tokenManager.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("tags"), return JSON.parseArray(response.getAsJson().getString("tags"),
Tag.class); Tag.class);
@ -86,7 +86,7 @@ public class TagApi extends MpApi {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("tag", tag); obj.put("tag", tag);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_update_uri, tokenHolder.getAccessToken()), String.format(tag_update_uri, tokenManager.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
} }
@ -104,7 +104,7 @@ public class TagApi extends MpApi {
public JsonResult deleteTag(int tagId) throws WeixinException { public JsonResult deleteTag(int tagId) throws WeixinException {
String tag_delete_uri = getRequestUri("tag_delete_uri"); String tag_delete_uri = getRequestUri("tag_delete_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_delete_uri, tokenHolder.getAccessToken()), String.format(tag_delete_uri, tokenManager.getAccessToken()),
String.format("{\"tagid\":%d}", tagId)); String.format("{\"tagid\":%d}", tagId));
return response.getAsJsonResult(); return response.getAsJsonResult();
} }
@ -133,7 +133,7 @@ public class TagApi extends MpApi {
obj.put("openid_list", openIds); obj.put("openid_list", openIds);
obj.put("tagid", tagId); obj.put("tagid", tagId);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_batch_uri, tokenHolder.getAccessToken()), String.format(tag_batch_uri, tokenManager.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
} }
@ -174,7 +174,7 @@ public class TagApi extends MpApi {
obj.put("tagid", tagId); obj.put("tagid", tagId);
obj.put("next_openid", nextOpenId); obj.put("next_openid", nextOpenId);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_user_uri, tokenHolder.getAccessToken()), String.format(tag_user_uri, tokenManager.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
@ -283,7 +283,7 @@ public class TagApi extends MpApi {
public Integer[] getUserTags(String openId) throws WeixinException { public Integer[] getUserTags(String openId) throws WeixinException {
String tag_userids_uri = getRequestUri("tag_userids_uri"); String tag_userids_uri = getRequestUri("tag_userids_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_userids_uri, tokenHolder.getAccessToken()), String.format(tag_userids_uri, tokenManager.getAccessToken()),
String.format("{\"openid\":\"%s\"}", openId)); String.format("{\"openid\":\"%s\"}", openId));
return response.getAsJson().getJSONArray("tagid_list") return response.getAsJson().getJSONArray("tagid_list")
.toArray(new Integer[] {}); .toArray(new Integer[] {});

View File

@ -12,7 +12,7 @@ import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.message.TemplateMessage; import com.foxinmy.weixin4j.mp.message.TemplateMessage;
import com.foxinmy.weixin4j.mp.model.TemplateMessageInfo; import com.foxinmy.weixin4j.mp.model.TemplateMessageInfo;
import com.foxinmy.weixin4j.mp.type.IndustryType; import com.foxinmy.weixin4j.mp.type.IndustryType;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.NameValue; import com.foxinmy.weixin4j.util.NameValue;
/** /**
@ -26,10 +26,10 @@ import com.foxinmy.weixin4j.util.NameValue;
*/ */
public class TmplApi extends MpApi { public class TmplApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public TmplApi(TokenHolder tokenHolder) { public TmplApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -50,7 +50,7 @@ public class TmplApi extends MpApi {
obj.put(String.format("industry_id%d", i + 1), obj.put(String.format("industry_id%d", i + 1),
Integer.toString(industryTypes[i].getTypeId())); Integer.toString(industryTypes[i].getTypeId()));
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String template_set_industry_uri = getRequestUri("template_set_industry_uri"); String template_set_industry_uri = getRequestUri("template_set_industry_uri");
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(String.format(
template_set_industry_uri, token.getAccessToken()), obj template_set_industry_uri, token.getAccessToken()), obj
@ -71,7 +71,7 @@ public class TmplApi extends MpApi {
public IndustryType[] getTmplIndustry() throws WeixinException { public IndustryType[] getTmplIndustry() throws WeixinException {
String template_get_industry_uri = getRequestUri("template_get_industry_uri"); String template_get_industry_uri = getRequestUri("template_get_industry_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
template_get_industry_uri, tokenHolder.getAccessToken())); template_get_industry_uri, tokenManager.getAccessToken()));
JSONObject primary = response.getAsJson().getJSONObject( JSONObject primary = response.getAsJson().getJSONObject(
"primary_industry"); "primary_industry");
JSONObject secondary = response.getAsJson().getJSONObject( JSONObject secondary = response.getAsJson().getJSONObject(
@ -96,7 +96,7 @@ public class TmplApi extends MpApi {
* href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN">获得模板ID</a> * href="https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1433751277&token=&lang=zh_CN">获得模板ID</a>
*/ */
public String getTemplateId(String shortId) throws WeixinException { public String getTemplateId(String shortId) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String template_getid_uri = getRequestUri("template_getid_uri"); String template_getid_uri = getRequestUri("template_getid_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(template_getid_uri, token.getAccessToken()), String.format(template_getid_uri, token.getAccessToken()),
@ -115,7 +115,7 @@ public class TmplApi extends MpApi {
* @throws WeixinException * @throws WeixinException
*/ */
public List<TemplateMessageInfo> getAllTemplates() throws WeixinException { public List<TemplateMessageInfo> getAllTemplates() throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String template_getall_uri = getRequestUri("template_getall_uri"); String template_getall_uri = getRequestUri("template_getall_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
template_getall_uri, token.getAccessToken())); template_getall_uri, token.getAccessToken()));
@ -134,7 +134,7 @@ public class TmplApi extends MpApi {
* @throws WeixinException * @throws WeixinException
*/ */
public JsonResult deleteTemplate(String templateId) throws WeixinException { public JsonResult deleteTemplate(String templateId) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String template_del_uri = getRequestUri("template_del_uri"); String template_del_uri = getRequestUri("template_del_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(template_del_uri, token.getAccessToken()), String.format(template_del_uri, token.getAccessToken()),
@ -159,7 +159,7 @@ public class TmplApi extends MpApi {
*/ */
public JsonResult sendTmplMessage(TemplateMessage tplMessage) public JsonResult sendTmplMessage(TemplateMessage tplMessage)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String template_send_uri = getRequestUri("template_send_uri"); String template_send_uri = getRequestUri("template_send_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(template_send_uri, token.getAccessToken()), String.format(template_send_uri, token.getAccessToken()),

View File

@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.Following; import com.foxinmy.weixin4j.mp.model.Following;
import com.foxinmy.weixin4j.mp.model.User; import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.mp.type.Lang; import com.foxinmy.weixin4j.mp.type.Lang;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 用户相关API * 用户相关API
@ -26,10 +26,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
*/ */
public class UserApi extends MpApi { public class UserApi extends MpApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public UserApi(TokenHolder tokenHolder) { public UserApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -66,7 +66,7 @@ public class UserApi extends MpApi {
*/ */
public User getUser(String openId, Lang lang) throws WeixinException { public User getUser(String openId, Lang lang) throws WeixinException {
String user_info_uri = getRequestUri("api_user_info_uri"); String user_info_uri = getRequestUri("api_user_info_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_info_uri, token.getAccessToken(), openId, lang.name())); user_info_uri, token.getAccessToken(), openId, lang.name()));
@ -118,7 +118,7 @@ public class UserApi extends MpApi {
} }
parameter.delete(parameter.length() - 1, parameter.length()); parameter.delete(parameter.length() - 1, parameter.length());
parameter.append("]}"); parameter.append("]}");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(api_users_info_uri, token.getAccessToken()), String.format(api_users_info_uri, token.getAccessToken()),
parameter.toString()); parameter.toString());
@ -174,7 +174,7 @@ public class UserApi extends MpApi {
public Following getFollowingOpenIds(String nextOpenId) public Following getFollowingOpenIds(String nextOpenId)
throws WeixinException { throws WeixinException {
String following_uri = getRequestUri("following_uri"); String following_uri = getRequestUri("following_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
following_uri, token.getAccessToken(), nextOpenId == null ? "" following_uri, token.getAccessToken(), nextOpenId == null ? ""
: nextOpenId)); : nextOpenId));
@ -267,7 +267,7 @@ public class UserApi extends MpApi {
public JsonResult remarkUserName(String openId, String remark) public JsonResult remarkUserName(String openId, String remark)
throws WeixinException { throws WeixinException {
String username_remark_uri = getRequestUri("username_remark_uri"); String username_remark_uri = getRequestUri("username_remark_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("openid", openId); obj.put("openid", openId);
obj.put("remark", remark); obj.put("remark", remark);

View File

@ -56,10 +56,7 @@ public class TemplateMessage implements Serializable {
private final static String TAIL_KEY = "remark"; private final static String TAIL_KEY = "remark";
private final static String DEFAULT_COLOR = "#173177"; private final static String DEFAULT_COLOR = "#173177";
@JSONCreator public TemplateMessage(String toUser, String templateId, String url) {
public TemplateMessage(@JSONField(name = "toUser") String toUser,
@JSONField(name = "templateId") String templateId,
@JSONField(name = "url") String url) {
this.toUser = toUser; this.toUser = toUser;
this.templateId = templateId; this.templateId = templateId;
this.url = url; this.url = url;

View File

@ -7,6 +7,7 @@ import java.util.List;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.mp.type.AutomatchMode; import com.foxinmy.weixin4j.mp.type.AutomatchMode;
import com.foxinmy.weixin4j.mp.type.AutoreplyMode; import com.foxinmy.weixin4j.mp.type.AutoreplyMode;
import com.foxinmy.weixin4j.type.ButtonType;
/** /**
* 自动回复设置 * 自动回复设置
@ -189,10 +190,9 @@ public class AutoReplySetting implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "Rule [ruleName=" + ruleName + ", createTime=" return "Rule [ruleName=" + ruleName + ", createTime=" + createTime
+ createTime + ", replyMode=" + replyMode + ", replyMode=" + replyMode + ", keywordList="
+ ", keywordList=" + keywordList + ", replyList=" + keywordList + ", replyList=" + replyList + "]";
+ replyList + "]";
} }
} }
@ -212,7 +212,7 @@ public class AutoReplySetting implements Serializable {
* 自动回复的类型关注后自动回复和消息自动回复的类型仅支持文本text图片img语音voice视频video * 自动回复的类型关注后自动回复和消息自动回复的类型仅支持文本text图片img语音voice视频video
* 关键词自动回复则还多了图文消息(news) * 关键词自动回复则还多了图文消息(news)
*/ */
private String type; private ButtonType type;
/** /**
* 对于文本类型content是文本内容对于图片语音视频类型content是mediaID,news是article * 对于文本类型content是文本内容对于图片语音视频类型content是mediaID,news是article
* *
@ -227,11 +227,11 @@ public class AutoReplySetting implements Serializable {
@JSONField(name = "match_mode") @JSONField(name = "match_mode")
private AutomatchMode matchMode; private AutomatchMode matchMode;
public String getType() { public ButtonType getType() {
return type; return type;
} }
public void setType(String type) { public void setType(ButtonType type) {
this.type = type; this.type = type;
} }

View File

@ -1,5 +1,6 @@
package com.foxinmy.weixin4j.mp.model; package com.foxinmy.weixin4j.mp.model;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
@ -10,8 +11,6 @@ import com.foxinmy.weixin4j.model.Token;
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2014年4月6日 * @date 2014年4月6日
* @since JDK 1.6 * @since JDK 1.6
* @see com.foxinmy.weixin4j.mp.model.AuthResult
* @see com.foxinmy.weixin4j.mp.model.AuthResult.AuthScope
*/ */
public class OauthToken extends Token { public class OauthToken extends Token {
@ -36,6 +35,10 @@ public class OauthToken extends Token {
private String scope; private String scope;
public OauthToken(String accessToken, long expires) {
super(accessToken, expires);
}
public String getOpenId() { public String getOpenId() {
return openId; return openId;
} }
@ -71,9 +74,7 @@ public class OauthToken extends Token {
@Override @Override
public String toString() { public String toString() {
return "OauthToken [openId=" + openId + ", unionId=" + unionId return "OauthToken [openId=" + openId + ", unionId=" + unionId
+ ", refreshToken=" + refreshToken + ", scope=" + scope + ", refreshToken=" + refreshToken + ", scope=" + scope + ", "
+ ", accessToken=" + getAccessToken() + super.toString() + "]";
+ ", expiresIn=" + getExpiresIn() + ", createTime="
+ getCreateTime() + "]";
} }
} }

View File

@ -6,13 +6,13 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.type.URLConsts; import com.foxinmy.weixin4j.mp.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenCreator; import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.type.TicketType; import com.foxinmy.weixin4j.type.TicketType;
/** /**
* 微信公众平台TICKET创建(包括jsticket其它JSSDK所需的ticket的创建 * 微信公众平台TICKET创建(包括jsticket其它JSSDK所需的ticket的创建
* *
* @className WeixinJSTicketCreator * @className WeixinTicketCreator
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年1月10日 * @date 2015年1月10日
* @since JDK 1.6 * @since JDK 1.6
@ -24,7 +24,7 @@ public class WeixinTicketCreator extends TokenCreator {
private final String appid; private final String appid;
private final TicketType ticketType; private final TicketType ticketType;
private final TokenHolder weixinTokenHolder; private final TokenManager weixinTokenManager;
/** /**
* jssdk * jssdk
@ -33,13 +33,14 @@ public class WeixinTicketCreator extends TokenCreator {
* 公众号的appid * 公众号的appid
* @param ticketType * @param ticketType
* 票据类型 * 票据类型
* @param weixinTokenHolder * @param weixinTokenManager
* <font color="red">公众平台的access_token</font> * <font color="red">公众平台的access_token</font>
*/ */
public WeixinTicketCreator(String appid, TicketType ticketType, TokenHolder weixinTokenHolder) { public WeixinTicketCreator(String appid, TicketType ticketType,
TokenManager weixinTokenManager) {
this.appid = appid; this.appid = appid;
this.ticketType = ticketType; this.ticketType = ticketType;
this.weixinTokenHolder = weixinTokenHolder; this.weixinTokenManager = weixinTokenManager;
} }
@Override @Override
@ -49,12 +50,11 @@ public class WeixinTicketCreator extends TokenCreator {
@Override @Override
public Token create() throws WeixinException { public Token create() throws WeixinException {
WeixinResponse response = weixinExecutor.get( WeixinResponse response = weixinExecutor.get(String.format(
String.format(URLConsts.JS_TICKET_URL, weixinTokenHolder.getToken().getAccessToken(), ticketType.name())); URLConsts.JS_TICKET_URL, weixinTokenManager.getAccessToken(),
ticketType.name()));
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
Token token = new Token(result.getString("ticket")); return new Token(result.getString("ticket"),
token.setExpiresIn(result.getIntValue("expires_in")); result.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -1,6 +1,6 @@
package com.foxinmy.weixin4j.mp.token; package com.foxinmy.weixin4j.mp.token;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.JSONObject;
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.Token; import com.foxinmy.weixin4j.model.Token;
@ -45,10 +45,8 @@ public class WeixinTokenCreator extends TokenCreator {
String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, appid, String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, appid,
secret); secret);
WeixinResponse response = weixinExecutor.get(tokenUrl); WeixinResponse response = weixinExecutor.get(tokenUrl);
Token token = response.getAsObject(new TypeReference<Token>() { JSONObject result = response.getAsJson();
}); return new Token(result.getString("access_token"),
token.setCreateTime(System.currentTimeMillis()); result.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -35,7 +35,7 @@ public class CustomTest extends TokenTest {
@Before @Before
public void init() { public void init() {
customApi = new CustomApi(tokenHolder); customApi = new CustomApi(tokenManager);
} }
@Test @Test

View File

@ -28,7 +28,7 @@ public class DataApiTest extends TokenTest {
@Before @Before
public void init() { public void init() {
dataApi = new DataApi(tokenHolder); dataApi = new DataApi(tokenManager);
} }
@Test @Test

View File

@ -24,7 +24,7 @@ public class GroupTest extends TokenTest {
@Before @Before
public void init() { public void init() {
groupApi = new GroupApi(tokenHolder); groupApi = new GroupApi(tokenManager);
} }
@Test @Test

View File

@ -23,7 +23,7 @@ public class HelperTest extends TokenTest {
@Before @Before
public void init() { public void init() {
helperApi = new HelperApi(tokenHolder); helperApi = new HelperApi(tokenManager);
} }
@Test @Test

View File

@ -34,8 +34,8 @@ public class MassTest extends TokenTest {
@Before @Before
public void init() { public void init() {
this.massApi = new MassApi(tokenHolder); this.massApi = new MassApi(tokenManager);
this.mediaApi = new MediaApi(tokenHolder); this.mediaApi = new MediaApi(tokenManager);
} }
@Test @Test

View File

@ -39,7 +39,7 @@ public class MediaTest extends TokenTest {
@Before @Before
public void init() { public void init() {
mediaApi = new MediaApi(tokenHolder); mediaApi = new MediaApi(tokenManager);
} }
@Test @Test
@ -87,14 +87,14 @@ public class MediaTest extends TokenTest {
List<MpArticle> articles = new ArrayList<MpArticle>(); List<MpArticle> articles = new ArrayList<MpArticle>();
articles.add(new MpArticle("8790403529", "title", "content")); articles.add(new MpArticle("8790403529", "title", "content"));
String mediaId = mediaApi.uploadMaterialArticle(articles); String mediaId = mediaApi.uploadMaterialArticle(articles);
// 17385064953 // DVWwU0u9ommOTPgyJszpK943IWCCVAcFGNmiIBObf5E
Assert.assertNotNull(mediaId); Assert.assertNotNull(mediaId);
System.err.println(mediaId); System.err.println(mediaId);
} }
@Test @Test
public void downloadArticle() throws WeixinException { public void downloadArticle() throws WeixinException {
List<MpArticle> articles = mediaApi.downloadArticle("17385064953"); List<MpArticle> articles = mediaApi.downloadArticle("DVWwU0u9ommOTPgyJszpK943IWCCVAcFGNmiIBObf5E");
Assert.assertTrue(articles != null && !articles.isEmpty()); Assert.assertTrue(articles != null && !articles.isEmpty());
System.err.println(articles); System.err.println(articles);
} }

View File

@ -31,7 +31,7 @@ public class MenuTest extends TokenTest {
@Before @Before
public void init() { public void init() {
menuApi = new MenuApi(tokenHolder); menuApi = new MenuApi(tokenManager);
} }
@Test @Test

View File

@ -37,8 +37,8 @@ public class NotifyTest extends TokenTest {
@Before @Before
public void init() { public void init() {
notifyApi = new NotifyApi(tokenHolder); notifyApi = new NotifyApi(tokenManager);
mediaApi = new MediaApi(tokenHolder); mediaApi = new MediaApi(tokenManager);
} }
@Test @Test

View File

@ -24,7 +24,7 @@ public class QRTest extends TokenTest {
@Before @Before
public void init() { public void init() {
qrApi = new QrApi(tokenHolder); qrApi = new QrApi(tokenManager);
} }
@Test @Test

View File

@ -13,7 +13,7 @@ public class SemanticTest extends TokenTest {
@Before @Before
public void init() { public void init() {
helperApi = new HelperApi(tokenHolder); helperApi = new HelperApi(tokenManager);
} }
@Test @Test

View File

@ -26,7 +26,7 @@ public class TagTest extends TokenTest {
@Before @Before
public void init() { public void init() {
tagApi = new TagApi(tokenHolder); tagApi = new TagApi(tokenManager);
} }
@Test @Test

View File

@ -15,7 +15,7 @@ public class TemplateTest extends TokenTest {
@Before @Before
public void init() { public void init() {
this.tmplApi = new TmplApi(tokenHolder); this.tmplApi = new TmplApi(tokenManager);
} }
@Test @Test

View File

@ -7,7 +7,7 @@ import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator; import com.foxinmy.weixin4j.mp.token.WeixinTokenCreator;
import com.foxinmy.weixin4j.setting.Weixin4jSettings; import com.foxinmy.weixin4j.setting.Weixin4jSettings;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* token测试 * token测试
@ -19,19 +19,19 @@ import com.foxinmy.weixin4j.token.TokenHolder;
*/ */
public class TokenTest { public class TokenTest {
protected TokenHolder tokenHolder; protected TokenManager tokenManager;
protected Weixin4jSettings settings; protected Weixin4jSettings settings;
@Before @Before
public void setUp() { public void setUp() {
this.settings = new Weixin4jSettings(); this.settings = new Weixin4jSettings();
tokenHolder = new TokenHolder(new WeixinTokenCreator(settings tokenManager = new TokenManager(new WeixinTokenCreator(settings
.getAccount().getId(), settings.getAccount() .getAccount().getId(), settings.getAccount().getSecret()),
.getSecret()), settings.getTokenStorager0()); settings.getCacheStorager0());
} }
@Test @Test
public void test() throws WeixinException { public void test() throws WeixinException {
Assert.assertNotNull(tokenHolder.getToken()); Assert.assertNotNull(tokenManager.getCache());
} }
} }

View File

@ -24,7 +24,7 @@ public class UserTest extends TokenTest {
@Before @Before
public void init() { public void init() {
userApi = new UserApi(tokenHolder); userApi = new UserApi(tokenManager);
} }
@Test @Test

View File

@ -14,9 +14,7 @@ import com.foxinmy.weixin4j.xml.XmlStream;
public class XmlstreamTest { public class XmlstreamTest {
public static void object2xmlWithRootElement() { public static void object2xmlWithRootElement() {
Token token = new Token("accessToken"); Token token = new Token("accessToken", 12l, 13l);
token.setExpiresIn(12);
token.setCreateTime(13l);
String content = XmlStream.toXML(token); String content = XmlStream.toXML(token);
System.err.println(content); System.err.println(content);
} }

View File

@ -38,7 +38,7 @@ import com.foxinmy.weixin4j.qy.model.IdParameter;
import com.foxinmy.weixin4j.qy.model.Party; import com.foxinmy.weixin4j.qy.model.Party;
import com.foxinmy.weixin4j.qy.model.Tag; import com.foxinmy.weixin4j.qy.model.Tag;
import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.qy.suite.SuitePerCodeHolder; import com.foxinmy.weixin4j.qy.suite.SuitePerCodeManager;
import com.foxinmy.weixin4j.qy.suite.WeixinTokenSuiteCreator; import com.foxinmy.weixin4j.qy.suite.WeixinTokenSuiteCreator;
import com.foxinmy.weixin4j.qy.token.WeixinTicketCreator; import com.foxinmy.weixin4j.qy.token.WeixinTicketCreator;
import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator; import com.foxinmy.weixin4j.qy.token.WeixinTokenCreator;
@ -47,7 +47,7 @@ import com.foxinmy.weixin4j.qy.type.InviteType;
import com.foxinmy.weixin4j.qy.type.KfType; import com.foxinmy.weixin4j.qy.type.KfType;
import com.foxinmy.weixin4j.qy.type.UserStatus; import com.foxinmy.weixin4j.qy.type.UserStatus;
import com.foxinmy.weixin4j.setting.Weixin4jSettings; import com.foxinmy.weixin4j.setting.Weixin4jSettings;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.type.TicketType; import com.foxinmy.weixin4j.type.TicketType;
@ -106,7 +106,7 @@ public class WeixinProxy {
/** /**
* token实现 * token实现
*/ */
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
/** /**
* 配置信息 * 配置信息
*/ */
@ -126,30 +126,30 @@ public class WeixinProxy {
* @see com.foxinmy.weixin4j.setting.Weixin4jSettings * @see com.foxinmy.weixin4j.setting.Weixin4jSettings
*/ */
public WeixinProxy(Weixin4jSettings settings) { public WeixinProxy(Weixin4jSettings settings) {
this(new TokenHolder(new WeixinTokenCreator(settings.getAccount() this(new TokenManager(new WeixinTokenCreator(settings.getAccount()
.getId(), settings.getAccount().getSecret()), .getId(), settings.getAccount().getSecret()),
settings.getTokenStorager0())); settings.getCacheStorager0()));
this.settings = settings; this.settings = settings;
} }
/** /**
* 第三方套件(永久授权码机制) * 第三方套件(永久授权码机制)
* *
* @param perCodeHolder * @param perCodeManager
* 第三方套件永久授权码 * 第三方套件永久授权码
* {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getPerCodeHolder(String)} * {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getPerCodeManager(String)}
* @param suiteTokenHolder * @param suitetokenManager
* 第三方套件凭证token * 第三方套件凭证token
* {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getTokenSuiteHolder(String)} * {@link com.foxinmy.weixin4j.qy.api.SuiteApi#getTokenSuiteManager(String)}
* @see com.foxinmy.weixin4j.qy.api.SuiteApi * @see com.foxinmy.weixin4j.qy.api.SuiteApi
* @see WeixinSuiteProxy#getWeixinProxy(String, String) * @see WeixinSuiteProxy#getWeixinProxy(String, String)
*/ */
public WeixinProxy(SuitePerCodeHolder perCodeHolder, public WeixinProxy(SuitePerCodeManager perCodeManager,
TokenHolder suiteTokenHolder) { TokenManager suiteTokenManager) {
this(new TokenHolder(new WeixinTokenSuiteCreator(perCodeHolder, this(new TokenManager(new WeixinTokenSuiteCreator(perCodeManager,
suiteTokenHolder), perCodeHolder.getTokenStorager())); suiteTokenManager), perCodeManager.getCacheStorager()));
this.settings = new Weixin4jSettings(new WeixinAccount( this.settings = new Weixin4jSettings(new WeixinAccount(
perCodeHolder.getAuthCorpId(), null)); perCodeManager.getAuthCorpId(), null));
} }
/** /**
@ -157,20 +157,20 @@ public class WeixinProxy {
* color="red">WeixinTokenCreator或WeixinTokenSuiteCreator</font> * color="red">WeixinTokenCreator或WeixinTokenSuiteCreator</font>
* *
* @see com.foxinmy.weixin4j.qy.token.WeixinTokenCreator * @see com.foxinmy.weixin4j.qy.token.WeixinTokenCreator
* @param tokenHolder * @param tokenManager
*/ */
private WeixinProxy(TokenHolder tokenHolder) { private WeixinProxy(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
this.partyApi = new PartyApi(tokenHolder); this.partyApi = new PartyApi(tokenManager);
this.userApi = new UserApi(tokenHolder); this.userApi = new UserApi(tokenManager);
this.tagApi = new TagApi(tokenHolder); this.tagApi = new TagApi(tokenManager);
this.helperApi = new HelperApi(tokenHolder); this.helperApi = new HelperApi(tokenManager);
this.agentApi = new AgentApi(tokenHolder); this.agentApi = new AgentApi(tokenManager);
this.batchApi = new BatchApi(tokenHolder); this.batchApi = new BatchApi(tokenManager);
this.notifyApi = new NotifyApi(tokenHolder); this.notifyApi = new NotifyApi(tokenManager);
this.menuApi = new MenuApi(tokenHolder); this.menuApi = new MenuApi(tokenManager);
this.mediaApi = new MediaApi(tokenHolder); this.mediaApi = new MediaApi(tokenManager);
this.chatApi = new ChatApi(tokenHolder); this.chatApi = new ChatApi(tokenManager);
} }
/** /**
@ -178,8 +178,8 @@ public class WeixinProxy {
* *
* @return * @return
*/ */
public TokenHolder getTokenHolder() { public TokenManager getTokenManager() {
return this.tokenHolder; return this.tokenManager;
} }
/** /**
@ -192,16 +192,16 @@ public class WeixinProxy {
} }
/** /**
* 获取JSSDK Ticket的tokenHolder * 获取JSSDK Ticket的tokenManager
* *
* @param ticketType * @param ticketType
* 票据类型 * 票据类型
* @return * @return
*/ */
public TokenHolder getTicketHolder(TicketType ticketType) { public TokenManager getTicketManager(TicketType ticketType) {
return new TokenHolder(new WeixinTicketCreator(getWeixinAccount() return new TokenManager(new WeixinTicketCreator(getWeixinAccount()
.getId(), ticketType, this.tokenHolder), .getId(), ticketType, this.tokenManager),
this.settings.getTokenStorager0()); this.settings.getCacheStorager0());
} }
/** /**

View File

@ -12,12 +12,12 @@ import com.foxinmy.weixin4j.qy.api.ProviderApi;
import com.foxinmy.weixin4j.qy.api.SuiteApi; import com.foxinmy.weixin4j.qy.api.SuiteApi;
import com.foxinmy.weixin4j.qy.model.OUserInfo; import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount; import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
import com.foxinmy.weixin4j.qy.suite.SuiteTicketHolder; import com.foxinmy.weixin4j.qy.suite.SuiteTicketManager;
import com.foxinmy.weixin4j.qy.suite.Weixin4jSuiteSettings; import com.foxinmy.weixin4j.qy.suite.Weixin4jSuiteSettings;
import com.foxinmy.weixin4j.qy.token.WeixinProviderTokenCreator; import com.foxinmy.weixin4j.qy.token.WeixinProviderTokenCreator;
import com.foxinmy.weixin4j.qy.type.LoginTargetType; import com.foxinmy.weixin4j.qy.type.LoginTargetType;
import com.foxinmy.weixin4j.qy.type.URLConsts; import com.foxinmy.weixin4j.qy.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
@ -64,8 +64,8 @@ public class WeixinSuiteProxy {
for (WeixinAccount suite : suiteSettings.getAccount() for (WeixinAccount suite : suiteSettings.getAccount()
.getSuiteAccounts()) { .getSuiteAccounts()) {
this.suiteMap.put(suite.getId(), new SuiteApi( this.suiteMap.put(suite.getId(), new SuiteApi(
new SuiteTicketHolder(suite.getId(), suite.getSecret(), new SuiteTicketManager(suite.getId(), suite.getSecret(),
suiteSettings.getTokenStorager0()))); suiteSettings.getCacheStorager0())));
this.suiteMap.put( this.suiteMap.put(
null, null,
suiteMap.get(suiteSettings.getAccount() suiteMap.get(suiteSettings.getAccount()
@ -75,12 +75,12 @@ public class WeixinSuiteProxy {
if (StringUtil.isNotBlank(suiteSettings.getAccount().getId()) if (StringUtil.isNotBlank(suiteSettings.getAccount().getId())
&& StringUtil.isNotBlank(suiteSettings.getAccount() && StringUtil.isNotBlank(suiteSettings.getAccount()
.getProviderSecret())) { .getProviderSecret())) {
this.providerApi = new ProviderApi(new TokenHolder( this.providerApi = new ProviderApi(new TokenManager(
new WeixinProviderTokenCreator(suiteSettings new WeixinProviderTokenCreator(suiteSettings
.getAccount().getId(), suiteSettings .getAccount().getId(), suiteSettings
.getAccount().getProviderSecret()), .getAccount().getProviderSecret()),
suiteSettings.getTokenStorager0()), suiteSettings.getCacheStorager0()),
suiteSettings.getTokenStorager0()); suiteSettings.getCacheStorager0());
} }
} }
@ -129,7 +129,7 @@ public class WeixinSuiteProxy {
*/ */
public void cacheTicket(String suiteId, String suiteTicket) public void cacheTicket(String suiteId, String suiteTicket)
throws WeixinException { throws WeixinException {
suite(suiteId).getTicketHolder().cachingTicket(suiteTicket); suite(suiteId).getTicketManager().cachingTicket(suiteTicket);
} }
/** /**
@ -160,7 +160,7 @@ public class WeixinSuiteProxy {
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php?title * @see <a href="http://qydev.weixin.qq.com/wiki/index.php?title
* =%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%AE%A1%E7%90%86%E5%91%98%E6% * =%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%AE%A1%E7%90%86%E5%91%98%E6%
* 8E%88%E6%9D%83%E5%BA%94%E7%94%A8">企业号第三方应用套件授权</a> * 8E%88%E6%9D%83%E5%BA%94%E7%94%A8">企业号第三方应用套件授权</a>
* @see {@link SuiteApi#getPreCodeHolder} * @see {@link SuiteApi#getPreCodeManager}
* @return 请求授权的URL * @return 请求授权的URL
* @throws WeixinException * @throws WeixinException
*/ */
@ -168,7 +168,7 @@ public class WeixinSuiteProxy {
String state) throws WeixinException { String state) throws WeixinException {
try { try {
return String.format(URLConsts.SUITE_OAUTH_URL, suiteId, return String.format(URLConsts.SUITE_OAUTH_URL, suiteId,
suite(suiteId).getTicketHolder().getTicket(), suite(suiteId).getTicketManager().getTicket(),
URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state); URLEncoder.encode(redirectUri, Consts.UTF_8.name()), state);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
; ;
@ -226,8 +226,8 @@ public class WeixinSuiteProxy {
* @return * @return
*/ */
public WeixinProxy getWeixinProxy(String suiteId, String authCorpId) { public WeixinProxy getWeixinProxy(String suiteId, String authCorpId) {
return new WeixinProxy(suite(suiteId).getPerCodeHolder(authCorpId), return new WeixinProxy(suite(suiteId).getPerCodeManager(authCorpId),
suite(suiteId).getSuiteTokenHolder()); suite(suiteId).getSuiteTokenManager());
} }
public final static String VERSION = "1.6.9"; public final static String VERSION = "1.6.9";

View File

@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.qy.model.AgentInfo;
import com.foxinmy.weixin4j.qy.model.AgentOverview; import com.foxinmy.weixin4j.qy.model.AgentOverview;
import com.foxinmy.weixin4j.qy.model.AgentSetter; import com.foxinmy.weixin4j.qy.model.AgentSetter;
import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 管理应用接口 * 管理应用接口
@ -26,10 +26,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%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=%E7%AE%A1%E7%90%86%E4%BC%81%E4%B8%9A%E5%8F%B7%E5%BA%94%E7%94%A8">管理应用接口说明</a>
*/ */
public class AgentApi extends QyApi { public class AgentApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public AgentApi(TokenHolder tokenHolder) { public AgentApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -45,7 +45,7 @@ public class AgentApi extends QyApi {
*/ */
public AgentInfo getAgent(int agentid) throws WeixinException { public AgentInfo getAgent(int agentid) throws WeixinException {
String agent_get_uri = getRequestUri("agent_get_uri"); String agent_get_uri = getRequestUri("agent_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(agent_get_uri, WeixinResponse response = weixinExecutor.get(String.format(agent_get_uri,
token.getAccessToken(), agentid)); token.getAccessToken(), agentid));
JSONObject jsonObj = response.getAsJson(); JSONObject jsonObj = response.getAsJson();
@ -74,7 +74,7 @@ public class AgentApi extends QyApi {
*/ */
public JsonResult setAgent(AgentSetter agentSet) throws WeixinException { public JsonResult setAgent(AgentSetter agentSet) throws WeixinException {
String agent_set_uri = getRequestUri("agent_set_uri"); String agent_set_uri = getRequestUri("agent_set_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(agent_set_uri, token.getAccessToken()), String.format(agent_set_uri, token.getAccessToken()),
JSON.toJSONString(agentSet, typeFilter)); JSON.toJSONString(agentSet, typeFilter));
@ -108,7 +108,7 @@ public class AgentApi extends QyApi {
*/ */
public List<AgentOverview> listAgentOverview() throws WeixinException { public List<AgentOverview> listAgentOverview() throws WeixinException {
String agent_list_uri = getRequestUri("agent_list_uri"); String agent_list_uri = getRequestUri("agent_list_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(agent_list_uri, WeixinResponse response = weixinExecutor.get(String.format(agent_list_uri,
token.getAccessToken())); token.getAccessToken()));

View File

@ -8,7 +8,7 @@ import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.model.BatchResult; import com.foxinmy.weixin4j.qy.model.BatchResult;
import com.foxinmy.weixin4j.qy.model.Callback; import com.foxinmy.weixin4j.qy.model.Callback;
import com.foxinmy.weixin4j.qy.model.IdParameter; import com.foxinmy.weixin4j.qy.model.IdParameter;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 批量异步任务API * 批量异步任务API
@ -25,10 +25,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
*/ */
public class BatchApi extends QyApi { public class BatchApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public BatchApi(TokenHolder tokenHolder) { public BatchApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -50,7 +50,7 @@ public class BatchApi extends QyApi {
public String inviteUser(IdParameter parameter, Callback callback, public String inviteUser(IdParameter parameter, Callback callback,
String tips) throws WeixinException { String tips) throws WeixinException {
String batch_inviteuser_uri = getRequestUri("batch_inviteuser_uri"); String batch_inviteuser_uri = getRequestUri("batch_inviteuser_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.putAll(parameter.getParameter()); obj.putAll(parameter.getParameter());
obj.put("callback", callback); obj.put("callback", callback);
@ -89,7 +89,7 @@ public class BatchApi extends QyApi {
private String batch(String batchUrl, String mediaId, Callback callback) private String batch(String batchUrl, String mediaId, Callback callback)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("media_id", mediaId); obj.put("media_id", mediaId);
obj.put("callback", callback); obj.put("callback", callback);
@ -162,7 +162,7 @@ public class BatchApi extends QyApi {
* @throws WeixinException * @throws WeixinException
*/ */
public BatchResult getBatchResult(String jobId) throws WeixinException { public BatchResult getBatchResult(String jobId) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String batch_getresult_uri = getRequestUri("batch_getresult_uri"); String batch_getresult_uri = getRequestUri("batch_getresult_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
batch_getresult_uri, token.getAccessToken(), jobId)); batch_getresult_uri, token.getAccessToken(), jobId));

View File

@ -12,7 +12,7 @@ import com.foxinmy.weixin4j.qy.message.ChatMessage;
import com.foxinmy.weixin4j.qy.model.ChatInfo; import com.foxinmy.weixin4j.qy.model.ChatInfo;
import com.foxinmy.weixin4j.qy.model.ChatMute; import com.foxinmy.weixin4j.qy.model.ChatMute;
import com.foxinmy.weixin4j.qy.type.ChatType; import com.foxinmy.weixin4j.qy.type.ChatType;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.ChatTuple; import com.foxinmy.weixin4j.tuple.ChatTuple;
import com.foxinmy.weixin4j.util.ObjectId; import com.foxinmy.weixin4j.util.ObjectId;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
@ -28,10 +28,10 @@ import com.foxinmy.weixin4j.util.StringUtil;
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%9C%8D%E5%8A%A1">企业号消息服务</a> * href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E6%B6%88%E6%81%AF%E6%9C%8D%E5%8A%A1">企业号消息服务</a>
*/ */
public class ChatApi extends QyApi { public class ChatApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public ChatApi(TokenHolder tokenHolder) { public ChatApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -53,7 +53,7 @@ public class ChatApi extends QyApi {
obj.put("chatid", chatId); obj.put("chatid", chatId);
} }
String message_chat_create_uri = getRequestUri("message_chat_create_uri"); String message_chat_create_uri = getRequestUri("message_chat_create_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
weixinExecutor.post( weixinExecutor.post(
String.format(message_chat_create_uri, token.getAccessToken()), String.format(message_chat_create_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -73,7 +73,7 @@ public class ChatApi extends QyApi {
*/ */
public ChatInfo getChat(String chatId) throws WeixinException { public ChatInfo getChat(String chatId) throws WeixinException {
String message_chat_get_uri = getRequestUri("message_chat_get_uri"); String message_chat_get_uri = getRequestUri("message_chat_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
message_chat_get_uri, token.getAccessToken(), chatId)); message_chat_get_uri, token.getAccessToken(), chatId));
return response.getAsJson().getObject("chat_info", ChatInfo.class); return response.getAsJson().getObject("chat_info", ChatInfo.class);
@ -105,7 +105,7 @@ public class ChatApi extends QyApi {
obj.put("add_user_list", addUsers); obj.put("add_user_list", addUsers);
obj.put("del_user_list", deleteUsers); obj.put("del_user_list", deleteUsers);
String message_chat_update_uri = getRequestUri("message_chat_update_uri"); String message_chat_update_uri = getRequestUri("message_chat_update_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(message_chat_update_uri, token.getAccessToken()), String.format(message_chat_update_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -130,7 +130,7 @@ public class ChatApi extends QyApi {
obj.put("chatid", chatId); obj.put("chatid", chatId);
obj.put("op_user", operator); obj.put("op_user", operator);
String message_chat_quit_uri = getRequestUri("message_chat_quit_uri"); String message_chat_quit_uri = getRequestUri("message_chat_quit_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(message_chat_quit_uri, token.getAccessToken()), String.format(message_chat_quit_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -157,7 +157,7 @@ public class ChatApi extends QyApi {
chat.put("type", chatType.name()); chat.put("type", chatType.name());
chat.put("id", targetId); chat.put("id", targetId);
String message_chat_clearnotify_uri = getRequestUri("message_chat_clearnotify_uri"); String message_chat_clearnotify_uri = getRequestUri("message_chat_clearnotify_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(message_chat_clearnotify_uri, String.format(message_chat_clearnotify_uri,
token.getAccessToken()), token.getAccessToken()),
@ -184,7 +184,7 @@ public class ChatApi extends QyApi {
JSONObject mute = new JSONObject(); JSONObject mute = new JSONObject();
mute.put("user_mute_list", chatMutes); mute.put("user_mute_list", chatMutes);
String message_chat_setmute_uri = getRequestUri("message_chat_setmute_uri"); String message_chat_setmute_uri = getRequestUri("message_chat_setmute_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor WeixinResponse response = weixinExecutor
.post(String.format(message_chat_setmute_uri, .post(String.format(message_chat_setmute_uri,
token.getAccessToken()), mute.toJSONString()); token.getAccessToken()), mute.toJSONString());
@ -216,7 +216,7 @@ public class ChatApi extends QyApi {
msg.put("msgtype", msgtype); msg.put("msgtype", msgtype);
msg.put(msgtype, tuple); msg.put(msgtype, tuple);
String message_chat_send_uri = getRequestUri("message_chat_send_uri"); String message_chat_send_uri = getRequestUri("message_chat_send_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(message_chat_send_uri, token.getAccessToken()), String.format(message_chat_send_uri, token.getAccessToken()),
msg.toJSONString()); msg.toJSONString());

View File

@ -6,7 +6,7 @@ import com.alibaba.fastjson.JSON;
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.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 辅助API * 辅助API
@ -18,10 +18,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
* @see * @see
*/ */
public class HelperApi extends QyApi { public class HelperApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public HelperApi(TokenHolder tokenHolder) { public HelperApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -34,7 +34,7 @@ public class HelperApi extends QyApi {
*/ */
public List<String> getWechatServerIp() throws WeixinException { public List<String> getWechatServerIp() throws WeixinException {
String getcallbackip_uri = getRequestUri("getcallbackip_uri"); String getcallbackip_uri = getRequestUri("getcallbackip_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(getcallbackip_uri, WeixinResponse response = weixinExecutor.get(String.format(getcallbackip_uri,
token.getAccessToken())); token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("ip_list"), return JSON.parseArray(response.getAsJson().getString("ip_list"),

View File

@ -39,7 +39,7 @@ import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.model.Callback; import com.foxinmy.weixin4j.qy.model.Callback;
import com.foxinmy.weixin4j.qy.model.Party; import com.foxinmy.weixin4j.qy.model.Party;
import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpArticle; import com.foxinmy.weixin4j.tuple.MpArticle;
import com.foxinmy.weixin4j.type.MediaType; import com.foxinmy.weixin4j.type.MediaType;
import com.foxinmy.weixin4j.util.FileUtil; import com.foxinmy.weixin4j.util.FileUtil;
@ -61,10 +61,10 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class MediaApi extends QyApi { public class MediaApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public MediaApi(TokenHolder tokenHolder) { public MediaApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -89,7 +89,7 @@ public class MediaApi extends QyApi {
fileName = String.format("%s.jpg", fileName); fileName = String.format("%s.jpg", fileName);
} }
String media_uploadimg_uri = getRequestUri("media_uploadimg_uri"); String media_uploadimg_uri = getRequestUri("media_uploadimg_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(String.format(
media_uploadimg_uri, token.getAccessToken()), media_uploadimg_uri, token.getAccessToken()),
new FormBodyPart("media", new InputStreamBody(is, new FormBodyPart("media", new InputStreamBody(is,
@ -146,7 +146,7 @@ public class MediaApi extends QyApi {
",%s,", suffixName))) { ",%s,", suffixName))) {
mediaType = MediaType.video; mediaType = MediaType.video;
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
try { try {
WeixinResponse response = null; WeixinResponse response = null;
if (agentid > 0) { if (agentid > 0) {
@ -200,7 +200,7 @@ public class MediaApi extends QyApi {
*/ */
public MediaDownloadResult downloadMedia(int agentid, String mediaId) public MediaDownloadResult downloadMedia(int agentid, String mediaId)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
try { try {
HttpRequest request = null; HttpRequest request = null;
if (agentid > 0) { if (agentid > 0) {
@ -273,7 +273,7 @@ public class MediaApi extends QyApi {
*/ */
public String uploadMaterialArticle(int agentid, List<MpArticle> articles) public String uploadMaterialArticle(int agentid, List<MpArticle> articles)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_article_upload_uri = getRequestUri("material_article_upload_uri"); String material_article_upload_uri = getRequestUri("material_article_upload_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("agentid", agentid); obj.put("agentid", agentid);
@ -301,7 +301,7 @@ public class MediaApi extends QyApi {
*/ */
public JsonResult deleteMaterialMedia(int agentid, String mediaId) public JsonResult deleteMaterialMedia(int agentid, String mediaId)
throws WeixinException { throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_media_del_uri = getRequestUri("material_media_del_uri"); String material_media_del_uri = getRequestUri("material_media_del_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
material_media_del_uri, token.getAccessToken(), mediaId, material_media_del_uri, token.getAccessToken(), mediaId,
@ -348,7 +348,7 @@ public class MediaApi extends QyApi {
*/ */
public String updateMaterialArticle(int agentid, String mediaId, public String updateMaterialArticle(int agentid, String mediaId,
List<MpArticle> articles) throws WeixinException { List<MpArticle> articles) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_article_update_uri = getRequestUri("material_article_update_uri"); String material_article_update_uri = getRequestUri("material_article_update_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("agentid", agentid); obj.put("agentid", agentid);
@ -375,7 +375,7 @@ public class MediaApi extends QyApi {
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E6%80%BB%E6%95%B0">获取素材总数</a> * href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%B4%A0%E6%9D%90%E6%80%BB%E6%95%B0">获取素材总数</a>
*/ */
public MediaCounter countMaterialMedia(int agentid) throws WeixinException { public MediaCounter countMaterialMedia(int agentid) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_media_count_uri = getRequestUri("material_media_count_uri"); String material_media_count_uri = getRequestUri("material_media_count_uri");
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
material_media_count_uri, token.getAccessToken(), agentid)); material_media_count_uri, token.getAccessToken(), agentid));
@ -406,7 +406,7 @@ public class MediaApi extends QyApi {
*/ */
public MediaRecord listMaterialMedia(int agentid, MediaType mediaType, public MediaRecord listMaterialMedia(int agentid, MediaType mediaType,
Pageable pageable) throws WeixinException { Pageable pageable) throws WeixinException {
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
String material_media_list_uri = getRequestUri("material_media_list_uri"); String material_media_list_uri = getRequestUri("material_media_list_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("agentid", agentid); obj.put("agentid", agentid);

View File

@ -15,7 +15,7 @@ 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.model.Button; import com.foxinmy.weixin4j.model.Button;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.type.ButtonType; import com.foxinmy.weixin4j.type.ButtonType;
/** /**
@ -29,10 +29,10 @@ import com.foxinmy.weixin4j.type.ButtonType;
*/ */
public class MenuApi extends QyApi { public class MenuApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public MenuApi(TokenHolder tokenHolder) { public MenuApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -51,7 +51,7 @@ public class MenuApi extends QyApi {
*/ */
public JsonResult createMenu(int agentid, List<Button> buttons) throws WeixinException { public JsonResult createMenu(int agentid, List<Button> buttons) throws WeixinException {
String menu_create_uri = getRequestUri("menu_create_uri"); String menu_create_uri = getRequestUri("menu_create_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("button", buttons); obj.put("button", buttons);
WeixinResponse response = weixinExecutor.post(String.format(menu_create_uri, token.getAccessToken(), agentid), WeixinResponse response = weixinExecutor.post(String.format(menu_create_uri, token.getAccessToken(), agentid),
@ -91,7 +91,7 @@ public class MenuApi extends QyApi {
*/ */
public List<Button> getMenu(int agentid) throws WeixinException { public List<Button> getMenu(int agentid) throws WeixinException {
String menu_get_uri = getRequestUri("menu_get_uri"); String menu_get_uri = getRequestUri("menu_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(menu_get_uri, token.getAccessToken(), agentid)); WeixinResponse response = weixinExecutor.get(String.format(menu_get_uri, token.getAccessToken(), agentid));
JSONArray buttons = response.getAsJson().getJSONObject("menu").getJSONArray("button"); JSONArray buttons = response.getAsJson().getJSONObject("menu").getJSONArray("button");
@ -121,7 +121,7 @@ public class MenuApi extends QyApi {
*/ */
public JsonResult deleteMenu(int agentid) throws WeixinException { public JsonResult deleteMenu(int agentid) throws WeixinException {
String menu_delete_uri = getRequestUri("menu_delete_uri"); String menu_delete_uri = getRequestUri("menu_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format(menu_delete_uri, token.getAccessToken(), agentid)); WeixinResponse response = weixinExecutor.get(String.format(menu_delete_uri, token.getAccessToken(), agentid));
return response.getAsJsonResult(); return response.getAsJsonResult();

View File

@ -15,7 +15,8 @@ import com.foxinmy.weixin4j.qy.message.CustomeMessage;
import com.foxinmy.weixin4j.qy.message.NotifyMessage; import com.foxinmy.weixin4j.qy.message.NotifyMessage;
import com.foxinmy.weixin4j.qy.model.IdParameter; import com.foxinmy.weixin4j.qy.model.IdParameter;
import com.foxinmy.weixin4j.qy.type.KfType; import com.foxinmy.weixin4j.qy.type.KfType;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.tuple.MpNews;
import com.foxinmy.weixin4j.tuple.NotifyTuple; import com.foxinmy.weixin4j.tuple.NotifyTuple;
/** /**
@ -39,10 +40,10 @@ import com.foxinmy.weixin4j.tuple.NotifyTuple;
*/ */
public class NotifyApi extends QyApi { public class NotifyApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public NotifyApi(TokenHolder tokenHolder) { public NotifyApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -76,6 +77,11 @@ public class NotifyApi extends QyApi {
public IdParameter sendNotifyMessage(NotifyMessage message) public IdParameter sendNotifyMessage(NotifyMessage message)
throws WeixinException { throws WeixinException {
NotifyTuple tuple = message.getTuple(); NotifyTuple tuple = message.getTuple();
if (tuple instanceof MpNews) {
if (((MpNews) tuple).getArticles().isEmpty()) {
throw new WeixinException("notify fail:articles is required");
}
}
Map<String, String> target = message.getTarget().getParameter(); Map<String, String> target = message.getTarget().getParameter();
String msgtype = tuple.getMessageType(); String msgtype = tuple.getMessageType();
JSONObject obj = (JSONObject) JSON.toJSON(message); JSONObject obj = (JSONObject) JSON.toJSON(message);
@ -87,7 +93,7 @@ public class NotifyApi extends QyApi {
obj.putAll(target); obj.putAll(target);
} }
String message_send_uri = getRequestUri("message_send_uri"); String message_send_uri = getRequestUri("message_send_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(message_send_uri, token.getAccessToken()), String.format(message_send_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -140,7 +146,7 @@ public class NotifyApi extends QyApi {
obj.put("msgtype", msgtype); obj.put("msgtype", msgtype);
obj.put(msgtype, tuple); obj.put(msgtype, tuple);
String message_kf_send_uri = getRequestUri("message_kf_send_uri"); String message_kf_send_uri = getRequestUri("message_kf_send_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(message_kf_send_uri, token.getAccessToken()), String.format(message_kf_send_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -163,7 +169,7 @@ public class NotifyApi extends QyApi {
if (kfType != null) { if (kfType != null) {
message_kf_list_uri += "&type=" + kfType.name(); message_kf_list_uri += "&type=" + kfType.name();
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
message_kf_list_uri, token.getAccessToken())); message_kf_list_uri, token.getAccessToken()));
JSONObject obj = response.getAsJson(); JSONObject obj = response.getAsJson();

View File

@ -9,7 +9,7 @@ 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.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.model.Party; import com.foxinmy.weixin4j.qy.model.Party;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 部门API * 部门API
@ -23,10 +23,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8">管理部门说明</a> * href="http://qydev.weixin.qq.com/wiki/index.php?title=%E7%AE%A1%E7%90%86%E9%83%A8%E9%97%A8">管理部门说明</a>
*/ */
public class PartyApi extends QyApi { public class PartyApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public PartyApi(TokenHolder tokenHolder) { public PartyApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -49,7 +49,7 @@ public class PartyApi extends QyApi {
if (party.getId() < 1) { if (party.getId() < 1) {
obj.remove("id"); obj.remove("id");
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(department_create_uri, token.getAccessToken()), String.format(department_create_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -79,7 +79,7 @@ public class PartyApi extends QyApi {
if (party.getOrder() < 0) { if (party.getOrder() < 0) {
obj.remove("order"); obj.remove("order");
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(department_update_uri, token.getAccessToken()), String.format(department_update_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -102,7 +102,7 @@ public class PartyApi extends QyApi {
if (partId > 0) { if (partId > 0) {
department_list_uri += String.format("&id=%d", partId); department_list_uri += String.format("&id=%d", partId);
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
department_list_uri, token.getAccessToken())); department_list_uri, token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("department"), return JSON.parseArray(response.getAsJson().getString("department"),
@ -121,7 +121,7 @@ public class PartyApi extends QyApi {
*/ */
public JsonResult deleteParty(int partId) throws WeixinException { public JsonResult deleteParty(int partId) throws WeixinException {
String department_delete_uri = getRequestUri("department_delete_uri"); String department_delete_uri = getRequestUri("department_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(String.format(
department_delete_uri, token.getAccessToken(), partId)); department_delete_uri, token.getAccessToken(), partId));
return response.getAsJsonResult(); return response.getAsJsonResult();

View File

@ -2,13 +2,14 @@ package com.foxinmy.weixin4j.qy.api;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.cache.CacheStorager;
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.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.model.OUserInfo; import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.qy.type.LoginTargetType; import com.foxinmy.weixin4j.qy.type.LoginTargetType;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenStorager; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
/** /**
@ -22,13 +23,13 @@ import com.foxinmy.weixin4j.util.StringUtil;
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">企业号登录授权说明</a> * href="http://qydev.weixin.qq.com/wiki/index.php?title=%E4%BC%81%E4%B8%9A%E5%8F%B7%E7%99%BB%E5%BD%95%E6%8E%88%E6%9D%83">企业号登录授权说明</a>
*/ */
public class ProviderApi extends QyApi { public class ProviderApi extends QyApi {
private final TokenHolder providerTokenHolder; private final TokenManager providerTokenManager;
private final TokenStorager tokenStorager; private final CacheStorager<Token> cacheStorager;
public ProviderApi(TokenHolder providerTokenHolder, public ProviderApi(TokenManager providerTokenManager,
TokenStorager tokenStorager) { CacheStorager<Token> cacheStorager) {
this.providerTokenHolder = providerTokenHolder; this.providerTokenManager = providerTokenManager;
this.tokenStorager = tokenStorager; this.cacheStorager = cacheStorager;
} }
/** /**
@ -46,20 +47,22 @@ public class ProviderApi extends QyApi {
String oauth_logininfo_uri = getRequestUri("oauth_logininfo_uri"); String oauth_logininfo_uri = getRequestUri("oauth_logininfo_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(oauth_logininfo_uri, String.format(oauth_logininfo_uri,
providerTokenHolder.getAccessToken()), providerTokenManager.getAccessToken()),
String.format("{\"auth_code\":\"%s\"}", authCode)); String.format("{\"auth_code\":\"%s\"}", authCode));
JSONObject obj = response.getAsJson(); JSONObject obj = response.getAsJson();
OUserInfo oUser = JSON.toJavaObject(obj, OUserInfo.class); OUserInfo oUser = JSON.toJavaObject(obj, OUserInfo.class);
oUser.getRedirectLoginInfo().setAccessToken( obj = obj.getJSONObject("redirect_login_info");
obj.getJSONObject("redirect_login_info").getString( Token loginInfo = new Token(obj.getString("login_ticket"),
"login_ticket")); obj.getLongValue("expires_in") * 1000l);
tokenStorager.caching(getLoginTicketCacheKey(oUser.getCorpInfo() oUser.setRedirectLoginInfo(loginInfo);
cacheStorager.caching(getLoginTicketCacheKey(oUser.getCorpInfo()
.getCorpId()), oUser.getRedirectLoginInfo()); .getCorpId()), oUser.getRedirectLoginInfo());
return oUser; return oUser;
} }
private String getLoginTicketCacheKey(String coprId) { private String getLoginTicketCacheKey(String coprId) {
return String.format("weixin4j_qy_provider_ticket_%s", coprId); return String.format("%sqy_provider_ticket_%s",
TokenCreator.CACHEKEY_PREFIX, coprId);
} }
/** /**
@ -78,7 +81,7 @@ public class ProviderApi extends QyApi {
*/ */
public String getLoginUrl(String corpId, LoginTargetType targetType, public String getLoginUrl(String corpId, LoginTargetType targetType,
int agentId) throws WeixinException { int agentId) throws WeixinException {
Token token = tokenStorager.lookup(getLoginTicketCacheKey(corpId)); Token token = cacheStorager.lookup(getLoginTicketCacheKey(corpId));
if (token == null || StringUtil.isBlank(token.getAccessToken())) { if (token == null || StringUtil.isBlank(token.getAccessToken())) {
throw new WeixinException("maybe oauth first?"); throw new WeixinException("maybe oauth first?");
} }
@ -91,7 +94,7 @@ public class ProviderApi extends QyApi {
} }
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(oauth_loginurl_uri, String.format(oauth_loginurl_uri,
providerTokenHolder.getAccessToken()), providerTokenManager.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
return response.getAsJson().getString("login_url"); return response.getAsJson().getString("login_url");
} }

View File

@ -10,13 +10,13 @@ import com.foxinmy.weixin4j.qy.model.AgentInfo;
import com.foxinmy.weixin4j.qy.model.AgentSetter; import com.foxinmy.weixin4j.qy.model.AgentSetter;
import com.foxinmy.weixin4j.qy.model.OUserInfo; import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.qy.suite.SuitePerCodeHolder; import com.foxinmy.weixin4j.qy.suite.SuitePerCodeManager;
import com.foxinmy.weixin4j.qy.suite.SuiteTicketHolder; import com.foxinmy.weixin4j.qy.suite.SuiteTicketManager;
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.suite.WeixinTokenSuiteCreator;
import com.foxinmy.weixin4j.token.TokenCreator; import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 第三方应用套件 * 第三方应用套件
@ -32,29 +32,29 @@ public class SuiteApi extends QyApi {
/** /**
* 应用套件token * 应用套件token
*/ */
private final TokenHolder suiteTokenHolder; private final TokenManager suiteTokenManager;
/** /**
* 应用套件ticket * 应用套件ticket
*/ */
private final SuiteTicketHolder suiteTicketHolder; private final SuiteTicketManager suiteTicketManager;
/** /**
* 应用套件pre_code * 应用套件pre_code
*/ */
private final TokenHolder suitePreCodeHolder; private final TokenManager suitePreCodeManager;
/** /**
* *
* @param suiteTicketHolder * @param suiteTicketManager
* 套件ticket存取 * 套件ticket存取
*/ */
public SuiteApi(SuiteTicketHolder suiteTicketHolder) { public SuiteApi(SuiteTicketManager suiteTicketManager) {
this.suiteTicketHolder = suiteTicketHolder; this.suiteTicketManager = suiteTicketManager;
this.suiteTokenHolder = new TokenHolder(new WeixinSuiteTokenCreator( this.suiteTokenManager = new TokenManager(new WeixinSuiteTokenCreator(
suiteTicketHolder), suiteTicketHolder.getTokenStorager()); suiteTicketManager), suiteTicketManager.getCacheStorager());
this.suitePreCodeHolder = new TokenHolder( this.suitePreCodeManager = new TokenManager(
new WeixinSuitePreCodeCreator(suiteTokenHolder, new WeixinSuitePreCodeCreator(suiteTokenManager,
suiteTicketHolder.getSuiteId()), suiteTicketManager.getSuiteId()),
suiteTicketHolder.getTokenStorager()); suiteTicketManager.getCacheStorager());
} }
/** /**
@ -62,8 +62,8 @@ public class SuiteApi extends QyApi {
* *
* @return * @return
*/ */
public TokenHolder getSuiteTokenHolder() { public TokenManager getSuiteTokenManager() {
return this.suiteTokenHolder; return this.suiteTokenManager;
} }
/** /**
@ -71,8 +71,8 @@ public class SuiteApi extends QyApi {
* *
* @return * @return
*/ */
public SuiteTicketHolder getTicketHolder() { public SuiteTicketManager getTicketManager() {
return this.suiteTicketHolder; return this.suiteTicketManager;
} }
/** /**
@ -80,8 +80,8 @@ public class SuiteApi extends QyApi {
* *
* @return * @return
*/ */
public TokenHolder getPreCodeHolder() { public TokenManager getPreCodeManager() {
return this.suitePreCodeHolder; return this.suitePreCodeManager;
} }
/** /**
@ -91,10 +91,10 @@ public class SuiteApi extends QyApi {
* 授权方corpid * 授权方corpid
* @return * @return
*/ */
public SuitePerCodeHolder getPerCodeHolder(String authCorpId) { public SuitePerCodeManager getPerCodeManager(String authCorpId) {
return new SuitePerCodeHolder(authCorpId, return new SuitePerCodeManager(authCorpId,
suiteTicketHolder.getSuiteId(), suiteTicketManager.getSuiteId(),
suiteTicketHolder.getTokenStorager()); suiteTicketManager.getCacheStorager());
} }
/** /**
@ -104,10 +104,10 @@ public class SuiteApi extends QyApi {
* 授权方corpid * 授权方corpid
* @return 企业号token * @return 企业号token
*/ */
public TokenHolder getTokenSuiteHolder(String authCorpId) { public TokenManager getTokenSuiteManager(String authCorpId) {
return new TokenHolder(new WeixinTokenSuiteCreator( return new TokenManager(new WeixinTokenSuiteCreator(
getPerCodeHolder(authCorpId), suiteTokenHolder), getPerCodeManager(authCorpId), suiteTokenManager),
suiteTicketHolder.getTokenStorager()); suiteTicketManager.getCacheStorager());
} }
/** /**
@ -124,13 +124,14 @@ public class SuiteApi extends QyApi {
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", suitePreCodeHolder.getAccessToken()); para.put("pre_auth_code", suitePreCodeManager.getAccessToken());
JSONObject appid = new JSONObject(); JSONObject appid = new JSONObject();
appid.put("appid", appids); appid.put("appid", appids);
para.put("session_info", appid); para.put("session_info", appid);
WeixinResponse response = weixinExecutor WeixinResponse response = weixinExecutor.post(
.post(String.format(suite_set_session_uri, String.format(suite_set_session_uri,
suiteTokenHolder.getAccessToken()), para.toJSONString()); suiteTokenManager.getAccessToken()),
para.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
} }
@ -150,28 +151,28 @@ public class SuiteApi extends QyApi {
throws WeixinException { throws WeixinException {
String suite_get_permanent_uri = getRequestUri("suite_get_permanent_uri"); String suite_get_permanent_uri = getRequestUri("suite_get_permanent_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("suite_id", suiteTicketHolder.getSuiteId()); obj.put("suite_id", suiteTicketManager.getSuiteId());
obj.put("auth_code", authCode); obj.put("auth_code", authCode);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor
String.format(suite_get_permanent_uri, .post(String.format(suite_get_permanent_uri,
suiteTokenHolder.getAccessToken()), obj.toJSONString()); suiteTokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
obj.put("corp_info", obj.remove("auth_corp_info")); obj.put("corp_info", obj.remove("auth_corp_info"));
obj.put("user_info", obj.remove("auth_user_info")); obj.put("user_info", obj.remove("auth_user_info"));
OUserInfo oInfo = JSON.toJavaObject(obj, OUserInfo.class); OUserInfo oInfo = JSON.toJavaObject(obj, OUserInfo.class);
// 微信授权企业号的永久授权码 // 微信授权企业号的永久授权码
SuitePerCodeHolder suitePerCodeHolder = getPerCodeHolder(oInfo SuitePerCodeManager suitePerCodeManager = getPerCodeManager(oInfo
.getCorpInfo().getCorpId()); .getCorpInfo().getCorpId());
// 缓存微信企业号access_token // 缓存微信企业号access_token
TokenCreator tokenCreator = new WeixinTokenSuiteCreator( TokenCreator tokenCreator = new WeixinTokenSuiteCreator(
suitePerCodeHolder, suiteTokenHolder); suitePerCodeManager, suiteTokenManager);
Token token = new Token(obj.getString("access_token")); Token token = new Token(obj.getString("access_token"),
token.setExpiresIn(obj.getIntValue("expires_in")); obj.getLongValue("expires_in") * 1000l);
suiteTicketHolder.getTokenStorager().caching( suiteTicketManager.getCacheStorager()
tokenCreator.key(), token); .caching(tokenCreator.key(), token);
// 缓存微信企业号永久授权码 // 缓存微信企业号永久授权码
suitePerCodeHolder suitePerCodeManager.cachingPermanentCode(obj
.cachingPermanentCode(obj.getString("permanent_code")); .getString("permanent_code"));
return oInfo; return oInfo;
} }
@ -189,13 +190,13 @@ public class SuiteApi extends QyApi {
public OUserInfo getOAuthInfo(String authCorpId) throws WeixinException { public OUserInfo getOAuthInfo(String authCorpId) throws WeixinException {
String suite_get_authinfo_uri = getRequestUri("suite_get_authinfo_uri"); String suite_get_authinfo_uri = getRequestUri("suite_get_authinfo_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("suite_id", suiteTicketHolder.getSuiteId()); obj.put("suite_id", suiteTicketManager.getSuiteId());
obj.put("auth_corpid", authCorpId); obj.put("auth_corpid", authCorpId);
obj.put("permanent_code", getPerCodeHolder(authCorpId) obj.put("permanent_code", getPerCodeManager(authCorpId)
.getPermanentCode()); .getPermanentCode());
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor
String.format(suite_get_authinfo_uri, .post(String.format(suite_get_authinfo_uri,
suiteTokenHolder.getAccessToken()), obj.toJSONString()); suiteTokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
obj.put("corp_info", obj.remove("auth_corp_info")); obj.put("corp_info", obj.remove("auth_corp_info"));
obj.put("user_info", obj.remove("auth_user_info")); obj.put("user_info", obj.remove("auth_user_info"));
@ -219,14 +220,14 @@ public class SuiteApi extends QyApi {
throws WeixinException { throws WeixinException {
String suite_get_agent_uri = getRequestUri("suite_get_agent_uri"); String suite_get_agent_uri = getRequestUri("suite_get_agent_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("suite_id", suiteTicketHolder.getSuiteId()); obj.put("suite_id", suiteTicketManager.getSuiteId());
obj.put("auth_corpid", authCorpId); obj.put("auth_corpid", authCorpId);
obj.put("permanent_code", getPerCodeHolder(authCorpId) obj.put("permanent_code", getPerCodeManager(authCorpId)
.getPermanentCode()); .getPermanentCode());
obj.put("agentid", agentid); obj.put("agentid", agentid);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor
String.format(suite_get_agent_uri, .post(String.format(suite_get_agent_uri,
suiteTokenHolder.getAccessToken()), obj.toJSONString()); suiteTokenManager.getAccessToken()), obj.toJSONString());
JSONObject jsonObj = response.getAsJson(); JSONObject jsonObj = response.getAsJson();
AgentInfo agent = JSON.toJavaObject(jsonObj, AgentInfo.class); AgentInfo agent = JSON.toJavaObject(jsonObj, AgentInfo.class);
agent.setAllowUsers(JSON.parseArray( agent.setAllowUsers(JSON.parseArray(
@ -257,14 +258,14 @@ public class SuiteApi extends QyApi {
throws WeixinException { throws WeixinException {
String suite_set_agent_uri = getRequestUri("suite_set_agent_uri"); String suite_set_agent_uri = getRequestUri("suite_set_agent_uri");
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("suite_id", suiteTicketHolder.getSuiteId()); obj.put("suite_id", suiteTicketManager.getSuiteId());
obj.put("auth_corpid", authCorpId); obj.put("auth_corpid", authCorpId);
obj.put("permanent_code", getPerCodeHolder(authCorpId) obj.put("permanent_code", getPerCodeManager(authCorpId)
.getPermanentCode()); .getPermanentCode());
obj.put("agent", agentSet); obj.put("agent", agentSet);
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(suite_set_agent_uri, String.format(suite_set_agent_uri,
suiteTokenHolder.getAccessToken()), suiteTokenManager.getAccessToken()),
JSON.toJSONString(obj, AgentApi.typeFilter)); JSON.toJSONString(obj, AgentApi.typeFilter));
return response.getAsJsonResult(); return response.getAsJsonResult();
} }

View File

@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.qy.model.Contacts;
import com.foxinmy.weixin4j.qy.model.IdParameter; import com.foxinmy.weixin4j.qy.model.IdParameter;
import com.foxinmy.weixin4j.qy.model.Tag; import com.foxinmy.weixin4j.qy.model.Tag;
import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 标签API * 标签API
@ -27,10 +27,10 @@ import com.foxinmy.weixin4j.token.TokenHolder;
* 管理标签</a> * 管理标签</a>
*/ */
public class TagApi extends QyApi { public class TagApi extends QyApi {
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public TagApi(TokenHolder tokenHolder) { public TagApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
} }
/** /**
@ -47,7 +47,7 @@ public class TagApi extends QyApi {
*/ */
public int createTag(Tag tag) throws WeixinException { public int createTag(Tag tag) throws WeixinException {
String tag_create_uri = getRequestUri("tag_create_uri"); String tag_create_uri = getRequestUri("tag_create_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
JSONObject obj = (JSONObject) JSON.toJSON(tag); JSONObject obj = (JSONObject) JSON.toJSON(tag);
if (obj.getIntValue("tagid") <= 0) { if (obj.getIntValue("tagid") <= 0) {
obj.remove("tagid"); obj.remove("tagid");
@ -72,7 +72,7 @@ public class TagApi extends QyApi {
*/ */
public JsonResult updateTag(Tag tag) throws WeixinException { public JsonResult updateTag(Tag tag) throws WeixinException {
String tag_update_uri = getRequestUri("tag_update_uri"); String tag_update_uri = getRequestUri("tag_update_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(tag_update_uri, token.getAccessToken()), String.format(tag_update_uri, token.getAccessToken()),
JSON.toJSONString(tag)); JSON.toJSONString(tag));
@ -92,7 +92,7 @@ public class TagApi extends QyApi {
*/ */
public JsonResult deleteTag(int tagId) throws WeixinException { public JsonResult deleteTag(int tagId) throws WeixinException {
String tag_delete_uri = getRequestUri("tag_delete_uri"); String tag_delete_uri = getRequestUri("tag_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
tag_delete_uri, token.getAccessToken(), tagId)); tag_delete_uri, token.getAccessToken(), tagId));
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -110,7 +110,7 @@ public class TagApi extends QyApi {
*/ */
public List<Tag> listTag() throws WeixinException { public List<Tag> listTag() throws WeixinException {
String tag_list_uri = getRequestUri("tag_list_uri"); String tag_list_uri = getRequestUri("tag_list_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
tag_list_uri, token.getAccessToken())); tag_list_uri, token.getAccessToken()));
return JSON.parseArray(response.getAsJson().getString("taglist"), return JSON.parseArray(response.getAsJson().getString("taglist"),
@ -133,7 +133,7 @@ public class TagApi extends QyApi {
*/ */
public Contacts getTagUsers(int tagId) throws WeixinException { public Contacts getTagUsers(int tagId) throws WeixinException {
String tag_get_user_uri = getRequestUri("tag_get_user_uri"); String tag_get_user_uri = getRequestUri("tag_get_user_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
tag_get_user_uri, token.getAccessToken(), tagId)); tag_get_user_uri, token.getAccessToken(), tagId));
JSONObject obj = response.getAsJson(); JSONObject obj = response.getAsJson();
@ -196,7 +196,7 @@ public class TagApi extends QyApi {
obj.put("tagid", tagId); obj.put("tagid", tagId);
obj.put("userlist", userIds); obj.put("userlist", userIds);
obj.put("partylist", partyIds); obj.put("partylist", partyIds);
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(uri, token.getAccessToken()), obj.toJSONString()); String.format(uri, token.getAccessToken()), obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();

View File

@ -15,7 +15,7 @@ import com.foxinmy.weixin4j.qy.model.OUserInfo;
import com.foxinmy.weixin4j.qy.model.User; import com.foxinmy.weixin4j.qy.model.User;
import com.foxinmy.weixin4j.qy.type.InviteType; import com.foxinmy.weixin4j.qy.type.InviteType;
import com.foxinmy.weixin4j.qy.type.UserStatus; import com.foxinmy.weixin4j.qy.type.UserStatus;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.NameValue; import com.foxinmy.weixin4j.util.NameValue;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
@ -33,11 +33,11 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class UserApi extends QyApi { public class UserApi extends QyApi {
private final MediaApi mediaApi; private final MediaApi mediaApi;
private final TokenHolder tokenHolder; private final TokenManager tokenManager;
public UserApi(TokenHolder tokenHolder) { public UserApi(TokenManager tokenManager) {
this.tokenHolder = tokenHolder; this.tokenManager = tokenManager;
this.mediaApi = new MediaApi(tokenHolder); this.mediaApi = new MediaApi(tokenManager);
} }
/** /**
@ -132,7 +132,7 @@ public class UserApi extends QyApi {
} else { } else {
obj.put("avatar_mediaid", obj.remove("avatar")); obj.put("avatar_mediaid", obj.remove("avatar"));
} }
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(uri, token.getAccessToken()), obj.toJSONString()); String.format(uri, token.getAccessToken()), obj.toJSONString());
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -152,7 +152,7 @@ public class UserApi extends QyApi {
*/ */
public User getUser(String userid) throws WeixinException { public User getUser(String userid) throws WeixinException {
String user_get_uri = getRequestUri("user_get_uri"); String user_get_uri = getRequestUri("user_get_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_get_uri, token.getAccessToken(), userid)); user_get_uri, token.getAccessToken(), userid));
JSONObject obj = response.getAsJson(); JSONObject obj = response.getAsJson();
@ -202,7 +202,7 @@ public class UserApi extends QyApi {
*/ */
public String[] getUserIdByCode(String code) throws WeixinException { public String[] getUserIdByCode(String code) throws WeixinException {
String user_getid_uri = getRequestUri("user_getid_uri"); String user_getid_uri = getRequestUri("user_getid_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_getid_uri, token.getAccessToken(), code)); user_getid_uri, token.getAccessToken(), code));
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
@ -261,7 +261,7 @@ public class UserApi extends QyApi {
UserStatus userStatus, boolean findDetail) throws WeixinException { UserStatus userStatus, boolean findDetail) throws WeixinException {
String user_list_uri = findDetail ? getRequestUri("user_list_uri") String user_list_uri = findDetail ? getRequestUri("user_list_uri")
: getRequestUri("user_slist_uri"); : getRequestUri("user_slist_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
if (userStatus == null) { if (userStatus == null) {
userStatus = UserStatus.UNFOLLOW; userStatus = UserStatus.UNFOLLOW;
} }
@ -316,7 +316,7 @@ public class UserApi extends QyApi {
*/ */
public JsonResult deleteUser(String userid) throws WeixinException { public JsonResult deleteUser(String userid) throws WeixinException {
String user_delete_uri = getRequestUri("user_delete_uri"); String user_delete_uri = getRequestUri("user_delete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_delete_uri, token.getAccessToken(), userid)); user_delete_uri, token.getAccessToken(), userid));
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -338,7 +338,7 @@ public class UserApi extends QyApi {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("useridlist", userIds); obj.put("useridlist", userIds);
String user_delete_uri = getRequestUri("user_batchdelete_uri"); String user_delete_uri = getRequestUri("user_batchdelete_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(String.format(
user_delete_uri, token.getAccessToken(), obj.toJSONString())); user_delete_uri, token.getAccessToken(), obj.toJSONString()));
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -357,7 +357,7 @@ public class UserApi extends QyApi {
*/ */
public JsonResult authsucc(String userId) throws WeixinException { public JsonResult authsucc(String userId) throws WeixinException {
String user_authsucc_uri = getRequestUri("user_authsucc_uri"); String user_authsucc_uri = getRequestUri("user_authsucc_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.get(String.format( WeixinResponse response = weixinExecutor.get(String.format(
user_authsucc_uri, token.getAccessToken(), userId)); user_authsucc_uri, token.getAccessToken(), userId));
return response.getAsJsonResult(); return response.getAsJsonResult();
@ -382,7 +382,7 @@ public class UserApi extends QyApi {
obj.put("userid", userId); obj.put("userid", userId);
obj.put("invite_tips", tips); obj.put("invite_tips", tips);
String invite_user_uri = getRequestUri("invite_user_uri"); String invite_user_uri = getRequestUri("invite_user_uri");
Token token = tokenHolder.getToken(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(invite_user_uri, token.getAccessToken()), String.format(invite_user_uri, token.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
@ -419,7 +419,7 @@ public class UserApi extends QyApi {
} }
String userid2openid_uri = getRequestUri("userid2openid_uri"); String userid2openid_uri = getRequestUri("userid2openid_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(userid2openid_uri, tokenHolder.getAccessToken()), String.format(userid2openid_uri, tokenManager.getAccessToken()),
obj.toJSONString()); obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
return new String[] { obj.getString("openid"), obj.getString("appid") }; return new String[] { obj.getString("openid"), obj.getString("appid") };
@ -440,7 +440,7 @@ public class UserApi extends QyApi {
public String openid2userid(String openid) throws WeixinException { public String openid2userid(String openid) throws WeixinException {
String openid2userid_uri = getRequestUri("openid2userid_uri"); String openid2userid_uri = getRequestUri("openid2userid_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(openid2userid_uri, tokenHolder.getAccessToken()), String.format(openid2userid_uri, tokenManager.getAccessToken()),
String.format("{\"openid\": \"%s\"}", openid)); String.format("{\"openid\": \"%s\"}", openid));
return response.getAsJson().getString("userid"); return response.getAsJson().getString("userid");
} }

View File

@ -3,11 +3,10 @@ package com.foxinmy.weixin4j.qy.jssdk;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.util.DateUtil; import com.foxinmy.weixin4j.util.DateUtil;
import com.foxinmy.weixin4j.util.DigestUtil; import com.foxinmy.weixin4j.util.DigestUtil;
import com.foxinmy.weixin4j.util.MapUtil; import com.foxinmy.weixin4j.util.MapUtil;
@ -23,16 +22,16 @@ import com.foxinmy.weixin4j.util.RandomUtil;
* @see * @see
*/ */
public class JSSDKContactConfigurator { public class JSSDKContactConfigurator {
private final TokenHolder ticketTokenHolder; private final TokenManager ticketTokenManager;
private JSSDKContactParameter contactParameter; private JSSDKContactParameter contactParameter;
/** /**
* ticket保存类 可调用WeixinProxy#getTicketHolder获取 * ticket保存类 可调用WeixinProxy#getTicketManager获取
* *
* @param ticketTokenHolder * @param ticketTokenManager
*/ */
public JSSDKContactConfigurator(TokenHolder ticketTokenHolder) { public JSSDKContactConfigurator(TokenManager ticketTokenManager) {
this.ticketTokenHolder = ticketTokenHolder; this.ticketTokenManager = ticketTokenManager;
this.contactParameter = new JSSDKContactParameter(); this.contactParameter = new JSSDKContactParameter();
} }
@ -180,7 +179,7 @@ public class JSSDKContactConfigurator {
Map<String, String> signMap = new HashMap<String, String>(); Map<String, String> signMap = new HashMap<String, String>();
String timestamp = DateUtil.timestamp2string(); String timestamp = DateUtil.timestamp2string();
String noncestr = RandomUtil.generateString(24); String noncestr = RandomUtil.generateString(24);
Token token = this.ticketTokenHolder.getToken(); Token token = this.ticketTokenManager.getCache();
signMap.put("timestamp", timestamp); signMap.put("timestamp", timestamp);
signMap.put("nonceStr", noncestr); signMap.put("nonceStr", noncestr);
signMap.put("group_ticket", token.getAccessToken()); signMap.put("group_ticket", token.getAccessToken());
@ -189,8 +188,7 @@ public class JSSDKContactConfigurator {
.toJoinString(signMap, false, true)); .toJoinString(signMap, false, true));
JSONObject config = new JSONObject(); JSONObject config = new JSONObject();
config.put("signature", sign); config.put("signature", sign);
config.put("groupId", JSON.parseObject(token.getOriginalResult()) config.put("groupId", token.getExtra().get("group_id"));
.getString("group_id"));
config.put("timestamp", timestamp); config.put("timestamp", timestamp);
config.put("noncestr", noncestr); config.put("noncestr", noncestr);
config.put("params", parameter); config.put("params", parameter);

View File

@ -2,8 +2,6 @@ package com.foxinmy.weixin4j.qy.message;
import java.io.Serializable; import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.qy.type.ChatType; import com.foxinmy.weixin4j.qy.type.ChatType;
import com.foxinmy.weixin4j.tuple.ChatTuple; import com.foxinmy.weixin4j.tuple.ChatTuple;
@ -39,11 +37,8 @@ public class ChatMessage implements Serializable {
*/ */
private ChatTuple chatTuple; private ChatTuple chatTuple;
@JSONCreator public ChatMessage(String targetId, ChatType chatType, String senderId,
public ChatMessage(@JSONField(name = "targetId") String targetId, ChatTuple chatTuple) {
@JSONField(name = "chatType") ChatType chatType,
@JSONField(name = "senderId") String senderId,
@JSONField(name = "chatTuple") ChatTuple chatTuple) {
this.targetId = targetId; this.targetId = targetId;
this.chatType = chatType; this.chatType = chatType;
this.senderId = senderId; this.senderId = senderId;

View File

@ -2,7 +2,6 @@ package com.foxinmy.weixin4j.qy.model;
import java.io.Serializable; import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
/** /**
@ -34,14 +33,12 @@ public class ChatMute implements Serializable {
/** /**
* 传入true时开启免打扰 * 传入true时开启免打扰
* *
* @param userid * @param userId
* 成员userid * 成员userid
* @param status * @param status
* 是否开启免打扰 * 是否开启免打扰
*/ */
@JSONCreator public ChatMute(String userId, boolean status) {
public ChatMute(@JSONField(name = "userId") String userId,
@JSONField(name = "status") boolean status) {
this.userId = userId; this.userId = userId;
this.status = status ? 1 : 0; this.status = status ? 1 : 0;
} }

View File

@ -32,7 +32,7 @@ public class User implements Serializable {
*/ */
private String name; private String name;
/** /**
* 非必须 成员所属部门id列表注意每个部门的直属员工上限为1000个 * 非必须 成员所属部门id列表,不超过20个
*/ */
@JSONField(name = "department") @JSONField(name = "department")
private List<Integer> partyIds; private List<Integer> partyIds;

View File

@ -1,29 +1,30 @@
package com.foxinmy.weixin4j.qy.suite; package com.foxinmy.weixin4j.qy.suite;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenStorager; import com.foxinmy.weixin4j.token.TokenCreator;
/** /**
* 应用套件永久授权码的存取 * 应用套件永久授权码的存取
* *
* @className SuitePerCodeHolder * @className SuitePerCodeManager
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年6月22日 * @date 2015年6月22日
* @since JDK 1.6 * @since JDK 1.6
* @see * @see
*/ */
public class SuitePerCodeHolder { public class SuitePerCodeManager {
private final String authCorpId; private final String authCorpId;
private final String suiteId; private final String suiteId;
private final TokenStorager tokenStorager; private final CacheStorager<Token> cacheStorager;
public SuitePerCodeHolder(String authCorpId, String suiteId, public SuitePerCodeManager(String authCorpId, String suiteId,
TokenStorager tokenStorager) { CacheStorager<Token> cacheStorager) {
this.authCorpId = authCorpId; this.authCorpId = authCorpId;
this.suiteId = suiteId; this.suiteId = suiteId;
this.tokenStorager = tokenStorager; this.cacheStorager = cacheStorager;
} }
/** /**
@ -35,8 +36,7 @@ public class SuitePerCodeHolder {
public void cachingPermanentCode(String permanentCode) public void cachingPermanentCode(String permanentCode)
throws WeixinException { throws WeixinException {
Token token = new Token(permanentCode); Token token = new Token(permanentCode);
token.setExpiresIn(-1); cacheStorager.caching(getCacheKey(), token);
tokenStorager.caching(getCacheKey(), token);
} }
/** /**
@ -45,8 +45,8 @@ public class SuitePerCodeHolder {
* @return * @return
*/ */
public String getCacheKey() { public String getCacheKey() {
return String.format("weixin4j_qy_suite_percode_%s_%s", suiteId, return String.format("%sqy_suite_percode_%s_%s",
authCorpId); TokenCreator.CACHEKEY_PREFIX, suiteId, authCorpId);
} }
/** /**
@ -56,7 +56,7 @@ public class SuitePerCodeHolder {
* @throws WeixinException * @throws WeixinException
*/ */
public String getPermanentCode() throws WeixinException { public String getPermanentCode() throws WeixinException {
return tokenStorager.lookup(getCacheKey()).getAccessToken(); return cacheStorager.lookup(getCacheKey()).getAccessToken();
} }
public String getSuiteId() { public String getSuiteId() {
@ -67,7 +67,7 @@ public class SuitePerCodeHolder {
return this.authCorpId; return this.authCorpId;
} }
public TokenStorager getTokenStorager() { public CacheStorager<Token> getCacheStorager() {
return this.tokenStorager; return this.cacheStorager;
} }
} }

View File

@ -1,29 +1,30 @@
package com.foxinmy.weixin4j.qy.suite; package com.foxinmy.weixin4j.qy.suite;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.token.TokenStorager; import com.foxinmy.weixin4j.token.TokenCreator;
/** /**
* 应用套件ticket的存取 * 应用套件ticket的存取
* *
* @className SuiteTicketHolder * @className SuiteTicketManager
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年6月22日 * @date 2015年6月22日
* @since JDK 1.6 * @since JDK 1.6
* @see * @see
*/ */
public class SuiteTicketHolder { public class SuiteTicketManager {
private final String suiteId; private final String suiteId;
private final String suiteSecret; private final String suiteSecret;
private final TokenStorager tokenStorager; private final CacheStorager<Token> cacheStorager;
public SuiteTicketHolder(String suiteId, String suiteSecret, public SuiteTicketManager(String suiteId, String suiteSecret,
TokenStorager tokenStorager) { CacheStorager<Token> cacheStorager) {
this.suiteId = suiteId; this.suiteId = suiteId;
this.suiteSecret = suiteSecret; this.suiteSecret = suiteSecret;
this.tokenStorager = tokenStorager; this.cacheStorager = cacheStorager;
} }
/** /**
@ -33,7 +34,7 @@ public class SuiteTicketHolder {
* @throws WeixinException * @throws WeixinException
*/ */
public String getTicket() throws WeixinException { public String getTicket() throws WeixinException {
return tokenStorager.lookup(getCacheKey()).getAccessToken(); return cacheStorager.lookup(getCacheKey()).getAccessToken();
} }
/** /**
@ -42,7 +43,8 @@ public class SuiteTicketHolder {
* @return * @return
*/ */
public String getCacheKey() { public String getCacheKey() {
return String.format("weixin4j_qy_suite_ticket_%s", suiteId); return String.format("%sqy_suite_ticket_%s",
TokenCreator.CACHEKEY_PREFIX, suiteId);
} }
/** /**
@ -53,8 +55,7 @@ public class SuiteTicketHolder {
*/ */
public void cachingTicket(String ticket) throws WeixinException { public void cachingTicket(String ticket) throws WeixinException {
Token token = new Token(ticket); Token token = new Token(ticket);
token.setExpiresIn(-1); cacheStorager.caching(getCacheKey(), token);
tokenStorager.caching(getCacheKey(), token);
} }
public String getSuiteId() { public String getSuiteId() {
@ -65,7 +66,7 @@ public class SuiteTicketHolder {
return this.suiteSecret; return this.suiteSecret;
} }
public TokenStorager getTokenStorager() { public CacheStorager<Token> getCacheStorager() {
return this.tokenStorager; return this.cacheStorager;
} }
} }

View File

@ -3,6 +3,9 @@ package com.foxinmy.weixin4j.qy.suite;
import java.util.Arrays; import java.util.Arrays;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.cache.FileCacheStorager;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.model.WeixinAccount; import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.qy.model.WeixinQyAccount; import com.foxinmy.weixin4j.qy.model.WeixinQyAccount;
import com.foxinmy.weixin4j.setting.SystemSettings; import com.foxinmy.weixin4j.setting.SystemSettings;
@ -19,6 +22,10 @@ import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
* @see * @see
*/ */
public class Weixin4jSuiteSettings extends SystemSettings<WeixinQyAccount> { public class Weixin4jSuiteSettings extends SystemSettings<WeixinQyAccount> {
/**
* Token的存储方式 默认为FileCacheStorager
*/
private CacheStorager<Token> cacheStorager;
/** /**
* 默认使用weixin4j.properties配置的信息 * 默认使用weixin4j.properties配置的信息
@ -61,6 +68,17 @@ public class Weixin4jSuiteSettings extends SystemSettings<WeixinQyAccount> {
return getTmpdir(); return getTmpdir();
} }
public CacheStorager<Token> getCacheStorager() {
return cacheStorager;
}
public CacheStorager<Token> getCacheStorager0() {
if (cacheStorager == null) {
return new FileCacheStorager<Token>(getTmpdir0());
}
return cacheStorager;
}
@Override @Override
public String toString() { public String toString() {
return "Weixin4jSuiteSettings [" + super.toString() + "]"; return "Weixin4jSuiteSettings [" + super.toString() + "]";

View File

@ -6,7 +6,7 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.type.URLConsts; import com.foxinmy.weixin4j.qy.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenCreator; import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 微信企业号应用套件预授权码创建 * 微信企业号应用套件预授权码创建
@ -22,18 +22,19 @@ import com.foxinmy.weixin4j.token.TokenHolder;
*/ */
public class WeixinSuitePreCodeCreator extends TokenCreator { public class WeixinSuitePreCodeCreator extends TokenCreator {
private final TokenHolder suiteTokenHolder; private final TokenManager suiteTokenManager;
private final String suiteId; private final String suiteId;
/** /**
* *
* @param suiteTokenHolder * @param suiteTokenManager
* 应用套件的token * 应用套件的token
* @param suiteId * @param suiteId
* 应用套件ID * 应用套件ID
*/ */
public WeixinSuitePreCodeCreator(TokenHolder suiteTokenHolder, String suiteId) { public WeixinSuitePreCodeCreator(TokenManager suiteTokenManager,
this.suiteTokenHolder = suiteTokenHolder; String suiteId) {
this.suiteTokenManager = suiteTokenManager;
this.suiteId = suiteId; this.suiteId = suiteId;
} }
@ -45,12 +46,11 @@ public class WeixinSuitePreCodeCreator extends TokenCreator {
@Override @Override
public Token create() throws WeixinException { public Token create() throws WeixinException {
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor.post(
String.format(URLConsts.SUITE_PRE_CODE_URL, suiteTokenHolder.getAccessToken()), String.format(URLConsts.SUITE_PRE_CODE_URL,
suiteTokenManager.getAccessToken()),
String.format("{\"suite_id\":\"%s\"}", suiteId)); String.format("{\"suite_id\":\"%s\"}", suiteId));
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
Token token = new Token(result.getString("pre_auth_code")); return new Token(result.getString("pre_auth_code"),
token.setExpiresIn(result.getIntValue("expires_in")); result.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.qy.suite; package com.foxinmy.weixin4j.qy.suite;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
@ -20,34 +20,32 @@ import com.foxinmy.weixin4j.token.TokenCreator;
*/ */
public class WeixinSuiteTokenCreator extends TokenCreator { public class WeixinSuiteTokenCreator extends TokenCreator {
private final SuiteTicketHolder ticketHolder; private final SuiteTicketManager ticketManager;
/** /**
* *
* @param stringStorager * @param ticketManager
* 套件ticket存取 * 套件ticket存取
*/ */
public WeixinSuiteTokenCreator(SuiteTicketHolder ticketHolder) { public WeixinSuiteTokenCreator(SuiteTicketManager ticketManager) {
this.ticketHolder = ticketHolder; this.ticketManager = ticketManager;
} }
@Override @Override
public String key0() { public String key0() {
return String.format("qy_suite_token_%s", ticketHolder.getSuiteId()); return String.format("qy_suite_token_%s", ticketManager.getSuiteId());
} }
@Override @Override
public Token create() throws WeixinException { public Token create() throws WeixinException {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("suite_id", ticketHolder.getSuiteId()); obj.put("suite_id", ticketManager.getSuiteId());
obj.put("suite_secret", ticketHolder.getSuiteSecret()); obj.put("suite_secret", ticketManager.getSuiteSecret());
obj.put("suite_ticket", ticketHolder.getTicket()); obj.put("suite_ticket", ticketManager.getTicket());
WeixinResponse response = weixinExecutor.post(URLConsts.SUITE_TOKEN_URL, WeixinResponse response = weixinExecutor.post(
obj.toJSONString()); URLConsts.SUITE_TOKEN_URL, obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
Token token = new Token(obj.getString("suite_access_token")); return new Token(obj.getString("suite_access_token"),
token.setExpiresIn(obj.getIntValue("expires_in")); obj.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -6,7 +6,7 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.type.URLConsts; import com.foxinmy.weixin4j.qy.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenCreator; import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
/** /**
* 微信企业号token创建(永久授权码) * 微信企业号token创建(永久授权码)
@ -22,38 +22,39 @@ import com.foxinmy.weixin4j.token.TokenHolder;
*/ */
public class WeixinTokenSuiteCreator extends TokenCreator { public class WeixinTokenSuiteCreator extends TokenCreator {
private final SuitePerCodeHolder perCodeHolder; private final SuitePerCodeManager perCodeManager;
private final TokenHolder suiteTokenHolder; private final TokenManager suiteTokenManager;
/** /**
* *
* @param perCodeHolder * @param perCodeManager
* 第三方套件永久授权码 * 第三方套件永久授权码
* @param suiteTokenHolder * @param suitetokenManager
* 第三方套件凭证token * 第三方套件凭证token
*/ */
public WeixinTokenSuiteCreator(SuitePerCodeHolder perCodeHolder, TokenHolder suiteTokenHolder) { public WeixinTokenSuiteCreator(SuitePerCodeManager perCodeManager,
this.perCodeHolder = perCodeHolder; TokenManager suiteTokenManager) {
this.suiteTokenHolder = suiteTokenHolder; this.perCodeManager = perCodeManager;
this.suiteTokenManager = suiteTokenManager;
} }
@Override @Override
public String key0() { public String key0() {
return String.format("qy_token_suite_%s_%s", perCodeHolder.getSuiteId(), perCodeHolder.getAuthCorpId()); return String.format("qy_token_suite_%s_%s",
perCodeManager.getSuiteId(), perCodeManager.getAuthCorpId());
} }
@Override @Override
public Token create() throws WeixinException { public Token create() throws WeixinException {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("suite_id", perCodeHolder.getSuiteId()); obj.put("suite_id", perCodeManager.getSuiteId());
obj.put("auth_corpid", perCodeHolder.getAuthCorpId()); obj.put("auth_corpid", perCodeManager.getAuthCorpId());
obj.put("permanent_code", perCodeHolder.getPermanentCode()); obj.put("permanent_code", perCodeManager.getPermanentCode());
WeixinResponse response = weixinExecutor WeixinResponse response = weixinExecutor
.post(String.format(URLConsts.TOKEN_SUITE_URL, suiteTokenHolder.getAccessToken()), obj.toJSONString()); .post(String.format(URLConsts.TOKEN_SUITE_URL,
suiteTokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
Token token = new Token(obj.getString("access_token")); return new Token(obj.getString("access_token"),
token.setExpiresIn(obj.getIntValue("expires_in")); obj.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -10,7 +10,7 @@ import com.foxinmy.weixin4j.token.TokenCreator;
/** /**
* 微信企业号应用提供商凭证创建 * 微信企业号应用提供商凭证创建
* *
* @className WeixinTokenCreator * @className WeixinProviderTokenCreator
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年1月10日 * @date 2015年1月10日
* @since JDK 1.6 * @since JDK 1.6
@ -46,11 +46,10 @@ public class WeixinProviderTokenCreator extends TokenCreator {
JSONObject obj = new JSONObject(); JSONObject obj = new JSONObject();
obj.put("corpid", corpid); obj.put("corpid", corpid);
obj.put("provider_secret", providersecret); obj.put("provider_secret", providersecret);
WeixinResponse response = weixinExecutor.post(URLConsts.PROVIDER_TOKEN_URL, obj.toJSONString()); WeixinResponse response = weixinExecutor.post(
URLConsts.PROVIDER_TOKEN_URL, obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
Token token = new Token(obj.getString("provider_access_token")); return new Token(obj.getString("provider_access_token"),
token.setExpiresIn(obj.getIntValue("expires_in")); obj.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -6,7 +6,7 @@ import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.qy.type.URLConsts; import com.foxinmy.weixin4j.qy.type.URLConsts;
import com.foxinmy.weixin4j.token.TokenCreator; import com.foxinmy.weixin4j.token.TokenCreator;
import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.token.TokenManager;
import com.foxinmy.weixin4j.type.TicketType; import com.foxinmy.weixin4j.type.TicketType;
/** /**
@ -23,20 +23,21 @@ public class WeixinTicketCreator extends TokenCreator {
private final String corpid; private final String corpid;
private final TicketType ticketType; private final TicketType ticketType;
private final TokenHolder weixinTokenHolder; private final TokenManager weixinTokenManager;
/** /**
* @param corpid * @param corpid
* 企业号ID * 企业号ID
* @param ticketType * @param ticketType
* 票据类型 * 票据类型
* @param weixinTokenHolder * @param weixinTokenManager
* <font color="red">企业号的access_token</font> * <font color="red">企业号的access_token</font>
*/ */
public WeixinTicketCreator(String corpid, TicketType ticketType, TokenHolder weixinTokenHolder) { public WeixinTicketCreator(String corpid, TicketType ticketType,
TokenManager weixinTokenManager) {
this.corpid = corpid; this.corpid = corpid;
this.ticketType = ticketType; this.ticketType = ticketType;
this.weixinTokenHolder = weixinTokenHolder; this.weixinTokenManager = weixinTokenManager;
} }
@Override @Override
@ -48,16 +49,16 @@ public class WeixinTicketCreator extends TokenCreator {
public Token create() throws WeixinException { public Token create() throws WeixinException {
WeixinResponse response = null; WeixinResponse response = null;
if (ticketType == TicketType.jsapi) { if (ticketType == TicketType.jsapi) {
response = weixinExecutor response = weixinExecutor.get(String.format(
.get(String.format(URLConsts.JS_TICKET_URL, weixinTokenHolder.getToken().getAccessToken())); URLConsts.JS_TICKET_URL, weixinTokenManager.getCache()
.getAccessToken()));
} else { } else {
response = weixinExecutor.get(String.format(URLConsts.SUITE_TICKET_URL, response = weixinExecutor.get(String.format(
weixinTokenHolder.getToken().getAccessToken(), ticketType.name())); URLConsts.SUITE_TICKET_URL, weixinTokenManager.getCache()
.getAccessToken(), ticketType.name()));
} }
JSONObject result = response.getAsJson(); JSONObject result = response.getAsJson();
Token token = new Token(result.getString("ticket")); return new Token(result.getString("ticket"),
token.setExpiresIn(result.getIntValue("expires_in")); result.getLong("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

View File

@ -1,6 +1,6 @@
package com.foxinmy.weixin4j.qy.token; package com.foxinmy.weixin4j.qy.token;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.JSONObject;
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.Token; import com.foxinmy.weixin4j.model.Token;
@ -46,10 +46,8 @@ public class WeixinTokenCreator extends TokenCreator {
String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, corpid, String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, corpid,
corpsecret); corpsecret);
WeixinResponse response = weixinExecutor.get(tokenUrl); WeixinResponse response = weixinExecutor.get(tokenUrl);
Token token = response.getAsObject(new TypeReference<Token>() { JSONObject result = response.getAsJson();
}); return new Token(result.getString("access_token"),
token.setCreateTime(System.currentTimeMillis()); result.getLongValue("expires_in") * 1000l);
token.setOriginalResult(response.getAsString());
return token;
} }
} }

Some files were not shown because too many files have changed in this diff Show More