From 5b213cd87fbc7a2291796a80a2de4499f5298c59 Mon Sep 17 00:00:00 2001 From: "jy.hu" Date: Wed, 19 Nov 2014 21:26:11 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BC=81=E4=B8=9A=E5=8F=B7?= =?UTF-8?q?=E5=B7=A5=E7=A8=8B=E5=B9=B6=E5=AE=8C=E6=88=90=E3=80=90=E9=83=A8?= =?UTF-8?q?=E9=97=A8=E7=AE=A1=E7=90=86=E3=80=91=E3=80=90=E6=88=90=E5=91=98?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E3=80=91=E3=80=90=E6=A0=87=E7=AD=BE=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E3=80=91=E4=B8=89=E4=B8=AA=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 12 + pom.xml | 23 ++ weixin4j-base/README.md | 6 +- .../java/com/foxinmy/weixin4j/http/error.xml | 365 +++++++++++++++++- .../com/foxinmy/weixin4j/model/Consts.java | 8 + .../com/foxinmy/weixin4j/model/Gender.java | 14 + .../foxinmy/weixin4j/model/WeixinAccount.java | 212 ++-------- .../weixin4j/model/WeixinMpAccount.java | 178 +++++++++ .../weixin4j/model/WeixinQyAccount.java | 34 ++ .../com/foxinmy/weixin4j/msg/BaseMessage.java | 48 --- .../weixin4j/token/AbstractTokenHolder.java | 19 +- .../weixin4j/token/FileTokenHolder.java | 24 +- .../weixin4j/token/RedisTokenHolder.java | 42 +- .../foxinmy/weixin4j/token/TokenHolder.java | 1 - .../foxinmy/weixin4j/type/AccountType.java | 14 + .../com/foxinmy/weixin4j/util/ConfigUtil.java | 12 +- weixin4j-mp/pom.xml | 23 -- weixin4j-mp/weixin4j-mp-api/README.md | 3 +- weixin4j-mp/weixin4j-mp-api/pom.xml | 2 +- .../com/foxinmy/weixin4j/mp/WeixinProxy.java | 15 +- .../foxinmy/weixin4j/mp/api/HelperApi.java | 6 +- .../com/foxinmy/weixin4j/mp/api/PayApi.java | 16 +- .../com/foxinmy/weixin4j/mp/api/TmplApi.java | 5 +- .../com/foxinmy/weixin4j/mp/api/UserApi.java | 2 +- .../com/foxinmy/weixin4j/mp/model/Group.java | 5 +- .../com/foxinmy/weixin4j/mp/model/User.java | 2 +- .../weixin4j/mp/msg/notify/BaseNotify.java | 26 +- .../weixin4j/mp/payment/MicroPayPackage.java | 6 +- .../weixin4j/mp/payment/PayAction.java | 16 +- .../foxinmy/weixin4j/mp/payment/PayUtil.java | 44 +-- .../mp/payment/v2/JsPayRequestV2.java | 6 +- .../mp/payment/v2/NativePayResponseV2.java | 4 +- .../weixin4j/mp/payment/v3/PayPackageV3.java | 8 +- .../weixin4j/mp/response/BaseResponse.java | 35 +- .../weixin4j/mp/response/TemplateMessage.java | 10 - .../com/foxinmy/weixin4j/mp/type/Gender.java | 23 -- .../src/main/resources/weixin.properties | 2 +- .../foxinmy/weixin4j/mp/test/TokenTest.java | 3 +- weixin4j-mp/weixin4j-mp-server/README.md | 4 +- weixin4j-mp/weixin4j-mp-server/pom.xml | 2 +- .../mp/server/WeixinMessageDecoder.java | 10 +- .../mp/server/WeixinMessageEncoder.java | 10 +- .../src/main/resources/weixin.properties | 2 +- weixin4j-qy/README.md | 20 +- weixin4j-qy/pom.xml | 12 + weixin4j-qy/weixin4j-qy-api/.gitignore | 28 ++ weixin4j-qy/weixin4j-qy-api/README.md | 56 +++ weixin4j-qy/weixin4j-qy-api/pom.xml | 24 ++ .../weixin4j-qy-api/src/main/assembly.xml | 31 ++ .../com/foxinmy/weixin4j/qy/WeixinProxy.java | 344 +++++++++++++++++ .../com/foxinmy/weixin4j/qy/api/BaseApi.java | 57 +++ .../foxinmy/weixin4j/qy/api/DepartApi.java | 110 ++++++ .../com/foxinmy/weixin4j/qy/api/TagApi.java | 179 +++++++++ .../com/foxinmy/weixin4j/qy/api/UserApi.java | 159 ++++++++ .../foxinmy/weixin4j/qy/api/weixin.properties | 39 ++ .../foxinmy/weixin4j/qy/model/Department.java | 74 ++++ .../foxinmy/weixin4j/qy/model/NameValue.java | 40 ++ .../com/foxinmy/weixin4j/qy/model/User.java | 203 ++++++++++ .../foxinmy/weixin4j/qy/type/UserStatus.java | 26 ++ .../src/main/resources/weixin.properties | 13 + .../foxinmy/weixin4j/qy/test/DepartTest.java | 58 +++ .../com/foxinmy/weixin4j/qy/test/TagTest.java | 77 ++++ .../foxinmy/weixin4j/qy/test/TokenTest.java | 33 ++ .../foxinmy/weixin4j/qy/test/UserTest.java | 70 ++++ weixin4j-qy/weixin4j-qy-server/.gitignore | 28 ++ weixin4j-qy/weixin4j-qy-server/README.md | 22 ++ weixin4j-qy/weixin4j-qy-server/pom.xml | 24 ++ .../weixin4j-qy-server/src/main/assembly.xml | 36 ++ .../weixin4j-qy-server/src/main/startup.sh | 142 +++++++ 69 files changed, 2741 insertions(+), 466 deletions(-) create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Gender.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinQyAccount.java create mode 100644 weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java delete mode 100644 weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/Gender.java create mode 100644 weixin4j-qy/weixin4j-qy-api/.gitignore create mode 100644 weixin4j-qy/weixin4j-qy-api/README.md create mode 100644 weixin4j-qy/weixin4j-qy-api/pom.xml create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/assembly.xml create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/BaseApi.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/DepartApi.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/TagApi.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/Department.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/NameValue.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/User.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/type/UserStatus.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/main/resources/weixin.properties create mode 100644 weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/DepartTest.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TagTest.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TokenTest.java create mode 100644 weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java create mode 100644 weixin4j-qy/weixin4j-qy-server/.gitignore create mode 100644 weixin4j-qy/weixin4j-qy-server/README.md create mode 100644 weixin4j-qy/weixin4j-qy-server/pom.xml create mode 100644 weixin4j-qy/weixin4j-qy-server/src/main/assembly.xml create mode 100644 weixin4j-qy/weixin4j-qy-server/src/main/startup.sh diff --git a/README.md b/README.md index 87a1d362..97c796c2 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,18 @@ weixin4j * 2014-11-17 + **weixin4j-mp**: 新增`冲正`和`被扫支付`接口 + +* 2014-11-19 + + + **weixin4j-base**: 新增`WeixinQyAccount`企业号账号信息类 + + + **weixin4j-qy**: 得到`weixin4j-qy`和`weixin4j-qy-server`工程 + + + **weixin4j-qy**: 新增`部门管理`接口 + + + **weixin4j-qy**: 新增`用户管理`接口 + + + **weixin4j-qy**: 新增`标签管理`接口 接下来 ------ diff --git a/pom.xml b/pom.xml index 33d8ad45..e28db54f 100644 --- a/pom.xml +++ b/pom.xml @@ -131,6 +131,29 @@ + + + + org.apache.maven.plugins + maven-assembly-plugin + ${maven.assembly.plugin.version} + + + src/main/assembly.xml + + + + + make-assembly + package + + single + + + + + + src/main/java diff --git a/weixin4j-base/README.md b/weixin4j-base/README.md index 582ae674..6eecff8d 100644 --- a/weixin4j-base/README.md +++ b/weixin4j-base/README.md @@ -25,4 +25,8 @@ weixin4j-base * 2014-11-15 - + 新增`aes加密解密`函数 \ No newline at end of file + + 新增`aes加密解密`函数 + +* 2014-11-19 + + + 新增`WeixinQyAccount`企业号账号信息类 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml index 8f6cf196..a52d7985 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml @@ -11,7 +11,7 @@ system error 系统繁忙 - + 40001 invalid credential @@ -32,6 +32,14 @@ invalid media type 不合法的媒体文件类型 + + 40005 + 不合法的文件类型 + + + 40006 + 不合法的文件大小 + 40007 invalid media_id @@ -102,6 +110,14 @@ invalid button url size 不合法的url长度 + + 40021 + 不合法的菜单版本号 + + + 40022 + 不合法的子菜单级数 + 40023 invalid sub button size @@ -127,6 +143,10 @@ invalid sub button url size 不合法的子菜单按钮url长度 + + 40028 + 不合法的自定义菜单使用员工 + 40029 invalid code @@ -137,6 +157,22 @@ invalid refresh_token 不合法的refresh_token + + 40031 + 不合法的UserID列表 + + + 40032 + 不合法的UserID列表长度 + + + 40033 + 不合法的请求字符,不能包含\uxxxx格式的字符 + + + 40035 + 不合法的参数 + 40036 invalid template_id size @@ -147,11 +183,27 @@ invalid template_id 不合法的template_id + + 40038 + 不合法的请求格式 + 40039 invalid url size 不合法的url长度 + + 40040 + 不合法的插件token + + + 40041 + 不合法的插件id + + + 40042 + 不合法的插件会话 + 40048 invalid url domain @@ -167,10 +219,82 @@ invalid button url domain 不合法的菜单按钮url域名 + + 40056 + 不合法的agentid + + + 40057 + 不合法的callbackurl + + + 40058 + 不合法的红包参数 + + + 40059 + 不合法的上报地理位置标志位 + + + 40060 + 设置上报地理位置标志位时没有设置callbackurl + + + 40061 + 设置应用头像失败 + + + 40062 + 不合法的应用模式 + + + 40063 + 红包参数为空 + + + 40064 + 管理组名字已存在 + + + 40065 + 不合法的管理组名字长度 + 40066 - invalid url - 不合法的url + invalid url/department + 不合法的url/不合法的部门列表 + + + 40067 + 标题长度不合法 + + + 40068 + 不合法的标签ID + + + 40069 + 不合法的标签ID列表 + + + 40070 + 列表中所有标签(用户)ID都不合法 + + + 40071 + 不合法的标签名字,标签名字已经存在 + + + 40072 + 不合法的标签名字长度 + + + 40073 + 不合法的openid + + + 40074 + news消息不支持指定为高保密消息 41001 @@ -222,6 +346,38 @@ missing url 缺失url参数 + + 41011 + 缺少agentid + + + 41012 + 缺少应用头像mediaid + + + 41013 + 缺少应用名字 + + + 41014 + 缺少应用描述 + + + 41015 + 缺少Content + + + 41016 + 缺少标题 + + + 41017 + 缺少标签ID + + + 41018 + 缺少标签名字 + 42001 access_token expired @@ -237,6 +393,10 @@ code expired code超时 + + 42004 + 插件token超时 + 43001 require GET method @@ -257,6 +417,34 @@ require subscribe 需要订阅关系 + + 43005 + 需要好友关系 + + + 43006 + 需要订阅 + + + 43007 + 需要授权 + + + 43008 + 需要支付授权 + + + 43009 + 需要员工已关注 + + + 43010 + 需要处于回调模式 + + + 43011 + 需要企业授权 + 44001 empty media data @@ -342,6 +530,10 @@ template size out of limit 模板大小超过限制 + + 45015 + 回复时间超过限制 + 45016 can't modify sys group @@ -357,11 +549,176 @@ too many group now, no need to add new 组数量过多 + + 45024 + 账号数量超过上限 + + + 46001 + 不存在媒体数据 + + + 46002 + 不存在的菜单版本 + + + 46003 + 不存在的菜单数据 + + + 46004 + 不存在的员工 + + + 47001 + 解析JSON/XML内容错误 + + + 48002 + Api禁用 + 50001 - api unauthorized + api/redirect_uri unauthorized 接口未授权 + + 50002 + 员工不在权限范围 + + + 50003 + 应用已停用 + + + 50004 + 员工状态不正确(未关注状态) + + + 50005 + 企业已禁用 + + + + 60001 + 部门长度不符合限制 + + + 60002 + 部门层级深度超过限制 + + + 60003 + 部门不存在 + + + 60004 + 父亲部门不存在 + + + 60005 + 不允许删除有成员的部门 + + + 60006 + 不允许删除有子部门的部门 + + + 60007 + 不允许删除根部门 + + + 60008 + 部门名称已存在 + + + 60009 + 部门名称含有非法字符 + + + 60010 + 部门存在循环关系 + + + 60011 + 管理员权限不足(user/department/agent)无权限 + + + 60012 + 不允许删除默认应用 + + + 60013 + 不允许关闭应用 + + + 60014 + 不允许开启应用 + + + 60015 + 不允许修改默认应用可见范围 + + + 60016 + 不允许删除存在成员的标签 + + + 60017 + 不允许设置企业 + + + 60102 + UserID已存在 + + + 60103 + 手机号码不合法 + + + 60104 + 手机号码已存在 + + + 60105 + 邮箱不合法 + + + 60106 + 邮箱已存在 + + + 60107 + 微信号不合法 + + + 60108 + 微信号已存在 + + + 60109 + QQ号已存在 + + + 60110 + 部门个数超出限制 + + + 60111 + UserID不存在 + + + 60112 + 成员姓名不合法 + + + 60113 + 身份认证信息(微信号/手机/邮箱)不能同时为空 + + + 60114 + 性别不合法 + 7000000 diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java index cccebc3e..636eeca8 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Consts.java @@ -11,4 +11,12 @@ public final class Consts { public static final String AES = "AES"; public static final String PROTOCOL_FILE = "file"; public static final String PROTOCOL_JAR = "jar"; + + public static final String MP_ASSESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; + public static final String QY_ASSESS_TOKEN_URL = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=%s&corpsecret=%s"; + + public static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder"; + public static final String MICROPAYURL = "https://api.mch.weixin.qq.com/pay/micropay"; + public static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s"; + public static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s"; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Gender.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Gender.java new file mode 100644 index 00000000..faf19c76 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Gender.java @@ -0,0 +1,14 @@ +package com.foxinmy.weixin4j.model; + +/** + * 用户性别 + * + * @className Gender + * @author jy + * @date 2014年11月5日 + * @since JDK 1.7 + * @see + */ +public enum Gender { + male, female, unknown; +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java index 7ec0afc8..ad29b88d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java @@ -2,48 +2,51 @@ package com.foxinmy.weixin4j.model; import java.io.Serializable; -import org.apache.commons.lang3.StringUtils; - /** - * 微信账户信息 + * 微信账号信息 * * @className WeixinAccount * @author jy - * @date 2014年8月17日 + * @date 2014年11月18日 * @since JDK 1.7 * @see */ -public class WeixinAccount implements Serializable { - private static final long serialVersionUID = 3689999353867189585L; +public abstract class WeixinAccount implements Serializable { + private static final long serialVersionUID = -6001008896414323534L; + // 唯一的身份标识 + private String id; + // 调用接口的密钥 + private String secret; private String token; - // 支付场景下为用户的openid 其余情况可能是公众号的原始ID - private String openId; - // 公众号身份的唯一标识 - private String appId; - // 公众平台接口 API 的权限获取所需密钥 Key - private String appSecret; - // 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值 - private String paySignKey; // 安全模式下的加密密钥 private String encodingAesKey; - // 财付通商户身份的标识 - private String partnerId; - // 财付通商户权限密钥Key - private String partnerKey; - // 微信支付商户号V3.x版本 - private String mchId; - // 微信支付分配的设备号 - private String deviceInfo; - // 微信支付版本号(如果无则按照mchId来做判断) - private int version; - // 是否已经认证 - private boolean isAlive; - // 是否是服务号 - private boolean isService; - // 是否是订阅号 - private boolean isSubscribe; + public abstract String getTokenUrl(); + + public WeixinAccount() { + } + + public WeixinAccount(String id, String secret) { + this.id = id; + this.secret = secret; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSecret() { + return secret; + } + + public void setSecret(String secret) { + this.secret = secret; + } public String getToken() { return token; @@ -53,30 +56,6 @@ public class WeixinAccount implements Serializable { this.token = token; } - public String getOpenId() { - return openId; - } - - public void setOpenId(String openId) { - this.openId = openId; - } - - public String getAppId() { - return appId; - } - - public void setAppId(String appId) { - this.appId = appId; - } - - public String getAppSecret() { - return appSecret; - } - - public void setAppSecret(String appSecret) { - this.appSecret = appSecret; - } - public String getEncodingAesKey() { return encodingAesKey; } @@ -85,130 +64,9 @@ public class WeixinAccount implements Serializable { this.encodingAesKey = encodingAesKey; } - public String getPaySignKey() { - return paySignKey; - } - - public void setPaySignKey(String paySignKey) { - this.paySignKey = paySignKey; - } - - public String getPartnerId() { - return partnerId; - } - - public void setPartnerId(String partnerId) { - this.partnerId = partnerId; - } - - public String getPartnerKey() { - return partnerKey; - } - - public void setPartnerKey(String partnerKey) { - this.partnerKey = partnerKey; - } - - public String getMchId() { - return mchId; - } - - public void setMchId(String mchId) { - this.mchId = mchId; - } - - public String getDeviceInfo() { - return deviceInfo; - } - - public void setDeviceInfo(String deviceInfo) { - this.deviceInfo = deviceInfo; - } - - public boolean getIsAlive() { - return isAlive; - } - - public void setIsAlive(Boolean isAlive) { - this.isAlive = isAlive; - } - - public boolean getIsService() { - return isService; - } - - public void setIsService(Boolean isService) { - this.isService = isService; - } - - public boolean getIsSubscribe() { - return isSubscribe; - } - - public void setIsSubscribe(Boolean isSubscribe) { - this.isSubscribe = isSubscribe; - } - - public int getVersion() { - if (version == 0) { - return StringUtils.isNotBlank(mchId) ? 3 : 2; - } - return version; - } - - public void setVersion(int version) { - this.version = version; - } - - public WeixinAccount() { - - } - - public WeixinAccount(String appId, String appSecret) { - this.appId = appId; - this.appSecret = appSecret; - } - - /** - * V3版本字段 - * - * @param appId - * @param appSecret - * @param paySignKey - * @param mchId - */ - public WeixinAccount(String appId, String appSecret, String paySignKey, - String mchId) { - this(appId, appSecret); - this.paySignKey = paySignKey; - this.mchId = mchId; - } - - /** - * V2版本字段 - * - * @param appId - * @param appSecret - * @param paySignKey - * @param partnerId - * @param partnerKey - */ - public WeixinAccount(String appId, String appSecret, String paySignKey, - String partnerId, String partnerKey) { - this(appId, appSecret); - this.paySignKey = paySignKey; - this.partnerId = partnerId; - this.partnerKey = partnerKey; - } - @Override public String toString() { - return "WeixinAccount [token=" + token + ", openId=" + openId - + ", appId=" + appId + ", appSecret=" + appSecret - + ", encodingAesKey=" + encodingAesKey + ", paySignKey=" - + paySignKey + ", partnerId=" + partnerId + ", partnerKey=" - + partnerKey + ", mchId=" + mchId + ", deviceInfo=" - + deviceInfo + ", isAlive=" + isAlive + ", isService=" - + isService + ", isSubscribe=" + isSubscribe + "]"; + return "WeixinAccount [id=" + id + ", secret=" + secret + ", token=" + + token + ", encodingAesKey=" + encodingAesKey + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java new file mode 100644 index 00000000..3d26f1d3 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinMpAccount.java @@ -0,0 +1,178 @@ +package com.foxinmy.weixin4j.model; + +import org.apache.commons.lang3.StringUtils; + +/** + * 微信公众平台信息 + * + * @className WeixinMpAccount + * @author jy + * @date 2014年8月17日 + * @since JDK 1.7 + * @see + */ +public class WeixinMpAccount extends WeixinAccount { + private static final long serialVersionUID = 3689999353867189585L; + + // 支付场景下为用户的openid 其余情况可能是公众号的原始ID + private String openId; + // 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值 + private String paySignKey; + // 财付通商户身份的标识 + private String partnerId; + // 财付通商户权限密钥Key + private String partnerKey; + // 微信支付商户号V3.x版本 + private String mchId; + // 微信支付分配的设备号 + private String deviceInfo; + // 微信支付版本号(如果无则按照mchId来做判断) + private int version; + + // 是否已经认证 + private boolean isAlive; + // 是否是服务号 + private boolean isService; + // 是否是订阅号 + private boolean isSubscribe; + + @Override + public String getTokenUrl() { + return String.format(Consts.MP_ASSESS_TOKEN_URL, getId(), getSecret()); + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getPaySignKey() { + return paySignKey; + } + + public void setPaySignKey(String paySignKey) { + this.paySignKey = paySignKey; + } + + public String getPartnerId() { + return partnerId; + } + + public void setPartnerId(String partnerId) { + this.partnerId = partnerId; + } + + public String getPartnerKey() { + return partnerKey; + } + + public void setPartnerKey(String partnerKey) { + this.partnerKey = partnerKey; + } + + public String getMchId() { + return mchId; + } + + public void setMchId(String mchId) { + this.mchId = mchId; + } + + public String getDeviceInfo() { + return deviceInfo; + } + + public void setDeviceInfo(String deviceInfo) { + this.deviceInfo = deviceInfo; + } + + public boolean getIsAlive() { + return isAlive; + } + + public void setIsAlive(Boolean isAlive) { + this.isAlive = isAlive; + } + + public boolean getIsService() { + return isService; + } + + public void setIsService(Boolean isService) { + this.isService = isService; + } + + public boolean getIsSubscribe() { + return isSubscribe; + } + + public void setIsSubscribe(Boolean isSubscribe) { + this.isSubscribe = isSubscribe; + } + + public int getVersion() { + if (version == 0) { + return StringUtils.isNotBlank(mchId) ? 3 : 2; + } + return version; + } + + public void setVersion(int version) { + this.version = version; + } + + public WeixinMpAccount() { + + } + + public WeixinMpAccount(String appId, String appSecret) { + super(appId, appSecret); + } + + /** + * V3版本字段 + * + * @param appId + * @param appSecret + * @param paySignKey + * @param mchId + */ + public WeixinMpAccount(String appId, String appSecret, String paySignKey, + String mchId) { + this(appId, appSecret); + this.paySignKey = paySignKey; + this.mchId = mchId; + } + + /** + * V2版本字段 + * + * @param appId + * @param appSecret + * @param paySignKey + * @param partnerId + * @param partnerKey + */ + public WeixinMpAccount(String appId, String appSecret, String paySignKey, + String partnerId, String partnerKey) { + this(appId, appSecret); + this.paySignKey = paySignKey; + this.partnerId = partnerId; + this.partnerKey = partnerKey; + } + + @Override + public String toString() { + return "WeixinMpAccount [openId=" + openId + ", paySignKey=" + + paySignKey + ", partnerId=" + partnerId + ", partnerKey=" + + partnerKey + ", mchId=" + mchId + ", deviceInfo=" + + deviceInfo + ", version=" + version + ", isAlive=" + isAlive + + ", isService=" + isService + ", isSubscribe=" + isSubscribe + + ", getId()=" + getId() + ", getSecret()=" + getSecret() + + ", getToken()=" + getToken() + ", getEncodingAesKey()=" + + getEncodingAesKey() + "]"; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinQyAccount.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinQyAccount.java new file mode 100644 index 00000000..9192ff25 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinQyAccount.java @@ -0,0 +1,34 @@ +package com.foxinmy.weixin4j.model; + +/** + * 微信企业号信息 + * + * @className WeixinQyAccount + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see + */ +public class WeixinQyAccount extends WeixinAccount { + private static final long serialVersionUID = 3689999353867189585L; + + public WeixinQyAccount() { + } + + public WeixinQyAccount(String corpid, String corpsecret) { + super(corpid, corpsecret); + } + + @Override + public String getTokenUrl() { + return String.format(Consts.QY_ASSESS_TOKEN_URL, getId(), getSecret()); + } + + @Override + public String toString() { + return "WeixinQyAccount [getTokenUrl()=" + getTokenUrl() + ", getId()=" + + getId() + ", getSecret()=" + getSecret() + ", getToken()=" + + getToken() + ", getEncodingAesKey()=" + getEncodingAesKey() + + "]"; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/BaseMessage.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/BaseMessage.java index fe296d8a..8dd900ff 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/BaseMessage.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/msg/BaseMessage.java @@ -1,15 +1,8 @@ package com.foxinmy.weixin4j.msg; -import java.io.Writer; - import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.type.MessageType; -import com.foxinmy.weixin4j.util.ClassUtil; -import com.foxinmy.weixin4j.xml.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; -import com.thoughtworks.xstream.io.json.JsonWriter; /** * 普通消息基类 @@ -26,32 +19,12 @@ import com.thoughtworks.xstream.io.json.JsonWriter; public class BaseMessage extends BaseMsg { private static final long serialVersionUID = 7761192742840031607L; - private final static XStream xmlStream = XStream.get(); - private final static XStream jsonStream = new XStream( - new JsonHierarchicalStreamDriver() { - public HierarchicalStreamWriter createWriter(Writer writer) { - return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE); - } - }); @XStreamAlias("MsgType") private MessageType msgType; // 消息类型 @XStreamAlias("MsgId") private long msgId; // 消息ID - static { - Class[] classes = ClassUtil.getClasses( - TextMessage.class.getPackage()).toArray(new Class[0]); - - xmlStream.processAnnotations(classes); - xmlStream.omitField(BaseMessage.class, "msgId"); - - jsonStream.setMode(XStream.NO_REFERENCES); - jsonStream.autodetectAnnotations(true); - jsonStream.processAnnotations(classes); - jsonStream.omitField(BaseMessage.class, "msgId"); - } - public BaseMessage(MessageType msgType) { this.msgType = msgType; } @@ -79,25 +52,4 @@ public class BaseMessage extends BaseMsg { } return false; } - - /** - * 消息对象转换为微信服务器接受的xml格式消息 - * - * @return xml字符串 - */ - public String toXml() { - Class targetClass = getMsgType() - .getMessageClass(); - xmlStream.alias("xml", targetClass); - return xmlStream.toXML(this); - } - - /** - * 消息对象转换为微信服务器接受的json格式字符串 - * - * @return json字符串 - */ - public String toJson() { - return jsonStream.toXML(this); - } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java index ec5ca972..b0fd49f8 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java @@ -2,10 +2,11 @@ package com.foxinmy.weixin4j.token; import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.util.ConfigUtil; /** - * 获取weixin.properties中的appid&appsecret信息 + * 获取weixin.properties中的id&secret信息 * * @className AbstractTokenHolder * @author jy @@ -14,12 +15,18 @@ import com.foxinmy.weixin4j.util.ConfigUtil; * @see */ public abstract class AbstractTokenHolder implements TokenHolder { - protected final String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"; - protected final HttpRequest request = new HttpRequest(); - private final WeixinAccount weixinAccount; - public AbstractTokenHolder() { - this.weixinAccount = ConfigUtil.getWeixinAccount(); + protected final HttpRequest request = new HttpRequest(); + protected final WeixinAccount weixinAccount; + + public AbstractTokenHolder(AccountType accountType) { + if (accountType == AccountType.MP) { + this.weixinAccount = ConfigUtil.getWeixinMpAccount(); + } else if (accountType == AccountType.QY) { + this.weixinAccount = ConfigUtil.getWeixinQyAccount(); + } else { + this.weixinAccount = null; + } } public AbstractTokenHolder(WeixinAccount weixinAccount) { diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java index 9a8749ca..21affe2c 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java @@ -13,6 +13,7 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.xml.XStream; @@ -24,23 +25,20 @@ import com.foxinmy.weixin4j.xml.XStream; * @date 2014年9月27日 * @since JDK 1.7 * @see 获取token说明 + * href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">微信公众平台获取token说明 + * @see 微信企业号获取token说明 * @see com.foxinmy.weixin4j.model.Token */ public class FileTokenHolder extends AbstractTokenHolder { - public FileTokenHolder() { - super(); + public FileTokenHolder(AccountType accountType) { + super(accountType); } public FileTokenHolder(WeixinAccount weixinAccount) { super(weixinAccount); } - public FileTokenHolder(String appid, String appsecret) { - this(new WeixinAccount(appid, appsecret)); - } - /** * 获取token *

