diff --git a/CHANGE.md b/CHANGE.md index 8f5087d1..39236993 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -683,4 +683,8 @@ * 2016-05-07 - + version upgrade to 1.6.9 \ No newline at end of file + + version upgrade to 1.6.9 + +* 2016-05-12 + + + 添加MemcacheTokenStorager支持 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 3fed2489..bae4e08b 100644 --- a/pom.xml +++ b/pom.xml @@ -229,10 +229,6 @@ org.apache.maven.plugins maven-javadoc-plugin - - org.apache.maven.plugins - maven-gpg-plugin - diff --git a/weixin4j-base/CHANGE.md b/weixin4j-base/CHANGE.md index 688ce874..fc34c5f1 100644 --- a/weixin4j-base/CHANGE.md +++ b/weixin4j-base/CHANGE.md @@ -145,4 +145,8 @@ + 新增海关接口 - + 添加日志支持 \ No newline at end of file + + 添加日志支持 + +* 2016-05-12 + + + 添加MemcacheTokenStorager支持 \ No newline at end of file diff --git a/weixin4j-base/pom.xml b/weixin4j-base/pom.xml index f4342253..ce8cfc0c 100644 --- a/weixin4j-base/pom.xml +++ b/weixin4j-base/pom.xml @@ -45,6 +45,12 @@ 2.6.0 true + + com.meetup + memcached-client + 2.6.6 + true + org.slf4j slf4j-api diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenStorager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenStorager.java index 203d3e89..015cad6b 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenStorager.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenStorager.java @@ -12,7 +12,7 @@ import com.foxinmy.weixin4j.util.FileUtil; import com.foxinmy.weixin4j.xml.XmlStream; /** - * 用FILE保存TOKEN + * 用File形式保存Token信息 * * @className FileTokenStorager * @author jy @@ -29,14 +29,17 @@ public class FileTokenStorager implements TokenStorager { @Override public Token lookup(String cacheKey) throws WeixinException { - File token_file = new File(String.format("%s/%s.xml", cachePath, 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); + Token token = XmlStream.fromXML( + new FileInputStream(token_file), Token.class); if (token.getCreateTime() < 0) { return token; } - if ((token.getCreateTime() + (token.getExpiresIn() * 1000l) - CUTMS) > System.currentTimeMillis()) { + if ((token.getCreateTime() + (token.getExpiresIn() * 1000l) - CUTMS) > System + .currentTimeMillis()) { return token; } } @@ -49,7 +52,10 @@ public class FileTokenStorager implements TokenStorager { @Override public void caching(String cacheKey, Token token) throws WeixinException { try { - XmlStream.toXML(token, new FileOutputStream(new File(String.format("%s/%s.xml", cachePath, cacheKey)))); + XmlStream.toXML( + token, + new FileOutputStream(new File(String.format("%s/%s.xml", + cachePath, cacheKey)))); } catch (IOException e) { throw new WeixinException(e); } @@ -58,10 +64,12 @@ public class FileTokenStorager implements TokenStorager { @Override public Token evict(String cacheKey) throws WeixinException { Token token = null; - File token_file = new File(String.format("%s/%s.xml", cachePath, cacheKey)); + 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 = XmlStream.fromXML(new FileInputStream(token_file), + Token.class); token_file.delete(); } } catch (IOException e) { @@ -75,8 +83,10 @@ public class FileTokenStorager implements TokenStorager { 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())); + return file.isFile() + && file.getName().startsWith(PREFIX) + && "xml".equals(FileUtil.getFileExtension(file + .getName())); } }); for (File token : files) { diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemcacheTokenStorager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemcacheTokenStorager.java new file mode 100644 index 00000000..93414a9a --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemcacheTokenStorager.java @@ -0,0 +1,216 @@ +package com.foxinmy.weixin4j.token; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import com.danga.MemCached.MemCachedClient; +import com.danga.MemCached.SockIOPool; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.model.Token; + +/** + * 用Memcache保存Token信息(推荐使用) + * + * @className MemcacheTokenStorager + * @author jy + * @date 2016年5月11日 + * @since JDK 1.6 + * @see + */ +public class MemcacheTokenStorager implements TokenStorager { + + private final MemCachedClient mc; + + public MemcacheTokenStorager(MemcachePoolConfig poolConfig) { + mc = new MemCachedClient(); + poolConfig.initSocketIO(); + } + + @Override + public Token lookup(String cacheKey) throws WeixinException { + return (Token) mc.get(cacheKey); + } + + @Override + public void caching(String cacheKey, Token token) throws WeixinException { + if (token.getExpiresIn() > 0) { + mc.set(cacheKey, token, + new Date(token.getCreateTime() + token.getExpiresIn() + * 1000 - CUTMS)); + } else { + mc.set(cacheKey, token); + } + } + + @Override + public Token evict(String cacheKey) throws WeixinException { + Token token = lookup(cacheKey); + mc.delete(cacheKey); + return token; + } + + @Override + public void clear() throws WeixinException { + throw new UnsupportedOperationException(); + } + + public static class MemcachePoolConfig { + public final static String HOST = "localhost"; + public final static int PORT = 11211; + public final static int WEIGHT = 1; + + public static int minConn = 5; + public static int initConn = 5; + public static int maxConn = 100; + public static long maxIdle = 300000L; + public static long maxBusyTime = 30000L; + public static int socketTO = 3000; + public static int socketConnectTO = 3000; + public static boolean failover = true; + public static boolean failback = true; + public static boolean nagle = false; + public static boolean aliveCheck = false; + public static final int consistentHash = 3; + public static final int mainSleep = 30000; + + private static SockIOPool pool; + static { + pool = SockIOPool.getInstance(); + pool.setFailback(failback); + pool.setFailover(failover); + pool.setMaxBusyTime(maxBusyTime); + pool.setMaxConn(maxConn); + pool.setMaxIdle(maxIdle); + pool.setMinConn(minConn); + pool.setNagle(nagle); + pool.setSocketConnectTO(socketConnectTO); + pool.setSocketTO(socketTO); + pool.setAliveCheck(aliveCheck); + pool.setHashingAlg(consistentHash); + pool.setInitConn(initConn); + pool.setMaintSleep(maxBusyTime); + } + + private List configs; + private String[] servers; + private Integer[] weights; + + /** + * {localhost:11211,1} + */ + public MemcachePoolConfig() { + this(HOST, PORT, WEIGHT); + } + + /** + * {host:11211,1} + * + * @param host + * 主机 + */ + public MemcachePoolConfig(String host) { + this(host, PORT); + } + + /** + * {host:port,1} + * + * @param host + * 主机 + * @param port + * 端口 + */ + public MemcachePoolConfig(String host, int port) { + this(host, port, WEIGHT); + } + + /** + * {host:port,weight} + * + * @param host + * 主机 + * @param port + * 端口 + * @param weight + * 权重 + */ + public MemcachePoolConfig(String host, int port, int weight) { + configs = new ArrayList(); + configs.add(new MemcacheConfig(host, port, weight)); + } + + public MemcachePoolConfig addServer(String host) { + return addServer(host, PORT, WEIGHT); + } + + public MemcachePoolConfig addServer(String host, int port) { + return addServer(host, port, WEIGHT); + } + + public MemcachePoolConfig addServer(String host, int port, int weight) { + configs.add(new MemcacheConfig(host, port, weight)); + return this; + } + + private void initConfig() { + if (servers == null || weights == null) { + servers = new String[configs.size()]; + weights = new Integer[configs.size()]; + for (int i = 0; i < configs.size(); i++) { + servers[i] = configs.get(i).getServer(); + weights[i] = configs.get(i).getWeight(); + } + } + } + + private void initSocketIO() { + pool.setServers(getServers()); + pool.setWeights(getWeights()); + if (pool.isInitialized()) { + pool.shutDown(); + } + pool.initialize(); + } + + public String[] getServers() { + initConfig(); + return servers; + } + + public Integer[] getWeights() { + initConfig(); + return weights; + } + + @Override + public String toString() { + return "MemcachePoolConfig [" + configs + "]"; + } + + private static class MemcacheConfig { + private String host; + private int port; + private int weight; + + public MemcacheConfig(String host, int port, int weight) { + this.host = host; + this.port = port; + this.weight = weight; + } + + public String getServer() { + return String.format("%s:%d", host, port); + } + + public int getWeight() { + return weight; + } + + @Override + public String toString() { + return String.format("{%s:%d,%d}", host, port, weight); + } + } + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemoryTokenStorager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemoryTokenStorager.java index 3436bde3..a82a25a4 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemoryTokenStorager.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/MemoryTokenStorager.java @@ -7,7 +7,7 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.model.Token; /** - * 用内存保存TOKEN(不推荐使用) + * 用内存保存Token信息(不推荐使用) * * @className MemoryTokenStorager * @author jy diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/README.md b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/README.md index 901dd211..6075d3d4 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/README.md +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/README.md @@ -8,4 +8,6 @@ * FileTokenStorager 是系统默认的token存储策略实现 -* RedisTokenStorager 如果服务器支持redis,推荐使用(需要自己添加jedis包) +* RedisTokenStorager 使用redis保存token(需要自行添加客户端包,[jedis](https://github.com/xetorthio/jedis)) + +* MemcacheTokenStorager 使用memcache保存token(需要自行添加客户端包,[Memcached-Java-Client](https://github.com/gwhalin/Memcached-Java-Client)) diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenStorager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenStorager.java index 3cfd78b7..4bd4ec74 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenStorager.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenStorager.java @@ -13,7 +13,7 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.model.Token; /** - * 用REDIS保存TOKEN(推荐使用) + * 用Redis保存Token信息(推荐使用) * * @className RedisTokenStorager * @author jy @@ -24,15 +24,16 @@ public class RedisTokenStorager implements 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 = 2000; + 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("localhost", PORT); + this(HOST, PORT); } public RedisTokenStorager(String host, int port) { @@ -45,7 +46,8 @@ public class RedisTokenStorager implements TokenStorager { this.jedisPool = new JedisPool(jedisPoolConfig, host, port); } - public RedisTokenStorager(String host, int port, JedisPoolConfig jedisPoolConfig) { + public RedisTokenStorager(String host, int port, + JedisPoolConfig jedisPoolConfig) { this(new JedisPool(jedisPoolConfig, host, port)); } @@ -77,7 +79,8 @@ public class RedisTokenStorager implements TokenStorager { jedis = jedisPool.getResource(); jedis.hmset(cacheKey, token2map(token)); if (token.getExpiresIn() > 0) { - jedis.expire(cacheKey, token.getExpiresIn() - (int) (CUTMS / 1000l)); + jedis.expire(cacheKey, token.getExpiresIn() + - (int) (CUTMS / 1000l)); } } finally { if (jedis != null) { diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenStorager.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenStorager.java index 61de6eac..089567a2 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenStorager.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenStorager.java @@ -13,6 +13,7 @@ import com.foxinmy.weixin4j.model.Token; * @see MemoryTokenStorager * @see FileTokenStorager * @see RedisTokenStorager + * @see MemcacheTokenStorager */ public interface TokenStorager extends CacheStorager { /** diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/CardColor.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/CardColor.java new file mode 100644 index 00000000..cf7e5aec --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/CardColor.java @@ -0,0 +1,48 @@ +package com.foxinmy.weixin4j.mp.type; + +/** + * 卡券颜色 + * + * @className CardColor + * @author jy + * @date 2016年4月4日 + * @since JDK 1.6 + * @see + */ +public enum CardColor { + COLOR010(99, 179, 89, "#63b359"), COLOR020(44, 159, 103, "#2c9f67"), COLOR030( + 80, 159, 201, "#509fc9"), COLOR040(88, 133, 207, "#5885cf"), COLOR050( + 144, 98, 192, "#9062c0"), COLOR060(208, 154, 69, "#d09a45"), COLOR070( + 228, 117, 56, "#e4b138"), COLOR080(238, 144, 60, "#ee903c"), COLOR081( + 240, 133, 0, "#f08500"), COLOR082(169, 217, 45, "#a9d92d"), COLOR090( + 221, 101, 73, "#dd6549"), COLOR0100(204, 70, 61, "#cc463d"), COLOR0101( + 207, 62, 54, "#cf3e36"), COLOR0102(94, 102, 113, "#5E6671"); + private int r; + private int g; + private int b; + private String hex; + + CardColor(int r, int g, int b, String hex) { + this.r = r; + this.g = g; + this.b = b; + this.hex = hex; + ; + } + + public int getR() { + return r; + } + + public int getG() { + return g; + } + + public int getB() { + return b; + } + + public String getHex() { + return hex; + } +} diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/CardType.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/CardType.java new file mode 100644 index 00000000..7440a6d1 --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/type/CardType.java @@ -0,0 +1,33 @@ +package com.foxinmy.weixin4j.mp.type; + +/** + * 卡券类型 + * + * @className CardType + * @author jy + * @date 2016年4月4日 + * @since JDK 1.6 + * @see + */ +public enum CardType { + /** + * 团购券 + */ + GROUPON, + /** + * 代金券 + */ + CASH, + /** + * 折扣券 + */ + DISCOUNT, + /** + * 兑换券 + */ + GIFT, + /** + * 优惠券 + */ + GENERAL_COUPON; +} diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTokenCreator.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTokenCreator.java index 3eaa35b0..9a4ae6f8 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTokenCreator.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/token/WeixinTokenCreator.java @@ -46,7 +46,8 @@ public class WeixinTokenCreator extends AbstractTokenCreator { @Override public Token createToken() throws WeixinException { - String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, corpid, corpsecret); + String tokenUrl = String.format(URLConsts.ASSESS_TOKEN_URL, corpid, + corpsecret); WeixinResponse response = weixinExecutor.get(tokenUrl); Token token = response.getAsObject(new TypeReference() { });