@@ -55,14 +53,13 @@ public class FileTokenHolder extends AbstractTokenHolder { */ @Override public Token getToken() throws WeixinException { - String appid = getAccount().getAppId(); - String appsecret = getAccount().getAppSecret(); - if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) { + String id = weixinAccount.getId(); + if (StringUtils.isBlank(id) || StringUtils.isBlank(weixinAccount.getSecret())) { throw new IllegalArgumentException( - "appid or appsecret not be null!"); + "id or secret not be null!"); } File token_file = new File(String.format("%s/token_%s.xml", - ConfigUtil.getValue("token_path"), appid)); + ConfigUtil.getValue("token_path"), id)); Token token = null; Calendar ca = Calendar.getInstance(); long now_time = ca.getTimeInMillis(); @@ -78,8 +75,7 @@ public class FileTokenHolder extends AbstractTokenHolder { } else { token_file.createNewFile(); } - String api_token_uri = String.format(tokenUrl, appid, appsecret); - Response response = request.get(api_token_uri); + Response response = request.get(weixinAccount.getTokenUrl()); token = response.getAsObject(new TypeReference() { }); token.setTime(now_time); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java index 1e4c1a94..2105a3a7 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java @@ -11,6 +11,7 @@ import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.type.AccountType; /** * 基于redis保存的Token获取类 @@ -20,7 +21,10 @@ import com.foxinmy.weixin4j.model.WeixinAccount; * @date 2014年9月27日 * @since JDK 1.7 * @see 获取token说明 + * href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">微信公众平台获取token说明 + * @see 微信企业号获取token说明 * @see com.foxinmy.weixin4j.model.Token */ public class RedisTokenHolder extends AbstractTokenHolder { @@ -37,47 +41,39 @@ public class RedisTokenHolder extends AbstractTokenHolder { this.jedisPool = new JedisPool(poolConfig, host, port); } - public RedisTokenHolder() { - this("localhost", 6379); - } - - public RedisTokenHolder(String host, int port) { - super(); + public RedisTokenHolder(String host, int port, AccountType accountType) { + super(accountType); createPool(host, port); } + public RedisTokenHolder(AccountType accountType) { + this("localhost", 6379, accountType); + } + public RedisTokenHolder(WeixinAccount weixinAccount) { - this(weixinAccount, "localhost", 6379); + this("localhost", 6379, weixinAccount); } - public RedisTokenHolder(String appId, String appSecret, String host, - int port) { - this(new WeixinAccount(appId, appSecret), host, port); - } - - public RedisTokenHolder(WeixinAccount weixinAccount, String host, int port) { + public RedisTokenHolder(String host, int port, WeixinAccount weixinAccount) { super(weixinAccount); createPool(host, port); } @Override public Token getToken() throws WeixinException { - String appid = getAccount().getAppId(); - String appsecret = getAccount().getAppSecret(); - if (StringUtils.isBlank(appid) || StringUtils.isBlank(appsecret)) { - throw new IllegalArgumentException( - "appid or appsecret not be null!"); + String id = weixinAccount.getId(); + if (StringUtils.isBlank(id) + || StringUtils.isBlank(weixinAccount.getSecret())) { + throw new IllegalArgumentException("id or secret not be null!"); } Token token = null; Jedis jedis = null; try { jedis = jedisPool.getResource(); - String key = String.format("token:%s", appid); + String key = String.format("token:%s", id); String accessToken = jedis.get(key); if (StringUtils.isBlank(accessToken)) { - String api_token_uri = String - .format(tokenUrl, appid, appsecret); - token = request.get(api_token_uri).getAsObject( + token = request.get(weixinAccount.getTokenUrl()).getAsObject( new TypeReference() { }); jedis.setex(key, token.getExpiresIn() - 3, diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java index f84041ff..094a5242 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java @@ -18,6 +18,5 @@ import com.foxinmy.weixin4j.model.WeixinAccount; */ public interface TokenHolder { public WeixinAccount getAccount(); - public Token getToken() throws WeixinException; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java new file mode 100644 index 00000000..8899289f --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/type/AccountType.java @@ -0,0 +1,14 @@ +package com.foxinmy.weixin4j.type; + +/** + * 账号类型 + * + * @className AccountType + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see + */ +public enum AccountType { + MP, QY +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java index 5bd3952d..e7403cf1 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/ConfigUtil.java @@ -5,7 +5,8 @@ import java.util.ResourceBundle; import java.util.Set; import com.alibaba.fastjson.JSON; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; +import com.foxinmy.weixin4j.model.WeixinQyAccount; /** * 商户配置工具类 @@ -33,8 +34,13 @@ public class ConfigUtil { return weixinBundle.getString(key); } - public static WeixinAccount getWeixinAccount() { + public static WeixinMpAccount getWeixinMpAccount() { String text = getValue("account"); - return JSON.parseObject(text, WeixinAccount.class); + return JSON.parseObject(text, WeixinMpAccount.class); + } + + public static WeixinQyAccount getWeixinQyAccount() { + String text = getValue("account"); + return JSON.parseObject(text, WeixinQyAccount.class); } } diff --git a/weixin4j-mp/pom.xml b/weixin4j-mp/pom.xml index a10554f6..b54e612f 100644 --- a/weixin4j-mp/pom.xml +++ b/weixin4j-mp/pom.xml @@ -19,29 +19,6 @@ weixin4j-mp - - - - org.apache.maven.plugins - maven-assembly-plugin - ${maven.assembly.plugin.version} - - - src/main/assembly.xml - - - - - make-assembly - package - - single - - - - - - diff --git a/weixin4j-mp/weixin4j-mp-api/README.md b/weixin4j-mp/weixin4j-mp-api/README.md index d6915fc2..191014a1 100644 --- a/weixin4j-mp/weixin4j-mp-api/README.md +++ b/weixin4j-mp/weixin4j-mp-api/README.md @@ -46,7 +46,7 @@ weixin.properties说明 示例(properties中换行用右斜杆\\) -> account={"appId":"appId","appSecret":"appSecret", +> account={"id":"appId","secret":"appSecret", > "token":"开放者的token 非必须","openId":"公众号的openid 非必须", > "encodingAesKey":"公众号设置了加密方式且为「安全模式」需要填入", > "mchId":"V3.x版本下的微信商户号", @@ -69,7 +69,6 @@ weixin.properties说明 3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`(继承`AbstractTokenHolder`并重写`getToken`方法),默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`. WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder()); - // weixinProxy = new WeixinProxy(new RedisTokenHolder(appid,appsecret)); // weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount)); 4.`mvn package`. diff --git a/weixin4j-mp/weixin4j-mp-api/pom.xml b/weixin4j-mp/weixin4j-mp-api/pom.xml index eba1602c..4345ef9d 100644 --- a/weixin4j-mp/weixin4j-mp-api/pom.xml +++ b/weixin4j-mp/weixin4j-mp-api/pom.xml @@ -10,7 +10,7 @@ weixin4j-mp-api weixin4j-mp-api - https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-api + https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-mp-api 微信公众号API weixin4j-mp-api diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index 13bdb137..3fa077a6 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -10,7 +10,7 @@ import com.alibaba.fastjson.JSONObject; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.JsonResult; import com.foxinmy.weixin4j.http.XmlResult; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.api.CustomApi; import com.foxinmy.weixin4j.mp.api.GroupApi; import com.foxinmy.weixin4j.mp.api.HelperApi; @@ -45,10 +45,11 @@ import com.foxinmy.weixin4j.mp.type.BillType; import com.foxinmy.weixin4j.mp.type.IdQuery; import com.foxinmy.weixin4j.token.FileTokenHolder; import com.foxinmy.weixin4j.token.TokenHolder; +import com.foxinmy.weixin4j.type.AccountType; import com.foxinmy.weixin4j.type.MediaType; /** - * 微信服务实现 + * 微信公众平台接口实现 * * @className WeixinProxy * @author jy.hu @@ -74,18 +75,18 @@ public class WeixinProxy { * 默认采用文件存放Token信息 */ public WeixinProxy() { - this(new FileTokenHolder()); + this(new FileTokenHolder(AccountType.MP)); } /** - * appid,appsecret
+ * appid,appsecret
* 将无法调用支付相关接口 * * @param appid * @param appsecret */ public WeixinProxy(String appid, String appsecret) { - this(new FileTokenHolder(appid, appsecret)); + this(new WeixinMpAccount(appid, appsecret)); } /** @@ -93,7 +94,7 @@ public class WeixinProxy { * * @param weixinAccount */ - public WeixinProxy(WeixinAccount weixinAccount) { + public WeixinProxy(WeixinMpAccount weixinAccount) { this(new FileTokenHolder(weixinAccount)); } @@ -793,7 +794,7 @@ public class WeixinProxy { * @throws WeixinException * @see com.foxinmy.weixin4j.mp.api.PayApi */ - public Order orderQueryV2(WeixinAccount weixinAccount, String outTradeNo) + public Order orderQueryV2(WeixinMpAccount weixinAccount, String outTradeNo) throws WeixinException { return payApi.orderQueryV2(outTradeNo); } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java index b99ff6d5..b65a2569 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java @@ -8,7 +8,7 @@ import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.model.SemQuery; import com.foxinmy.weixin4j.mp.model.SemResult; import com.foxinmy.weixin4j.token.TokenHolder; @@ -65,10 +65,10 @@ public class HelperApi extends BaseApi { * @throws WeixinException */ public SemResult semantic(SemQuery semQuery) throws WeixinException { - WeixinAccount weixinAccount = tokenHolder.getAccount(); + WeixinMpAccount weixinAccount = (WeixinMpAccount) tokenHolder.getAccount(); String semantic_uri = getRequestUri("semantic_uri"); Token token = tokenHolder.getToken(); - semQuery.appid(weixinAccount.getAppId()); + semQuery.appid(weixinAccount.getId()); Response response = request.post( String.format(semantic_uri, token.getAccessToken()), semQuery.toJson()); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java index d2d05a05..a7deec63 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/PayApi.java @@ -41,7 +41,7 @@ import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.http.SSLHttpRequest; import com.foxinmy.weixin4j.http.XmlResult; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.payment.ApiResult; import com.foxinmy.weixin4j.mp.payment.PayUtil; import com.foxinmy.weixin4j.mp.payment.Refund; @@ -70,11 +70,11 @@ import com.foxinmy.weixin4j.util.RandomUtil; */ public class PayApi extends BaseApi { private final TokenHolder tokenHolder; - private final WeixinAccount weixinAccount; + private final WeixinMpAccount weixinAccount; public PayApi(TokenHolder tokenHolder) { this.tokenHolder = tokenHolder; - this.weixinAccount = tokenHolder.getAccount(); + this.weixinAccount = (WeixinMpAccount) tokenHolder.getAccount(); } /** @@ -101,7 +101,7 @@ public class PayApi extends BaseApi { Token token = tokenHolder.getToken(); Map param = new HashMap(); - param.put("appid", weixinAccount.getAppId()); + param.put("appid", weixinAccount.getId()); param.put("appkey", weixinAccount.getPaySignKey()); param.put("openid", openId); param.put("transid", transid); @@ -142,14 +142,14 @@ public class PayApi extends BaseApi { String timestamp = DateUtil.timestamp2string(); JSONObject obj = new JSONObject(); - obj.put("appid", weixinAccount.getAppId()); + obj.put("appid", weixinAccount.getId()); obj.put("appkey", weixinAccount.getPaySignKey()); obj.put("package", sb.toString()); obj.put("timestamp", timestamp); String signature = PayUtil.paysignSha(obj, null); obj.clear(); - obj.put("appid", weixinAccount.getAppId()); + obj.put("appid", weixinAccount.getId()); obj.put("package", sb.toString()); obj.put("timestamp", timestamp); obj.put("app_signature", signature); @@ -494,7 +494,7 @@ public class PayApi extends BaseApi { String _billDate = DateUtil.fortmat2yyyyMMdd(billDate); String bill_path = ConfigUtil.getValue("bill_path"); String fileName = String.format("%s_%s_%s.xls", _billDate, billType - .name().toLowerCase(), weixinAccount.getAppId()); + .name().toLowerCase(), weixinAccount.getId()); File file = new File(String.format("%s/%s", bill_path, fileName)); if (file.exists()) { return file; @@ -592,7 +592,7 @@ public class PayApi extends BaseApi { */ private Map baseMapV3(IdQuery idQuery) { Map map = new HashMap(); - map.put("appid", weixinAccount.getAppId()); + map.put("appid", weixinAccount.getId()); map.put("mch_id", weixinAccount.getMchId()); map.put("nonce_str", RandomUtil.generateString(16)); if (StringUtils.isNotBlank(weixinAccount.getDeviceInfo())) { diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/TmplApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/TmplApi.java index 5bd6913a..7a52ac78 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/TmplApi.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/TmplApi.java @@ -1,5 +1,6 @@ package com.foxinmy.weixin4j.mp.api; +import com.alibaba.fastjson.JSON; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.JsonResult; import com.foxinmy.weixin4j.http.Response; @@ -39,9 +40,9 @@ public class TmplApi extends BaseApi { throws WeixinException { Token token = tokenHolder.getToken(); String template_send_uri = getRequestUri("template_send_uri"); + String para = JSON.toJSONString(tplMessage); Response response = request.post( - String.format(template_send_uri, token.getAccessToken()), - tplMessage.toJson()); + String.format(template_send_uri, token.getAccessToken()), para); return response.getAsJsonResult(); } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java index e85fee95..d172aa8d 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/api/UserApi.java @@ -48,7 +48,7 @@ public class UserApi extends BaseApi { WeixinAccount weixinAccount = tokenHolder.getAccount(); String user_token_uri = getRequestUri("sns_user_token_uri"); Response response = request.get(String.format(user_token_uri, - weixinAccount.getAppId(), weixinAccount.getAppSecret(), code)); + weixinAccount.getId(), weixinAccount.getSecret(), code)); return response.getAsObject(new TypeReference() { }); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Group.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Group.java index ce9bd840..7a6726ec 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Group.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/Group.java @@ -55,11 +55,10 @@ public class Group implements Serializable { /** * 返回创建分组所需的json格式字符串 * - * @return {"group": {"id": 107, "name": "test"}} + * @return {"group": {"name": "test"}} */ public String toCreateJson() { - return String.format("{\"group\":{\"id\":%s,\"name\":\"%s\"}}", id, - name); + return String.format("{\"group\":{\"name\":\"%s\"}}", name); } /** diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/User.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/User.java index 0368a7bf..e34d8ec4 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/User.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/model/User.java @@ -4,8 +4,8 @@ import java.io.Serializable; import org.apache.commons.lang3.StringUtils; +import com.foxinmy.weixin4j.model.Gender; import com.foxinmy.weixin4j.mp.type.FaceSize; -import com.foxinmy.weixin4j.mp.type.Gender; import com.foxinmy.weixin4j.mp.type.Lang; /** diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/msg/notify/BaseNotify.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/msg/notify/BaseNotify.java index 6045ad98..1c2e1ce8 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/msg/notify/BaseNotify.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/msg/notify/BaseNotify.java @@ -4,6 +4,7 @@ import java.io.Serializable; import java.io.Writer; import com.foxinmy.weixin4j.mp.type.ResponseType; +import com.foxinmy.weixin4j.util.ClassUtil; import com.foxinmy.weixin4j.xml.XStream; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; @@ -22,6 +23,21 @@ public class BaseNotify implements Serializable { private static final long serialVersionUID = 7190233634431087729L; + private final static XStream jsonStream = new XStream( + new JsonHierarchicalStreamDriver() { + public HierarchicalStreamWriter createWriter(Writer writer) { + return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE); + } + }); + static { + Class[] classes = ClassUtil + .getClasses(BaseNotify.class.getPackage()) + .toArray(new Class[0]); + + jsonStream.setMode(XStream.NO_REFERENCES); + jsonStream.autodetectAnnotations(true); + jsonStream.processAnnotations(classes); + } private String touser; private ResponseType msgtype; @@ -56,15 +72,7 @@ public class BaseNotify implements Serializable { * @return {"touser": "to","msgtype": "text","text": {"content": "123"}} */ public String toJson() { - XStream xstream = new XStream(new JsonHierarchicalStreamDriver() { - public HierarchicalStreamWriter createWriter(Writer writer) { - return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE); - } - }); - xstream.setMode(XStream.NO_REFERENCES); - xstream.autodetectAnnotations(true); - xstream.processAnnotations(this.getClass()); - return xstream.toXML(this); + return jsonStream.toXML(this); } @Override diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java index 240b5e0c..c11e212b 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/MicroPayPackage.java @@ -4,7 +4,7 @@ import java.util.Date; import org.apache.commons.lang3.StringUtils; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.util.RandomUtil; import com.thoughtworks.xstream.annotations.XStreamAlias; @@ -33,10 +33,10 @@ public class MicroPayPackage extends PayPackage { } - public MicroPayPackage(WeixinAccount weixinAccount, String body, + public MicroPayPackage(WeixinMpAccount weixinAccount, String body, String attach, String out_trade_no, double total_fee, String spbill_create_ip, String auth_code) { - this(weixinAccount.getAppId(), weixinAccount.getMchId(), weixinAccount + this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount .getDeviceInfo(), RandomUtil.generateString(16), body, attach, out_trade_no, total_fee, spbill_create_ip, null, null, null, auth_code); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java index 6c5c1ba6..7d9b9f52 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayAction.java @@ -12,7 +12,7 @@ import com.alibaba.fastjson.JSONObject; import com.foxinmy.weixin4j.exception.PayException; import com.foxinmy.weixin4j.http.XmlResult; import com.foxinmy.weixin4j.model.Consts; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.payment.v2.NativePayNotifyV2; import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2; import com.foxinmy.weixin4j.mp.payment.v2.PayFeedback; @@ -46,7 +46,7 @@ public class PayAction { public JSONObject jsPay() { JSONObject obj = new JSONObject(); PayPackage payPackage = null; - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); // V3 支付 payPackage = new PayPackageV3(weixinAccount, "用户openid", "商品描述", "系统内部订单号", 1d, "IP地址", TradeType.JSAPI); @@ -111,7 +111,7 @@ public class PayAction { log.info("jspay_notify_orderinfo,{}", objMap); JsPayNotify payNotify = XStream.get(inputStream, JsPayNotify.class); log.info("jspay_notify_userinfo,{}", payNotify); - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); // 验证财付通签名 String sign = objMap.get("sign"); objMap.remove("sign"); @@ -153,7 +153,7 @@ public class PayAction { log.info("jaapi_notify_order_info:", order); String sign = order.getSign(); order.setSign(null); - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); String valid_sign = PayUtil.paysignMd5(order, weixinAccount.getPaySignKey()); log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign); @@ -187,7 +187,7 @@ public class PayAction { NativePayNotifyV2 payNotify = XStream.get(inputStream, NativePayNotifyV2.class); log.info("native_pay_notify,{}", payNotify); - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); String sign = payNotify.getPaySign(); payNotify.setPaySign(null); payNotify.setSignType(null); @@ -227,7 +227,7 @@ public class PayAction { NativePayNotifyV3.class); String sign = payNotify.getSign(); payNotify.setSign(null); - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); String valid_sign = PayUtil.paysignMd5(payNotify, weixinAccount.getPaySignKey()); log.info("微信签名----->sign={},vaild_sign={}", sign, valid_sign); @@ -272,7 +272,7 @@ public class PayAction { public String warning(InputStream inputStream) { PayWarn payWarn = XStream.get(inputStream, PayWarn.class); log.info("pay_warning,{}", payWarn); - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); String sign = payWarn.getPaySign(); payWarn.setPaySign(null); payWarn.setSignType(null); @@ -293,7 +293,7 @@ public class PayAction { public String feedback(InputStream inputStream) { PayFeedback feedback = XStream.get(inputStream, PayFeedback.class); log.info("pay_feedback_info:{}", feedback); - WeixinAccount weixinAccount = ConfigUtil.getWeixinAccount(); + WeixinMpAccount weixinAccount = ConfigUtil.getWeixinMpAccount(); // 验证微信签名 Map obj = new HashMap(); obj.put("openid", feedback.getOpenId()); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java index 44f85416..092ef016 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/PayUtil.java @@ -13,7 +13,8 @@ import com.foxinmy.weixin4j.exception.PayException; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.Response; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.Consts; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.payment.v2.JsPayRequestV2; import com.foxinmy.weixin4j.mp.payment.v2.NativePayResponseV2; import com.foxinmy.weixin4j.mp.payment.v2.PayPackageV2; @@ -37,11 +38,6 @@ import com.foxinmy.weixin4j.xml.XStream; * @see */ public class PayUtil { - private static final String UNIFIEDORDER = "https://api.mch.weixin.qq.com/pay/unifiedorder"; - private static final String MICROPAYURL = "https://api.mch.weixin.qq.com/pay/micropay"; - private static final String NATIVEURLV2 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&productid=%s×tamp=%s&noncestr=%s"; - private static final String NATIVEURLV3 = "weixin://wxpay/bizpayurl?sign=%s&appid=%s&mch_id=%s&product_id=%s&time_stamp=%s&nonce_str=%s"; - /** * 生成JSAPI字符串 * @@ -53,7 +49,7 @@ public class PayUtil { * @throws PayException */ public static String createPayJsRequestJson(PayPackage payPackage, - WeixinAccount weixinAccount) throws PayException { + WeixinMpAccount weixinAccount) throws PayException { if (payPackage instanceof PayPackageV2) { return createPayJsRequestJsonV2((PayPackageV2) payPackage, weixinAccount); @@ -74,7 +70,7 @@ public class PayUtil { * @return */ public static String createPayJsRequestJsonV2(PayPackageV2 payPackage, - WeixinAccount weixinAccount) { + WeixinMpAccount weixinAccount) { if (StringUtils.isBlank(payPackage.getPartner())) { payPackage.setPartner(weixinAccount.getPartnerId()); } @@ -101,7 +97,7 @@ public class PayUtil { * @return */ public static String createPayJsRequestJsonV2(String body, String orderNo, - double orderFee, String ip, WeixinAccount weixinAccount) { + double orderFee, String ip, WeixinMpAccount weixinAccount) { PayPackageV2 payPackage = new PayPackageV2(body, orderNo, orderFee, ip); payPackage.setPartner(weixinAccount.getPartnerId()); return createPayJsRequestJsonV2(payPackage, weixinAccount); @@ -168,7 +164,7 @@ public class PayUtil { */ public static String createPayJsRequestJsonV3(String openId, String body, String orderNo, double orderFee, String ip, String notifyUrl, - WeixinAccount weixinAccount) throws PayException { + WeixinMpAccount weixinAccount) throws PayException { PayPackageV3 payPackage = new PayPackageV3(weixinAccount, openId, body, orderNo, orderFee, ip, TradeType.JSAPI); payPackage.setNotify_url(notifyUrl); @@ -186,7 +182,7 @@ public class PayUtil { * @throws PayException */ public static String createPayJsRequestJsonV3(PayPackageV3 payPackage, - WeixinAccount weixinAccount) throws PayException { + WeixinMpAccount weixinAccount) throws PayException { String paySignKey = weixinAccount.getPaySignKey(); payPackage.setSign(paysignMd5(payPackage, paySignKey)); PrePay prePay = createPrePay(payPackage); @@ -201,7 +197,7 @@ public class PayUtil { String payJsRequestXml = XStream.to(payPackage).replaceAll("__", "_"); HttpRequest request = new HttpRequest(); try { - Response response = request.post(UNIFIEDORDER, payJsRequestXml); + Response response = request.post(Consts.UNIFIEDORDER, payJsRequestXml); prePay = response.getAsObject(new TypeReference() { }); } catch (WeixinException e) { @@ -263,17 +259,17 @@ public class PayUtil { * 与订单ID等价 * @return */ - public String createNativePayRequestURLV2(WeixinAccount weixinAccount, + public String createNativePayRequestURLV2(WeixinMpAccount weixinAccount, String productId) { Map map = new HashMap(); String timestamp = DateUtil.timestamp2string(); String noncestr = RandomUtil.generateString(16); - map.put("appid", weixinAccount.getAppId()); + map.put("appid", weixinAccount.getId()); map.put("timestamp", timestamp); map.put("noncestr", noncestr); map.put("productid", productId); String sign = paysignSha(map, weixinAccount.getPaySignKey()); - return String.format(NATIVEURLV2, sign, weixinAccount.getAppId(), + return String.format(Consts.NATIVEURLV2, sign, weixinAccount.getId(), productId, timestamp, noncestr); } @@ -286,29 +282,29 @@ public class PayUtil { * 与订单ID等价 * @return */ - public String createNativePayRequestURLV3(WeixinAccount weixinAccount, + public String createNativePayRequestURLV3(WeixinMpAccount weixinAccount, String productId) { Map map = new HashMap(); String timestamp = DateUtil.timestamp2string(); String noncestr = RandomUtil.generateString(16); - map.put("appid", weixinAccount.getAppId()); + map.put("appid", weixinAccount.getId()); map.put("mch_id", weixinAccount.getMchId()); map.put("time_stamp", timestamp); map.put("nonce_str", noncestr); map.put("product_id", productId); String sign = paysignMd5(map, weixinAccount.getPaySignKey()); - return String.format(NATIVEURLV3, sign, weixinAccount.getAppId(), + return String.format(Consts.NATIVEURLV3, sign, weixinAccount.getId(), weixinAccount.getMchId(), productId, timestamp, noncestr); } - public static String createNativePayRequestV2(WeixinAccount weixinAccount, + public static String createNativePayRequestV2(WeixinMpAccount weixinAccount, PayPackageV2 payPackage) { NativePayResponseV2 payRequest = new NativePayResponseV2(weixinAccount, payPackage); Map map = new HashMap(); String timestamp = DateUtil.timestamp2string(); String noncestr = RandomUtil.generateString(16); - map.put("appid", weixinAccount.getAppId()); + map.put("appid", weixinAccount.getId()); map.put("timestamp", timestamp); map.put("noncestr", noncestr); map.put("package", payRequest.getPackageInfo()); @@ -336,12 +332,12 @@ public class PayUtil { * @param weixinAccount * 商户信息 * @return 返回数据 - * @see {@link com.foxinmy.weixin4j.mp.payment.PayUtil#createMicroPay(MicroPayPackage, WeixinAccount)} + * @see {@link com.foxinmy.weixin4j.mp.payment.PayUtil#createMicroPay(MicroPayPackage, WeixinMpAccount)} * @throws WeixinException */ public static com.foxinmy.weixin4j.mp.payment.v3.Order createMicroPay( String authCode, String body, String attach, String orderNo, - double orderFee, String ip, WeixinAccount weixinAccount) + double orderFee, String ip, WeixinMpAccount weixinAccount) throws WeixinException { MicroPayPackage payPackage = new MicroPayPackage(weixinAccount, body, attach, orderNo, orderFee, ip, authCode); @@ -359,13 +355,13 @@ public class PayUtil { * @throws WeixinException */ public static com.foxinmy.weixin4j.mp.payment.v3.Order createMicroPay( - MicroPayPackage payPackage, WeixinAccount weixinAccount) + MicroPayPackage payPackage, WeixinMpAccount weixinAccount) throws WeixinException { String sign = paysignMd5(payPackage, weixinAccount.getPaySignKey()); payPackage.setSign(sign); String para = XStream.to(payPackage).replaceAll("__", "_"); HttpRequest request = new HttpRequest(); - Response response = request.post(MICROPAYURL, para); + Response response = request.post(Consts.MICROPAYURL, para); return response .getAsObject(new TypeReference() { }); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/JsPayRequestV2.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/JsPayRequestV2.java index f0ad15a4..774aeb56 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/JsPayRequestV2.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/JsPayRequestV2.java @@ -5,7 +5,7 @@ import java.beans.Transient; import org.apache.commons.codec.digest.DigestUtils; import com.alibaba.fastjson.annotation.JSONField; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.payment.PayRequest; import com.foxinmy.weixin4j.util.MapUtil; @@ -28,8 +28,8 @@ public class JsPayRequestV2 extends PayRequest { private static final long serialVersionUID = -5972173459255255197L; - public JsPayRequestV2(WeixinAccount weixinAccount, PayPackageV2 payPackage) { - this.setAppId(weixinAccount.getAppId()); + public JsPayRequestV2(WeixinMpAccount weixinAccount, PayPackageV2 payPackage) { + this.setAppId(weixinAccount.getId()); this.setPackageInfo(package2string(payPackage, weixinAccount.getPartnerKey())); } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java index e7418e78..398c6ed7 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v2/NativePayResponseV2.java @@ -1,6 +1,6 @@ package com.foxinmy.weixin4j.mp.payment.v2; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.thoughtworks.xstream.annotations.XStreamAlias; /** @@ -21,7 +21,7 @@ public class NativePayResponseV2 extends JsPayRequestV2 { @XStreamAlias("RetErrMsg") private String retMsg; - public NativePayResponseV2(WeixinAccount weixinAccount, + public NativePayResponseV2(WeixinMpAccount weixinAccount, PayPackageV2 payPackage) { super(weixinAccount, payPackage); this.retCode = "0"; diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java index 4b28abc0..349098ac 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/payment/v3/PayPackageV3.java @@ -4,7 +4,7 @@ import java.util.Date; import org.apache.commons.lang3.StringUtils; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.payment.PayPackage; import com.foxinmy.weixin4j.mp.type.TradeType; import com.foxinmy.weixin4j.util.RandomUtil; @@ -38,17 +38,17 @@ public class PayPackageV3 extends PayPackage { } - public PayPackageV3(WeixinAccount weixinAccount, String openId, + public PayPackageV3(WeixinMpAccount weixinAccount, String openId, String body, String out_trade_no, double total_fee, String spbill_create_ip, TradeType tradeType) { this(weixinAccount, openId, body, null, out_trade_no, total_fee, spbill_create_ip, null, tradeType); } - public PayPackageV3(WeixinAccount weixinAccount, String openId, + public PayPackageV3(WeixinMpAccount weixinAccount, String openId, String body, String attach, String out_trade_no, double total_fee, String spbill_create_ip, String notify_url, TradeType tradeType) { - this(weixinAccount.getAppId(), weixinAccount.getMchId(), weixinAccount + this(weixinAccount.getId(), weixinAccount.getMchId(), weixinAccount .getDeviceInfo(), RandomUtil.generateString(16), body, attach, out_trade_no, total_fee, spbill_create_ip, null, null, null, notify_url, tradeType, openId, null); diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/BaseResponse.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/BaseResponse.java index e73f9b99..e219ead2 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/BaseResponse.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/BaseResponse.java @@ -1,16 +1,11 @@ package com.foxinmy.weixin4j.mp.response; -import java.io.Writer; - import com.foxinmy.weixin4j.model.BaseMsg; import com.foxinmy.weixin4j.mp.type.ResponseType; import com.foxinmy.weixin4j.msg.BaseMessage; import com.foxinmy.weixin4j.util.ClassUtil; import com.foxinmy.weixin4j.xml.XStream; import com.thoughtworks.xstream.annotations.XStreamAlias; -import com.thoughtworks.xstream.io.HierarchicalStreamWriter; -import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver; -import com.thoughtworks.xstream.io.json.JsonWriter; /** * 响应消息基类 @@ -28,26 +23,15 @@ public class BaseResponse extends BaseMsg { private static final long serialVersionUID = 7761192742840031607L; protected final static XStream xmlStream = XStream.get(); - private final static XStream jsonStream = new XStream( - new JsonHierarchicalStreamDriver() { - public HierarchicalStreamWriter createWriter(Writer writer) { - return new JsonWriter(writer, JsonWriter.DROP_ROOT_MODE); - } - }); - - @XStreamAlias("MsgType") - private ResponseType msgType; // 消息类型 - static { Class[] classes = ClassUtil.getClasses( BaseResponse.class.getPackage()).toArray(new Class[0]); + xmlStream.autodetectAnnotations(true); xmlStream.processAnnotations(classes); - - jsonStream.setMode(XStream.NO_REFERENCES); - jsonStream.autodetectAnnotations(true); - jsonStream.processAnnotations(classes); } + @XStreamAlias("MsgType") + private ResponseType msgType; // 消息类型 public BaseResponse(ResponseType msgType) { this.msgType = msgType; @@ -59,7 +43,7 @@ public class BaseResponse extends BaseMsg { public BaseResponse(ResponseType msgType, String toUserName, String fromUserName) { - super(toUserName,fromUserName); + super(toUserName, fromUserName); this.msgType = msgType; } @@ -78,17 +62,6 @@ public class BaseResponse extends BaseMsg { * @return xml字符串 */ public String toXml() { - Class targetClass = msgType.getMessageClass(); - xmlStream.alias("xml", targetClass); return xmlStream.toXML(this); } - - /** - * 消息对象转换为微信服务器接受的json格式字符串 - * - * @return json字符串 - */ - public String toJson() { - return jsonStream.toXML(this); - } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TemplateMessage.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TemplateMessage.java index 53296f0c..52fbe79c 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TemplateMessage.java +++ b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/response/TemplateMessage.java @@ -1,13 +1,9 @@ package com.foxinmy.weixin4j.mp.response; -import java.beans.Transient; import java.io.Serializable; import java.util.HashMap; import java.util.Map; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.annotation.JSONField; - /** * 模板消息 * @@ -115,10 +111,4 @@ public class TemplateMessage implements Serializable { + template_id + ", url=" + url + ", topcolor=" + topcolor + ", data=" + data + "]"; } - - @Transient - @JSONField(serialize = false) - public String toJson() { - return JSON.toJSONString(this); - } } diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/Gender.java b/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/Gender.java deleted file mode 100644 index d017e058..00000000 --- a/weixin4j-mp/weixin4j-mp-api/src/main/java/com/foxinmy/weixin4j/mp/type/Gender.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.foxinmy.weixin4j.mp.type; - -/** - * 用户性别 - * @className Gender - * @author jy - * @date 2014年11月5日 - * @since JDK 1.7 - * @see - */ -public enum Gender { - male(1), female(2), unknown(0); - - private int sex; - - Gender(int sex) { - this.sex = sex; - } - - public int getInt() { - return sex; - } -} diff --git a/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties b/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties index 4cc5d0b7..8e3edf72 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties +++ b/weixin4j-mp/weixin4j-mp-api/src/main/resources/weixin.properties @@ -1,6 +1,6 @@ # \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath # \u516c\u4f17\u53f7\u4fe1\u606f -account={"appId":"wx4ab8f8de58159a57","appSecret":"1d4eb0f4bf556aaed539f30ed05ca795",\ +account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\ "token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\ "encodingAesKey":"\u516c\u4f17\u53f7\u8bbe\u7f6e\u4e86\u52a0\u5bc6\u65b9\u5f0f\u4e14\u4e3a\u300c\u5b89\u5168\u6a21\u5f0f\u300d\u65f6\u9700\u8981\u586b\u5165",\ "mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\ diff --git a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/TokenTest.java b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/TokenTest.java index da879980..3de54ff7 100644 --- a/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/TokenTest.java +++ b/weixin4j-mp/weixin4j-mp-api/src/test/java/com/foxinmy/weixin4j/mp/test/TokenTest.java @@ -7,6 +7,7 @@ import org.junit.Test; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.token.FileTokenHolder; import com.foxinmy.weixin4j.token.TokenHolder; +import com.foxinmy.weixin4j.type.AccountType; /** * token测试 @@ -22,7 +23,7 @@ public class TokenTest { @Before public void setUp() { - tokenHolder = new FileTokenHolder(); + tokenHolder = new FileTokenHolder(AccountType.MP); } @Test diff --git a/weixin4j-mp/weixin4j-mp-server/README.md b/weixin4j-mp/weixin4j-mp-server/README.md index 752ea0a8..a1a47270 100644 --- a/weixin4j-mp/weixin4j-mp-server/README.md +++ b/weixin4j-mp/weixin4j-mp-server/README.md @@ -1,7 +1,7 @@ weixin4j-mp-server ================== -微信netty服务 +微信公众平台netty服务 ------------ 功能列表 @@ -26,7 +26,7 @@ weixin4j-mp-server 示例(properties中换行用右斜杆\\) -> account={"appId":"appId","appSecret":"appSecret", +> account={"id":"appId","secret":"appSecret", > "token":"开放者的token 非必须","openId":"公众号的openid 非必须", > "encodingAesKey":"公众号设置了加密方式且为「安全模式」时需要填入", > "mchId":"V3.x版本下的微信商户号", diff --git a/weixin4j-mp/weixin4j-mp-server/pom.xml b/weixin4j-mp/weixin4j-mp-server/pom.xml index 9b63f36d..0c1c43f4 100644 --- a/weixin4j-mp/weixin4j-mp-server/pom.xml +++ b/weixin4j-mp/weixin4j-mp-server/pom.xml @@ -10,7 +10,7 @@ weixin4j-mp-server weixin4j-mp-server - https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-server + https://github.com/foxinmy/weixin4j/tree/master/weixin4j-mp/weixin4j-mp-server 微信公众号服务 weixin-mp-server diff --git a/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageDecoder.java b/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageDecoder.java index d6f575a3..6d6e7d49 100644 --- a/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageDecoder.java +++ b/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageDecoder.java @@ -13,7 +13,7 @@ import org.apache.http.Consts; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.model.HttpWeixinMessage; import com.foxinmy.weixin4j.mp.type.EncryptType; import com.foxinmy.weixin4j.util.ConfigUtil; @@ -37,7 +37,7 @@ public class WeixinMessageDecoder extends @Override protected void decode(ChannelHandlerContext ctx, FullHttpRequest req, List out) throws Exception { - WeixinAccount account = ConfigUtil.getWeixinAccount(); + WeixinMpAccount mpAccount = ConfigUtil.getWeixinMpAccount(); String xmlContent = req.content().toString(Consts.UTF_8); HttpWeixinMessage message = new HttpWeixinMessage(); if (StringUtils.isNotBlank(xmlContent)) { @@ -72,10 +72,10 @@ public class WeixinMessageDecoder extends message.setXmlContent(xmlContent); if (message.getEncryptType() == EncryptType.AES) { - message.setXmlContent(MessageUtil.aesDecrypt(account.getAppId(), - account.getEncodingAesKey(), message.getEncryptContent())); + message.setXmlContent(MessageUtil.aesDecrypt(mpAccount.getId(), + mpAccount.getEncodingAesKey(), message.getEncryptContent())); } - message.setToken(account.getToken()); + message.setToken(mpAccount.getToken()); out.add(message); } } diff --git a/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageEncoder.java b/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageEncoder.java index 75bd9b32..1d2c10d2 100644 --- a/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageEncoder.java +++ b/weixin4j-mp/weixin4j-mp-server/src/main/java/com/foxinmy/weixin4j/mp/server/WeixinMessageEncoder.java @@ -11,7 +11,7 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import com.foxinmy.weixin4j.model.WeixinAccount; +import com.foxinmy.weixin4j.model.WeixinMpAccount; import com.foxinmy.weixin4j.mp.response.BaseResponse; import com.foxinmy.weixin4j.mp.util.HttpUtil; import com.foxinmy.weixin4j.util.ConfigUtil; @@ -45,13 +45,13 @@ public class WeixinMessageEncoder extends MessageToMessageEncoder @Override protected void encode(ChannelHandlerContext ctx, BaseResponse response, List out) throws Exception { - WeixinAccount account = ConfigUtil.getWeixinAccount(); + WeixinMpAccount mpAccount = ConfigUtil.getWeixinMpAccount(); String xmlContent = response.toXml(); String nonce = RandomUtil.generateString(32); String timestamp = DateUtil.timestamp2string(); - String encrtypt = MessageUtil.aesEncrypt(account.getAppId(), - account.getEncodingAesKey(), xmlContent); - String msgSignature = MessageUtil.signature(account.getToken(), nonce, + String encrtypt = MessageUtil.aesEncrypt(mpAccount.getId(), + mpAccount.getEncodingAesKey(), xmlContent); + String msgSignature = MessageUtil.signature(mpAccount.getToken(), nonce, timestamp, encrtypt); Map map = new HashMap(); map.put("Encrypt", encrtypt); diff --git a/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties b/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties index f1b18e7f..61fbfbe5 100644 --- a/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties +++ b/weixin4j-mp/weixin4j-mp-server/src/main/resources/weixin.properties @@ -1,5 +1,5 @@ # \u516c\u4f17\u53f7\u4fe1\u606f -account={"appId":"wx4ab8f8de58159a57","appSecret":"1d4eb0f4bf556aaed539f30ed05ca795",\ +account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\ "token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\ "encodingAesKey":"\u516c\u4f17\u53f7\u8bbe\u7f6e\u4e86\u52a0\u5bc6\u65b9\u5f0f\u4e14\u4e3a\u300c\u5b89\u5168\u6a21\u5f0f\u300d\u9700\u8981\u586b\u5165",\ "mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\ diff --git a/weixin4j-qy/README.md b/weixin4j-qy/README.md index 4cf1a442..0dc9807c 100644 --- a/weixin4j-qy/README.md +++ b/weixin4j-qy/README.md @@ -1,17 +1,27 @@ weixin4j-qy =========== -@(weixin4j)[企业号] - -微信[企业号](http://qydev.weixin.qq.com/wiki/index.php)开发工具包 +[微信企业号](http://qydev.weixin.qq.com/wiki/index.php)开发工具包 --------------------------------------------------------------- 功能列表 ------- +* **weixin4j-qy-api** -如何使用 --------- + + DepartApi `部门管理API` + + + UserApi `成员管理API` + + + TagApi `标签管理API` 更新LOG ------- +* 2014-11-19 + + 得到`weixin4j-qy-api`和`weixin4j-qy-server`工程 + + + **weixin4j-qy-api**: 新增部门管理接口 + + + **weixin4j-qy-api**: 新增用户管理接口 + + + **weixin4j-qy-api**: 新增标签管理接口 diff --git a/weixin4j-qy/pom.xml b/weixin4j-qy/pom.xml index 97a50f47..b577eeb7 100644 --- a/weixin4j-qy/pom.xml +++ b/weixin4j-qy/pom.xml @@ -10,6 +10,18 @@ weixin4j-qy weixin4j-qy + pom https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy 微信企业号工具包 + + weixin4j-qy-api + weixin4j-qy-server + + + + com.foxinmy.weixin4j + weixin4j-base + ${weixin4j.base.version} + + diff --git a/weixin4j-qy/weixin4j-qy-api/.gitignore b/weixin4j-qy/weixin4j-qy-api/.gitignore new file mode 100644 index 00000000..c880f664 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/.gitignore @@ -0,0 +1,28 @@ +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# eclipse ignore +*.settings/* +/.project +/.classpath +/.tomcatplugin + +# maven ignore +target/* + +# other ignore +*.log +*.tmp +Thumbs.db +/target/ +.DS_Store diff --git a/weixin4j-qy/weixin4j-qy-api/README.md b/weixin4j-qy/weixin4j-qy-api/README.md new file mode 100644 index 00000000..35b3831f --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/README.md @@ -0,0 +1,56 @@ +weixin4j-qy-api +=============== + +[微信企业号](http://qydev.weixin.qq.com/wiki/index.php)开发工具包 +--------------------------------------------------------------- + +功能列表 +------- + + * DepartApi `部门管理API` + + * UserApi `成员管理API` + + * TagApi `标签管理API` + +如何使用 +-------- +1.API工程可以单独打包到其他项目中使用,需新增或拷贝`weixin.properties`文件到项目的`classpath`中 + +weixin.properties说明 + +| 属性名 | 说明 | +| :---------- | :-------------- | +| account | 微信企业号信息 `json格式` | +| token_path | 使用FileTokenHolder时token保存的物理路径 | + +示例(properties中换行用右斜杆\\) + +> account={"id":"corpid","secret":"corpsecret", +> "token":"开放者的token 非必须", +> "encodingAesKey":"AES加密密钥"} +> token_path=/tmp/weixin/token
+ +2.实例化一个`WeixinProxy`对象,调用API + + WeixinProxy weixinProxy = new WeixinProxy(); + // weixinProxy = new WeixinProxy(corpid,corpsecret); + // weixinProxy = new WeixinProxy(weixinAccount); + weixinProxy.getUser(userid); + +3.针对`token`存储有两种方案,`File存储`/`Redis存储`,当然也可自己实现`TokenHolder`(继承`AbstractTokenHolder`并重写`getToken`方法),默认使用文件(xml)的方式保存token,如果环境中支持`redis`,建议使用`RedisTokenHolder`. + + WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder()); + // weixinProxy = new WeixinProxy(new RedisTokenHolder(weixinAccount)); + +4.`mvn package`. + +更新LOG +------- +* 2014-11-19 + + + 新增`部门管理`接口 + + + 新增`用户管理`接口 + + + 新增`标签管理`接口 diff --git a/weixin4j-qy/weixin4j-qy-api/pom.xml b/weixin4j-qy/weixin4j-qy-api/pom.xml new file mode 100644 index 00000000..31b4bd09 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + com.foxinmy.weixin4j + weixin4j-qy + 0.0.1-SNAPSHOT + + weixin4j-qy-api + weixin4j-qy-api + https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy/weixin4j-qy-api + 微信企业号API + + weixin4j-qy-api + + + org.apache.maven.plugins + maven-assembly-plugin + + + + diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/assembly.xml b/weixin4j-qy/weixin4j-qy-api/src/main/assembly.xml new file mode 100644 index 00000000..67b38b63 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/assembly.xml @@ -0,0 +1,31 @@ + + full + + jar + + false + + + target/classes + / + + /** + + + *.properties + *.xml + + + + + + true + + com.foxinmy.weixin4j:weixin4j-base + + + + \ No newline at end of file diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java new file mode 100644 index 00000000..289c0e0e --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/WeixinProxy.java @@ -0,0 +1,344 @@ +package com.foxinmy.weixin4j.qy; + +import java.util.List; + +import com.alibaba.fastjson.JSONArray; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.model.WeixinQyAccount; +import com.foxinmy.weixin4j.qy.api.DepartApi; +import com.foxinmy.weixin4j.qy.api.TagApi; +import com.foxinmy.weixin4j.qy.api.UserApi; +import com.foxinmy.weixin4j.qy.model.Department; +import com.foxinmy.weixin4j.qy.model.User; +import com.foxinmy.weixin4j.qy.type.UserStatus; +import com.foxinmy.weixin4j.token.FileTokenHolder; +import com.foxinmy.weixin4j.token.TokenHolder; +import com.foxinmy.weixin4j.type.AccountType; + +/** + * 微信企业号接口实现 + * + * @className WeixinProxy + * @author jy + * @date 2014年11月19日 + * @since JDK 1.7 + * @see api文档 + */ +public class WeixinProxy { + private final DepartApi departApi; + private final UserApi userApi; + private final TagApi tagApi; + + /** + * 默认采用文件存放Token信息 + */ + public WeixinProxy() { + this(new FileTokenHolder(AccountType.QY)); + } + + /** + * appid,appsecret + * + * @param appid + * @param appsecret + */ + public WeixinProxy(String corpid, String corpsecret) { + this(new WeixinQyAccount(corpid, corpsecret)); + } + + /** + * WeixinAccount对象 + * + * @param weixinAccount + */ + public WeixinProxy(WeixinQyAccount weixinAccount) { + this(new FileTokenHolder(weixinAccount)); + } + + /** + * TokenHolder对象 + * + * @param tokenHolder + */ + public WeixinProxy(TokenHolder tokenHolder) { + this.departApi = new DepartApi(tokenHolder); + this.userApi = new UserApi(tokenHolder); + this.tagApi = new TagApi(tokenHolder); + } + + /** + * 创建部门(根部门的parentid为1) + * + * @param depart + * 部门对象 + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 创建部门说明 + * @see com.foxinmy.weixin4j.qy.api.DepartApi + * @return 部门ID + * @throws WeixinException + */ + public int createDepart(Department depart) throws WeixinException { + return departApi.createDepart(depart); + } + + /** + * 更新部门(如果非必须的字段未指定 则不更新该字段之前的设置值) + * + * @param depart + * 部门对象 + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 更新部门说明 + * @see com.foxinmy.weixin4j.qy.api.DepartApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult updateDepart(Department depart) throws WeixinException { + return departApi.updateDepart(depart); + } + + /** + * 查询部门列表(以部门的order字段从小到大排列) + * + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 获取部门列表 + * @see com.foxinmy.weixin4j.qy.api.DepartApi + * @return 部门列表 + * @throws WeixinException + */ + public List listDepart() throws WeixinException { + return departApi.listDepart(); + } + + /** + * 删除部门(不能删除根部门;不能删除含有子部门、成员的部门) + * + * @param departId + * 部门ID + * @see 删除部门说明 + * @see com.foxinmy.weixin4j.qy.api.DepartApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult deleteDepart(int departId) throws WeixinException { + return departApi.deleteDepart(departId); + } + + /** + * 创建成员 + * + * @param user + * 成员对象 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 创建成员说明 + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult createUser(User user) throws WeixinException { + return userApi.createUser(user); + } + + /** + * 更新用户(如果非必须的字段未指定 则不更新该字段之前的设置值) + * + * @param user + * 成员对象 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 更新成员说明 + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult updateUser(User user) throws WeixinException { + return userApi.updateUser(user); + } + + /** + * 获取成员 + * + * @param userid + * 成员唯一ID + * @see com.foxinmy.weixin4j.qy.model.User + * @see 获取成员说明 + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @return 成员对象 + * @throws WeixinException + */ + public User getUser(String userid) throws WeixinException { + return userApi.getUser(userid); + } + + /** + * 获取部门成员 + * + * @param departId + * 部门ID 必须 + * @param fetchChild + * 是否递归获取子部门下面的成员 非必须 + * @param userStatus + * 成员状态 status可叠加 非必须 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 获取部门成员说明 + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @return 成员列表 + * @throws WeixinException + */ + public List listUser(int departId, boolean fetchChild, + UserStatus userStatus) throws WeixinException { + return userApi.listUser(departId, fetchChild, userStatus); + } + + /** + * 获取部门下所有状态成员(不进行递归) + * + * @param departId + * 部门ID + * @see {@link com.foxinmy.weixin4j.qy.WeixinProxy#listUser(int, boolean,UserStatus)} + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @return 成员列表 + * @throws WeixinException + */ + public List listUser(int departId) throws WeixinException { + return userApi.listUser(departId); + } + + /** + * 删除成员 + * + * @param userid + * 成员ID + * @see 删除成员说明 + * @see com.foxinmy.weixin4j.qy.api.UserApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult deleteUser(String userid) throws WeixinException { + return userApi.deleteUser(userid); + } + + /** + * 创建标签(创建的标签属于管理组;默认为未加锁状态) + * + * @param tagName + * 标签名称 + * @see 创建标签说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @return 标签ID + * @throws WeixinException + */ + public int createTag(String tagName) throws WeixinException { + return tagApi.createTag(tagName); + } + + /** + * 更新标签(管理组必须是指定标签的创建者) + * + * @param tagId + * 标签ID + * @param tagName + * 标签名称 + * @see 更新标签说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult updateTag(int tagId, String tagName) + throws WeixinException { + return tagApi.updateTag(tagId, tagName); + } + + /** + * 删除标签(管理组必须是指定标签的创建者 并且标签的成员列表为空) + * + * @param tagId + * 标签ID + * @return 处理结果 + * @see 删除标签说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @throws WeixinException + */ + public JsonResult deleteTag(int tagId) throws WeixinException { + return tagApi.deleteTag(tagId); + } + + /** + * 获取标签列表 + * + * @see 获取标签列表说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @return 标签列表 + * @throws WeixinException + */ + public JSONArray listTag() throws WeixinException { + return tagApi.listTag(); + } + + /** + * 获取标签成员(管理组须拥有“获取标签成员”的接口权限,标签须对管理组可见;返回列表仅包含管理组管辖范围的成员) + * + * @param tagId + * 标签ID + * @see com.foxinmy.weixin4j.qy.model.User + * @see 获取标签成员说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @return 成员列表 + * @throws WeixinException + */ + public List getTagUsers(int tagId) throws WeixinException { + return tagApi.getTagUsers(tagId); + } + + /** + * 新增标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)
+ * 若部分userid非法,则在text中体现 + * + * @param tagId + * 标签ID + * @param userIds + * 成员ID + * @see 新增标签成员说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult addTagUsers(int tagId, List userIds) + throws WeixinException { + return tagApi.addTagUsers(tagId, userIds); + } + + /** + * 删除标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)
+ * 若部分userid非法,则在text中体现 + * + * @param tagId + * 标签ID + * @param userIds + * 成员ID + * @see 删除标签成员说明 + * @see com.foxinmy.weixin4j.qy.api.TagApi + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult deleteTagUsers(int tagId, List userIds) + throws WeixinException { + return tagApi.deleteTagUsers(tagId, userIds); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/BaseApi.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/BaseApi.java new file mode 100644 index 00000000..bbddb79a --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/BaseApi.java @@ -0,0 +1,57 @@ +package com.foxinmy.weixin4j.qy.api; + +import java.util.Map; +import java.util.ResourceBundle; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.foxinmy.weixin4j.http.HttpRequest; +import com.foxinmy.weixin4j.xml.Map2ObjectConverter; +import com.foxinmy.weixin4j.xml.XStream; +import com.thoughtworks.xstream.core.ClassLoaderReference; +import com.thoughtworks.xstream.mapper.DefaultMapper; + +/** + * + * @className BaseApi + * @author jy.hu + * @date 2014年11月18日 + * @since JDK 1.7 + * @see api文档 + */ +public class BaseApi { + protected final HttpRequest request = new HttpRequest(); + protected final static XStream mapXstream = XStream.get(); + private final static ResourceBundle weixinBundle; + static { + weixinBundle = ResourceBundle + .getBundle("com/foxinmy/weixin4j/qy/api/weixin"); + mapXstream.alias("xml", Map.class); + mapXstream.registerConverter(new Map2ObjectConverter(new DefaultMapper( + new ClassLoaderReference(XStream.class.getClassLoader())))); + } + + protected String map2xml(Map map) { + return mapXstream.toXML(map).replaceAll("__", "_"); + } + + @SuppressWarnings("unchecked") + protected Map xml2map(String xml) { + return mapXstream.fromXML(xml, Map.class); + } + + protected String getRequestUri(String key) { + String url = weixinBundle.getString(key); + Pattern p = Pattern.compile("(\\{[^\\}]*\\})"); + Matcher m = p.matcher(url); + StringBuffer sb = new StringBuffer(); + String sub = null; + while (m.find()) { + sub = m.group(); + m.appendReplacement(sb, + getRequestUri(sub.substring(1, sub.length() - 1))); + } + m.appendTail(sb); + return sb.toString(); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/DepartApi.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/DepartApi.java new file mode 100644 index 00000000..53a3b18f --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/DepartApi.java @@ -0,0 +1,110 @@ +package com.foxinmy.weixin4j.qy.api; + +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.http.Response; +import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.qy.model.Department; +import com.foxinmy.weixin4j.token.TokenHolder; + +/** + * 部门API + * + * @className DepartApi + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 管理部门说明 + */ +public class DepartApi extends BaseApi { + private final TokenHolder tokenHolder; + + public DepartApi(TokenHolder tokenHolder) { + this.tokenHolder = tokenHolder; + } + + /** + * 创建部门(根部门的parentid为1) + * + * @param depart + * 部门对象 + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 创建部门说明 + * @return 部门ID + * @throws WeixinException + */ + public int createDepart(Department depart) throws WeixinException { + String department_create_uri = getRequestUri("department_create_uri"); + JSONObject obj = (JSONObject) JSON.toJSON(depart); + obj.remove("id"); + Token token = tokenHolder.getToken(); + Response response = request.post( + String.format(department_create_uri, token.getAccessToken()), + obj.toJSONString()); + return response.getAsJson().getIntValue("id"); + } + + /** + * 更新部门(如果非必须的字段未指定 则不更新该字段之前的设置值) + * + * @param depart + * 部门对象 + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 更新部门说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult updateDepart(Department depart) throws WeixinException { + String department_update_uri = getRequestUri("department_update_uri"); + JSONObject obj = (JSONObject) JSON.toJSON(depart); + Token token = tokenHolder.getToken(); + Response response = request.post( + String.format(department_update_uri, token.getAccessToken()), + obj.toJSONString()); + return response.getAsJsonResult(); + } + + /** + * 查询部门列表(以部门的order字段从小到大排列) + * + * @see com.foxinmy.weixin4j.qy.model.Department + * @see 获取部门列表 + * @return 部门列表 + * @throws WeixinException + */ + public List listDepart() throws WeixinException { + String department_list_uri = getRequestUri("department_list_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(department_list_uri, + token.getAccessToken())); + return JSON.parseArray(response.getAsJson().getString("department"), + Department.class); + } + + /** + * 删除部门(不能删除根部门;不能删除含有子部门、成员的部门) + * + * @param departId + * 部门ID + * @see 删除部门说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult deleteDepart(int departId) throws WeixinException { + String department_delete_uri = getRequestUri("department_delete_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(department_delete_uri, + token.getAccessToken(), departId)); + return response.getAsJsonResult(); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/TagApi.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/TagApi.java new file mode 100644 index 00000000..c7d1d0f3 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/TagApi.java @@ -0,0 +1,179 @@ +package com.foxinmy.weixin4j.qy.api; + +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.http.Response; +import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.qy.model.User; +import com.foxinmy.weixin4j.token.TokenHolder; + +/** + * 标签API + * + * @className TagApi + * @author jy + * @date 2014年11月19日 + * @since JDK 1.7 + * @see 管理标签 + */ +public class TagApi extends BaseApi { + private final TokenHolder tokenHolder; + + public TagApi(TokenHolder tokenHolder) { + this.tokenHolder = tokenHolder; + } + + /** + * 创建标签(创建的标签属于管理组;默认为未加锁状态) + * + * @param tagName + * 标签名称 + * @see 创建标签说明 + * @return 标签ID + * @throws WeixinException + */ + public int createTag(String tagName) throws WeixinException { + String tag_create_uri = getRequestUri("tag_create_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post( + String.format(tag_create_uri, token.getAccessToken()), + String.format("{\"tagname\":\"%s\"}", tagName)); + return response.getAsJson().getIntValue("tagid"); + } + + /** + * 更新标签(管理组必须是指定标签的创建者) + * + * @param tagId + * 标签ID + * @param tagName + * 标签名称 + * @see 更新标签说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult updateTag(int tagId, String tagName) + throws WeixinException { + String tag_update_uri = getRequestUri("tag_update_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(tag_update_uri, + token.getAccessToken()), String.format( + "{\"tagid\":%d,\"tagname\":\"%s\"}", tagId, tagName)); + return response.getAsJsonResult(); + } + + /** + * 删除标签(管理组必须是指定标签的创建者 并且标签的成员列表为空) + * + * @param tagId + * 标签ID + * @return 处理结果 + * @see 删除标签说明 + * @throws WeixinException + */ + public JsonResult deleteTag(int tagId) throws WeixinException { + String tag_delete_uri = getRequestUri("tag_delete_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(tag_delete_uri, + token.getAccessToken(), tagId)); + return response.getAsJsonResult(); + } + + /** + * 获取标签列表 + * + * @see 获取标签列表说明 + * @return 标签列表 + * @throws WeixinException + */ + public JSONArray listTag() throws WeixinException { + String tag_list_uri = getRequestUri("tag_list_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(tag_list_uri, + token.getAccessToken())); + return response.getAsJson().getJSONArray("taglist"); + } + + /** + * 获取标签成员(管理组须拥有“获取标签成员”的接口权限,标签须对管理组可见;返回列表仅包含管理组管辖范围的成员) + * + * @param tagId + * 标签ID + * @see com.foxinmy.weixin4j.qy.model.User + * @see 获取标签成员说明 + * @return 成员列表 + * @throws WeixinException + */ + public List getTagUsers(int tagId) throws WeixinException { + String tag_get_user_uri = getRequestUri("tag_get_user_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(tag_get_user_uri, + token.getAccessToken(), tagId)); + return JSON.parseArray(response.getAsJson().getString("userlist"), + User.class); + } + + /** + * 新增标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)
+ * 若部分userid非法,则在text中体现 + * + * @param tagId + * 标签ID + * @param userIds + * 成员ID + * @see 新增标签成员说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult addTagUsers(int tagId, List userIds) + throws WeixinException { + String tag_add_user_uri = getRequestUri("tag_add_user_uri"); + return excuteUsers(tag_add_user_uri, tagId, userIds); + } + + /** + * 删除标签成员(标签对管理组可见且未加锁,成员属于管理组管辖范围)
+ * 若部分userid非法,则在text中体现 + * + * @param tagId + * 标签ID + * @param userIds + * 成员ID + * @see 删除标签成员说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult deleteTagUsers(int tagId, List userIds) + throws WeixinException { + String tag_delete_user_uri = getRequestUri("tag_delete_user_uri"); + return excuteUsers(tag_delete_user_uri, tagId, userIds); + } + + private JsonResult excuteUsers(String uri, int tagId, List userIds) + throws WeixinException { + JSONObject obj = new JSONObject(); + obj.put("tagid", tagId); + obj.put("userlist", userIds); + Token token = tokenHolder.getToken(); + Response response = request.post( + String.format(uri, token.getAccessToken()), obj.toJSONString()); + obj = response.getAsJson(); + JsonResult result = JSON.toJavaObject(obj, JsonResult.class); + result.setText(obj.getString("invalidlist")); + return result; + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java new file mode 100644 index 00000000..b78ac07b --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/UserApi.java @@ -0,0 +1,159 @@ +package com.foxinmy.weixin4j.qy.api; + +import java.util.List; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.http.Response; +import com.foxinmy.weixin4j.model.Token; +import com.foxinmy.weixin4j.qy.model.User; +import com.foxinmy.weixin4j.qy.type.UserStatus; +import com.foxinmy.weixin4j.token.TokenHolder; + +/** + * 成员API + * + * @className UserApi + * @author jy + * @date 2014年11月19日 + * @since JDK 1.7 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 管理成员说明 + */ +public class UserApi extends BaseApi { + private final TokenHolder tokenHolder; + + public UserApi(TokenHolder tokenHolder) { + this.tokenHolder = tokenHolder; + } + + /** + * 创建成员 + * + * @param user + * 成员对象 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 创建成员说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult createUser(User user) throws WeixinException { + String user_create_uri = getRequestUri("user_create_uri"); + return excute(user_create_uri, user); + } + + /** + * 更新用户(如果非必须的字段未指定 则不更新该字段之前的设置值) + * + * @param user + * 成员对象 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 更新成员说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult updateUser(User user) throws WeixinException { + String user_update_uri = getRequestUri("user_update_uri"); + return excute(user_update_uri, user); + } + + private JsonResult excute(String uri, User user) throws WeixinException { + JSONObject obj = (JSONObject) JSON.toJSON(user); + Object extattr = obj.remove("extattr"); + if (extattr != null) { + JSONObject attrs = new JSONObject(); + attrs.put("attrs", extattr); + obj.put("extattr", attrs); + } + Token token = tokenHolder.getToken(); + Response response = request.post( + String.format(uri, token.getAccessToken()), obj.toJSONString()); + return response.getAsJsonResult(); + } + + /** + * 获取成员 + * + * @param userid + * 成员唯一ID + * @see com.foxinmy.weixin4j.qy.model.User + * @see 获取成员说明 + * @return 成员对象 + * @throws WeixinException + */ + public User getUser(String userid) throws WeixinException { + String user_get_uri = getRequestUri("user_get_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(user_get_uri, + token.getAccessToken(), userid)); + JSONObject obj = response.getAsJson(); + Object attrs = obj.getJSONObject("extattr").remove("attrs"); + if (attrs != null) { + obj.put("extattr", attrs); + } + return JSON.toJavaObject(obj, User.class); + } + + /** + * 获取部门成员 + * + * @param departId + * 部门ID 必须 + * @param fetchChild + * 是否递归获取子部门下面的成员 非必须 + * @param userStatus + * 成员状态 status可叠加 非必须 + * @see com.foxinmy.weixin4j.qy.model.User + * @see 获取部门成员说明 + * @return 成员列表 + * @throws WeixinException + */ + public List listUser(int departId, boolean fetchChild, + UserStatus userStatus) throws WeixinException { + String user_list_uri = getRequestUri("user_list_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(user_list_uri, + token.getAccessToken(), departId, fetchChild ? 1 : 0, + userStatus.getVal())); + return JSON.parseArray(response.getAsJson().getString("userlist"), + User.class); + } + + /** + * 获取部门下所有状态成员(不进行递归) + * + * @param departId + * 部门ID + * @see {@link com.foxinmy.weixin4j.qy.api.UserApi#listUser(int, boolean,UserStatus)} + * @return 成员列表 + * @throws WeixinException + */ + public List listUser(int departId) throws WeixinException { + return listUser(departId, false, UserStatus.BOTH); + } + + /** + * 删除成员 + * + * @param userid + * 成员ID + * @see 删除成员说明 + * @return 处理结果 + * @throws WeixinException + */ + public JsonResult deleteUser(String userid) throws WeixinException { + String user_delete_uri = getRequestUri("user_delete_uri"); + Token token = tokenHolder.getToken(); + Response response = request.post(String.format(user_delete_uri, + token.getAccessToken(), userid)); + return response.getAsJsonResult(); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties new file mode 100644 index 00000000..1c74445a --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/api/weixin.properties @@ -0,0 +1,39 @@ +# ---------------------------------------------------------------------------- +# api\u9996\u9875 +# http://qydev.weixin.qq.com/wiki/index.php +# ---------------------------------------------------------------------------- + +api_base_url=https://qyapi.weixin.qq.com/cgi-bin + +# \u521b\u5efa\u90e8\u95e8 +department_create_uri={api_base_url}/department/create?access_token=%s +# \u66f4\u65b0\u90e8\u95e8 +department_update_uri={api_base_url}/department/update?access_token=%s +# \u90e8\u95e8\u5217\u8868 +department_list_uri={api_base_url}/department/list?access_token=%s +# \u5220\u9664\u90e8\u95e8 +department_delete_uri={api_base_url}/department/delete?access_token=%s&id=%d +# \u521b\u5efa\u6210\u5458 +user_create_uri={api_base_url}/user/create?access_token=%s +# \u66f4\u65b0\u6210\u5458 +user_update_uri={api_base_url}/user/update?access_token=%s +# \u83b7\u53d6\u6210\u5458 +user_get_uri={api_base_url}/user/get?access_token=%s&userid=%s +# \u83b7\u53d6\u90e8\u95e8\u6210\u5458 +user_list_uri={api_base_url}/user/simplelist?access_token=%s&department_id=%d&fetch_child=%d&status=%d +# \u5220\u9664\u6210\u5458 +user_delete_uri={api_base_url}/user/delete?access_token=%s&userid=%s +# \u521b\u5efa\u6807\u7b7e +tag_create_uri={api_base_url}/tag/create?access_token=%s +# \u66f4\u65b0\u6807\u7b7e +tag_update_uri={api_base_url}/tag/update?access_token=%s +# \u5220\u9664\u6807\u7b7e +tag_delete_uri={api_base_url}/tag/delete?access_token=%s&tagid=%d +# \u83b7\u53d6\u6807\u7b7e +tag_list_uri={api_base_url}/tag/list?access_token=%s +# \u83b7\u53d6\u6807\u7b7e\u6210\u5458 +tag_get_user_uri={api_base_url}/tag/get?access_token=%s&tagid=%d +# \u6dfb\u52a0\u6807\u7b7e\u6210\u5458 +tag_add_user_uri={api_base_url}/tag/addtagusers?access_token=%s +# \u5220\u9664\u6807\u7b7e\u6210\u5458 +tag_delete_user_uri={api_base_url}/tag/deltagusers?access_token=%s \ No newline at end of file diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/Department.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/Department.java new file mode 100644 index 00000000..f5019721 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/Department.java @@ -0,0 +1,74 @@ +package com.foxinmy.weixin4j.qy.model; + +import java.io.Serializable; + +/** + * 部门对象 + * + * @className Department + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see 管理部门说明 + */ +public class Department implements Serializable { + + private static final long serialVersionUID = -2567893218591084288L; + private int id; // 部门ID + private String name; // 部门名称。长度限制为1~64个字符 + private int parentid;// 父亲部门id。根部门id为1 + private int order;// 在父部门中的次序。从1开始,数字越大排序越靠后 + + public Department() { + + } + + public Department(String name) { + this(name, 1, 1); + } + + public Department(String name, int parentid, int order) { + this.name = name; + this.parentid = parentid; + this.order = order; + } + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getParentid() { + return parentid; + } + + public void setParentid(int parentid) { + this.parentid = parentid; + } + + public int getOrder() { + return order; + } + + public void setOrder(int order) { + this.order = order; + } + + @Override + public String toString() { + return "Department [id=" + id + ", name=" + name + ", parentid=" + + parentid + ", order=" + order + "]"; + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/NameValue.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/NameValue.java new file mode 100644 index 00000000..4e7fcf11 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/NameValue.java @@ -0,0 +1,40 @@ +package com.foxinmy.weixin4j.qy.model; + +import java.io.Serializable; + +public class NameValue implements Serializable { + + private static final long serialVersionUID = -348620146718819093L; + private String name; + private String value; + + public NameValue() { + + } + + public NameValue(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "NameValue [name=" + name + ", value=" + value + "]"; + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/User.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/User.java new file mode 100644 index 00000000..7bccb807 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/model/User.java @@ -0,0 +1,203 @@ +package com.foxinmy.weixin4j.qy.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.alibaba.fastjson.annotation.JSONField; +import com.foxinmy.weixin4j.model.Gender; +import com.foxinmy.weixin4j.qy.type.UserStatus; + +/** + * 部门成员对象 + * + * @className User + * @author jy + * @date 2014年11月19日 + * @since JDK 1.7 + * @see 管理成员说明 + */ +public class User implements Serializable { + + private static final long serialVersionUID = 4747301605060801611L; + private String userid;// 是 员工UserID。对应管理端的帐号,企业内必须唯一。长度为1~64个字符 + private String name;// 是 成员名称。长度为1~64个字符 + private List department;// 否 成员所属部门id列表。注意,每个部门的直属员工上限为1000个 + private String position;// 否 职位信息。长度为0~64个字符 + private String mobile;// 否 手机号码。企业内必须唯一,mobile/weixinid/email三者不能同时为空 + private int gender;// 否 性别。gender=0表示男,=1表示女。默认gender=0 + private String tel;// 否 办公电话。长度为0~64个字符 + private String email;// 否 邮箱。长度为0~64个字符。企业内必须唯一 + private String weixinid;// 否 微信号。企业内必须唯一 + private String avatar;// 头像url。注:如果要获取小图将url最后的"/0"改成"/64"即可 + private int status;// 关注状态: 1=已关注,2=已冻结,4=未关注 + private List extattr;// 否 扩展属性。扩展属性需要在WEB管理端创建后才生效,否则忽略未知属性的赋值 + + public User() { + this.extattr = new ArrayList(); + } + + public User(String userid, String name) { + this(userid, name, null, null, null); + } + + /** + * mobile/weixinid/email三者不能同时为空 + * + * @param userid + * @param name + * @param tel + * @param email + * @param weixinid + */ + public User(String userid, String name, String tel, String email, + String weixinid) { + this.userid = userid; + this.name = name; + this.tel = tel; + this.email = email; + this.weixinid = weixinid; + this.extattr = new ArrayList(); + } + + public String getUserid() { + return userid; + } + + public void setUserid(String userid) { + this.userid = userid; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getDepartment() { + return department; + } + + public void setDepartment(List department) { + this.department = department; + } + + public void setDepartment(Integer... department) { + this.department = Arrays.asList(department); + } + + public String getPosition() { + return position; + } + + public void setPosition(String position) { + this.position = position; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public int getGender() { + return gender; + } + + @JSONField(serialize = false) + public Gender getEnumGender() { + if (gender == 0) { + return Gender.male; + } else if (gender == 1) { + return Gender.female; + } else { + return Gender.unknown; + } + } + + public void setGender(int gender) { + this.gender = gender; + } + + public String getTel() { + return tel; + } + + public void setTel(String tel) { + this.tel = tel; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getWeixinid() { + return weixinid; + } + + public void setWeixinid(String weixinid) { + this.weixinid = weixinid; + } + + @JSONField(serialize = false) + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } + + @JSONField(serialize = false) + public UserStatus getStatus() { + for (UserStatus userStatus : UserStatus.values()) { + if (userStatus.getVal() == status) { + return userStatus; + } + } + return null; + } + + public void setStatus(int status) { + this.status = status; + } + + public List getExtattr() { + return extattr; + } + + public void setExtattr(List extattr) { + this.extattr = extattr; + } + + public void setExtattr(NameValue... extattr) { + this.extattr = Arrays.asList(extattr); + } + + public void pushExattr(String name, String value) { + pushExattr(new NameValue(name, value)); + } + + public void pushExattr(NameValue nameValue) { + extattr.add(nameValue); + } + + @Override + public String toString() { + return "User [userid=" + userid + ", name=" + name + ", department=" + + department + ", position=" + position + ", mobile=" + mobile + + ", gender=" + gender + ", tel=" + tel + ", email=" + email + + ", weixinid=" + weixinid + ", avatar=" + avatar + ", status=" + + status + ", extattr=" + extattr + "]"; + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/type/UserStatus.java b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/type/UserStatus.java new file mode 100644 index 00000000..dcbbda4f --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/java/com/foxinmy/weixin4j/qy/type/UserStatus.java @@ -0,0 +1,26 @@ +package com.foxinmy.weixin4j.qy.type; + +/** + * 成员状态 + * + * @className UserStatus + * @author jy + * @date 2014年11月19日 + * @since JDK 1.7 + * @see + */ +public enum UserStatus { + BOTH(0), // 0=全部 + FOLLOW(1), // 1=已关注 + FROZEN(2), // 2=已冻结 + UNFOLLOW(4);// 4=未关注 + private int val; + + UserStatus(int val) { + this.val = val; + } + + public int getVal() { + return val; + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/main/resources/weixin.properties b/weixin4j-qy/weixin4j-qy-api/src/main/resources/weixin.properties new file mode 100644 index 00000000..3987979a --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/main/resources/weixin.properties @@ -0,0 +1,13 @@ +# \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath +# \u4f01\u4e1a\u53f7\u4fe1\u606f +account={"id":"wxd9d9fa581a07cefd","secret":"7tr6FXh2NORvqq1la9CVwxV0xZWGsRSgI6tfqd3-JFc9E2p7UukNNYeKoOTLe0Ru",\ +"token":"gp2eGT5mIpngr",\ +"encodingAesKey":"BRYfV4zPFUJb3v3MySNBg1ERKE3vyyMRoScu76vFySv"\ +} + +# \u4f7f\u7528FileTokenHolder\u65f6token\u7684\u5b58\u653e\u8def\u5f84 +token_path=/tmp/weixin/token +# \u4e8c\u7ef4\u7801\u4fdd\u5b58\u8def\u5f84 +qr_path=/tmp/weixin/qr +# \u5a92\u4f53\u6587\u4ef6\u4fdd\u5b58\u8def\u5f84 +media_path=/tmp/weixin/media \ No newline at end of file diff --git a/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/DepartTest.java b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/DepartTest.java new file mode 100644 index 00000000..8897f050 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/DepartTest.java @@ -0,0 +1,58 @@ +package com.foxinmy.weixin4j.qy.test; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.qy.api.DepartApi; +import com.foxinmy.weixin4j.qy.model.Department; + +/** + * 部门API测试 + * + * @className DepartTest + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see + */ +public class DepartTest extends TokenTest { + public DepartApi departApi; + + @Before + public void init() { + this.departApi = new DepartApi(tokenHolder); + } + + @Test + public void create() throws WeixinException { + Department depart = new Department("苦逼组"); + int id = departApi.createDepart(depart); + Assert.assertTrue(id > 0); + } + + @Test + public void update() throws WeixinException { + Department depart = new Department("苦逼组111"); + depart.setId(2); + JsonResult result = departApi.updateDepart(depart); + Assert.assertEquals("updated", result.getDesc()); + } + + @Test + public void list() throws WeixinException { + List list = departApi.listDepart(); + Assert.assertFalse(list.isEmpty()); + System.out.println(list); + } + + @Test + public void delete() throws WeixinException { + JsonResult result = departApi.deleteDepart(2); + Assert.assertEquals("deleted", result.getDesc()); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TagTest.java b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TagTest.java new file mode 100644 index 00000000..3b7d4804 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TagTest.java @@ -0,0 +1,77 @@ +package com.foxinmy.weixin4j.qy.test; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.alibaba.fastjson.JSONArray; +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.qy.api.TagApi; +import com.foxinmy.weixin4j.qy.model.User; + +/** + * 部门API测试 + * + * @className DepartTest + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see + */ +public class TagTest extends TokenTest { + public TagApi tagApi; + + @Before + public void init() { + this.tagApi = new TagApi(tokenHolder); + } + + @Test + public void create() throws WeixinException { + int tagId = tagApi.createTag("coder"); + Assert.assertTrue(tagId > 0); + } + + @Test + public void update() throws WeixinException { + JsonResult result = tagApi.updateTag(1, "coder456"); + Assert.assertEquals("updated", result.getDesc()); + } + + @Test + public void getUsers() throws WeixinException { + List listUser = tagApi.getTagUsers(1); + Assert.assertFalse(listUser.isEmpty()); + System.out.println(listUser); + } + + @Test + public void addUsers() throws WeixinException { + JsonResult result = tagApi.addTagUsers(1, Arrays.asList("jinyu")); + Assert.assertEquals("ok", result.getDesc()); + } + + @Test + public void deleteUsers() throws WeixinException { + JsonResult result = tagApi.deleteTagUsers(1, Arrays.asList("jinyu")); + Assert.assertEquals("ok", result.getDesc()); + System.out.println(result); + } + + @Test + public void list() throws WeixinException { + JSONArray tags = tagApi.listTag(); + Assert.assertFalse(tags.isEmpty()); + System.out.println(tags); + } + + @Test + public void delete() throws WeixinException { + JsonResult result = tagApi.deleteTag(3); + Assert.assertEquals("deleted", result.getDesc()); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TokenTest.java b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TokenTest.java new file mode 100644 index 00000000..354058d9 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/TokenTest.java @@ -0,0 +1,33 @@ +package com.foxinmy.weixin4j.qy.test; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.token.FileTokenHolder; +import com.foxinmy.weixin4j.token.TokenHolder; +import com.foxinmy.weixin4j.type.AccountType; + +/** + * token测试 + * + * @className TokenTest + * @author jy.hu + * @date 2014年4月10日 + * @since JDK 1.7 + */ +public class TokenTest { + + protected TokenHolder tokenHolder; + + @Before + public void setUp() { + tokenHolder = new FileTokenHolder(AccountType.QY); + } + + @Test + public void test() throws WeixinException { + Assert.assertNotNull(tokenHolder.getToken()); + } +} diff --git a/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java new file mode 100644 index 00000000..8e75fabe --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-api/src/test/java/com/foxinmy/weixin4j/qy/test/UserTest.java @@ -0,0 +1,70 @@ +package com.foxinmy.weixin4j.qy.test; + +import java.util.List; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import com.foxinmy.weixin4j.exception.WeixinException; +import com.foxinmy.weixin4j.http.JsonResult; +import com.foxinmy.weixin4j.qy.api.UserApi; +import com.foxinmy.weixin4j.qy.model.User; + +/** + * 部门API测试 + * + * @className DepartTest + * @author jy + * @date 2014年11月18日 + * @since JDK 1.7 + * @see + */ +public class UserTest extends TokenTest { + public UserApi userApi; + + @Before + public void init() { + this.userApi = new UserApi(tokenHolder); + } + + @Test + public void create() throws WeixinException { + User user = new User("u001", "jack"); + user.setMobile("13500000000"); + user.setDepartment(1); + user.pushExattr("爱好", "code"); + JsonResult result = userApi.createUser(user); + Assert.assertEquals("created", result.getDesc()); + } + + @Test + public void update() throws WeixinException { + User user = new User("u001", "ted"); + user.setMobile("13500000000"); + user.setDepartment(1); + user.pushExattr("爱好", "code"); + JsonResult result = userApi.updateUser(user); + Assert.assertEquals("updated", result.getDesc()); + } + + @Test + public void get() throws WeixinException { + User user = userApi.getUser("u001"); + Assert.assertTrue(user != null); + System.out.println(user); + } + + @Test + public void list() throws WeixinException { + List userList = userApi.listUser(1); + Assert.assertFalse(userList.isEmpty()); + System.out.println(userList); + } + + @Test + public void delete() throws WeixinException { + JsonResult result = userApi.deleteUser("u001"); + Assert.assertEquals("deleted", result.getDesc()); + } +} diff --git a/weixin4j-qy/weixin4j-qy-server/.gitignore b/weixin4j-qy/weixin4j-qy-server/.gitignore new file mode 100644 index 00000000..c880f664 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-server/.gitignore @@ -0,0 +1,28 @@ +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.ear + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +*~ + +# eclipse ignore +*.settings/* +/.project +/.classpath +/.tomcatplugin + +# maven ignore +target/* + +# other ignore +*.log +*.tmp +Thumbs.db +/target/ +.DS_Store diff --git a/weixin4j-qy/weixin4j-qy-server/README.md b/weixin4j-qy/weixin4j-qy-server/README.md new file mode 100644 index 00000000..596d072a --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-server/README.md @@ -0,0 +1,22 @@ +weixin4j-qy-server +================== + +微信企业号netty服务 +------------ + +功能列表 +------- + +* `netty构建服务器` + +* `消息分发` + +如何使用 +-------- + + +更新LOG +------- +* 2014-11-19 + + + 得到`weixin4j-qy-server`工程 \ No newline at end of file diff --git a/weixin4j-qy/weixin4j-qy-server/pom.xml b/weixin4j-qy/weixin4j-qy-server/pom.xml new file mode 100644 index 00000000..59bbe425 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-server/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + com.foxinmy.weixin4j + weixin4j-qy + 0.0.1-SNAPSHOT + + weixin4j-qy-server + weixin4j-qy-server + https://github.com/foxinmy/weixin4j/tree/master/weixin4j-qy/weixin4j-qy-server + 微信企业号工具包 + + weixin-qy-server + + + org.apache.maven.plugins + maven-assembly-plugin + + + + diff --git a/weixin4j-qy/weixin4j-qy-server/src/main/assembly.xml b/weixin4j-qy/weixin4j-qy-server/src/main/assembly.xml new file mode 100644 index 00000000..c128b820 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-server/src/main/assembly.xml @@ -0,0 +1,36 @@ + + bin + + zip + + true + + + true + /lib + + + + + com/foxinmy/weixin4j/qy + + **/*.md + + + + src/main + / + + *.sh + *.bat + + + + src/main/resources + /conf + + + \ No newline at end of file diff --git a/weixin4j-qy/weixin4j-qy-server/src/main/startup.sh b/weixin4j-qy/weixin4j-qy-server/src/main/startup.sh new file mode 100644 index 00000000..d55fbd85 --- /dev/null +++ b/weixin4j-qy/weixin4j-qy-server/src/main/startup.sh @@ -0,0 +1,142 @@ +ulimit -n 110000 +#JDK home +JAVA_HOME="/usr/local/java/" + +#executing user +RUNNING_USER=root + +#Run home +APP_HOME="/usr/local/weixin/weixin-mp-server" + +#main class +APP_MAINCLASS=com.foxinmy.weixin4j.mp.startup.WeixinServerBootstrap + +#classpath +CLASSPATH=$APP_HOME/classes +for i in "$APP_HOME"/lib/*.jar; do + CLASSPATH="$CLASSPATH":"$i" +done + +CLASSPATH="$CLASSPATH":"$APP_HOME"/conf + +#jvm options +JAVA_OPTS="-Xms256m -Xmx512m -Djava.awt.headless=true -XX:MaxPermSize=128m -server -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=85 -XX:+DisableExplicitGC -Xnoclassgc -Xverify:none" + +#psid +psid=0 + +checkpid() { + javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS` + + if [ -n "$javaps" ]; then + psid=`echo $javaps | awk '{print $1}'` + else + psid=0 + fi +} + +################################### +#startup +################################### +start() { + checkpid + + if [ $psid -ne 0 ]; then + echo "=====================================================" + echo "warn: $APP_MAINCLASS already started! (pid=$psid)" + echo "=====================================================" + else + echo -n "Starting $APP_MAINCLASS ..." +# JAVA_CMD="nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >/dev/null 2>&1 &" + JAVA_CMD="$JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS &" + su - $RUNNING_USER -c "$JAVA_CMD" + checkpid + if [ $psid -ne 0 ]; then + echo "(pid=$psid) [OK]" + else + echo "[Failed]" + fi + fi +} + +################################### +#stop +################################### +stop() { + checkpid + + if [ $psid -ne 0 ]; then + echo -n "Stopping $APP_MAINCLASS ...(pid=$psid) " + su - $RUNNING_USER -c "kill -9 $psid" + if [ $? -eq 0 ]; then + echo "[OK]" + else + echo "[Failed]" + fi + + checkpid + if [ $psid -ne 0 ]; then + stop + fi + else + echo "=====================================================" + echo "warn: $APP_MAINCLASS is not running" + echo "=====================================================" + fi +} + +################################### +#status +################################### +status() { + checkpid + + if [ $psid -ne 0 ]; then + echo "$APP_MAINCLASS is running! (pid=$psid)" + else + echo "$APP_MAINCLASS is not running" + fi +} + +################################### +#info +################################### +info() { + echo "System Information:" + echo "****************************" + echo `head -n 1 /etc/issue` + echo `uname -a` + echo + echo "JAVA_HOME=$JAVA_HOME" + echo `$JAVA_HOME/bin/java -version` + echo + echo "APP_HOME=$APP_HOME" + echo "APP_MAINCLASS=$APP_MAINCLASS" + echo "****************************" +} + +################################### +#access only 1 argument:{start|stop|restart|status|info} +################################### +case "$1" in + 'start') + start + ;; + 'stop') + stop + ;; + 'restart') + stop + start + ;; + 'status') + status + ;; + 'info') + info + ;; + *) + echo "Usage: $0 {start|stop|restart|status|info}" + exit 1 +esac +exit 0