diff --git a/CHANGE.md b/CHANGE.md index a70bda70..63efe3bb 100644 --- a/CHANGE.md +++ b/CHANGE.md @@ -381,4 +381,13 @@ + 精简函数上的@link注释 - + 新增媒体文件上传、下载结果类([MediaUploadResult.java](./weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaUploadResult.java),[MediaDownloadResult.java](./weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaDownloadResult.java)) \ No newline at end of file + + 新增媒体文件上传、下载结果类([MediaUploadResult.java](./weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaUploadResult.java),[MediaDownloadResult.java](./weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/MediaDownloadResult.java)) + +* 2015-07-29 + + + 精简WeixinAccount类及其配置文件 + + + **weixin4j-mp**: 新增二维码结果类[QRResult.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java)并将二维码接口[QRApi.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java)名称变更为createQR和createQRFile + + + **weixin4j-mp**: [Oauth授权](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java)跳转的uri在配置文件的属性名改为`oauth_redirect_uri` + \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java index d51122e8..a37d011b 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/Button.java @@ -34,7 +34,7 @@ public class Button implements Serializable { * * @see com.foxinmy.weixin4j.type.ButtonType */ - private String type; + private ButtonType type; /** * 菜单KEY值,根据type的类型而定,用于消息接口推送,不超过128字节. *

@@ -43,7 +43,9 @@ public class Button implements Serializable { *

* 使用API设置的自定义菜单:
* click、scancode_push、scancode_waitmsg、pic_sysphoto、pic_photo_or_album - * 、
pic_weixin、location_select:保存为key;view:保存为url;media_id、view_limited:保存为media_id + * 、
+ * pic_weixin、location_select:保存为key;view:保存为url;media_id、view_limited + * :保存为media_id *

*

*/ @@ -64,13 +66,13 @@ public class Button implements Serializable { * 菜单显示的名称 * @param content * 当buttonType为view时content设置为url,否则为key. - * @param buttonType + * @param type * 按钮类型 */ - public Button(String name, String content, ButtonType buttonType) { + public Button(String name, String content, ButtonType type) { this.name = name; this.content = content; - this.type = buttonType.name(); + this.type = type; } public String getName() { @@ -81,16 +83,11 @@ public class Button implements Serializable { this.name = name; } - public String getType() { + public ButtonType getType() { return type; } - @JSONField(serialize = false, deserialize = false) - public ButtonType getFormatType() { - return ButtonType.valueOf(type); - } - - public void setType(String type) { + public void setType(ButtonType type) { this.type = type; } 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 1d563b08..a625c622 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,6 +2,9 @@ package com.foxinmy.weixin4j.model; import java.io.Serializable; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; + /** * 微信账号信息 * @@ -12,6 +15,7 @@ import java.io.Serializable; * @see */ public class WeixinAccount implements Serializable { + private static final long serialVersionUID = -6001008896414323534L; /** @@ -22,17 +26,10 @@ public class WeixinAccount implements Serializable { * 调用接口的密钥 */ private String secret; - private String token; - /** - * 安全模式下的加密密钥 - */ - private String encodingAesKey; - public WeixinAccount() { - - } - - public WeixinAccount(String id, String secret) { + @JSONCreator + public WeixinAccount(@JSONField(name = "id") String id, + @JSONField(name = "secret") String secret) { this.id = id; this.secret = secret; } @@ -45,33 +42,8 @@ public class WeixinAccount implements Serializable { return secret; } - public void setId(String id) { - this.id = id; - } - - public void setSecret(String secret) { - this.secret = secret; - } - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getEncodingAesKey() { - return encodingAesKey; - } - - public void setEncodingAesKey(String encodingAesKey) { - this.encodingAesKey = encodingAesKey; - } - @Override public String toString() { - return "id=" + id + ", secret=" + secret + ", token=" + token - + ", encodingAesKey=" + encodingAesKey; + return "id=" + id + ", secret=" + secret; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinPayAccount.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinPayAccount.java index 16d48016..1af9ef23 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinPayAccount.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinPayAccount.java @@ -53,42 +53,28 @@ public class WeixinPayAccount extends WeixinAccount { * @param appSecret * 调用接口的凭证 * @param paySignKey - * 支付密钥字符串 + * 支付密钥字符串(必填) * @param mchId - * 微信支付分配的商户号 + * 微信支付分配的商户号(V3版本必填) + * @param partnerId 财付通的商户号(V2版本必填) + * @param partnerKey 财付通商户权限密钥Key(V2版本必填) + * @param subMchId 微信支付分配的子商户号,受理模式下必填(商户平台版) + * @param deviceInfo 微信支付分配的设备号(商户平台版) */ @JSONCreator - public WeixinPayAccount(@JSONField(name = "appId") String appId, - @JSONField(name = "appSecret") String appSecret, - @JSONField(name = "paySignKey") String paySignKey, - @JSONField(name = "mchId") String mchId) { - super(appId, appSecret); - this.paySignKey = paySignKey; - this.mchId = mchId; - } - - /** - * V2版本字段 - * - * @param appId - * 公众号唯一的身份ID - * @param appSecret - * 调用接口的凭证 - * @param paySignKey - * 支付密钥字符串 - * @param partnerId - * 财付通账号的ID - * @param partnerKey - * 财付通账号的key - */ - @JSONCreator - public WeixinPayAccount(@JSONField(name = "appId") String appId, - @JSONField(name = "appSecret") String appSecret, + public WeixinPayAccount(@JSONField(name = "id") String appId, + @JSONField(name = "secret") String appSecret, @JSONField(name = "paySignKey") String paySignKey, + @JSONField(name = "mchId") String mchId, + @JSONField(name = "subMchId") String subMchId, + @JSONField(name = "deviceInfo") String deviceInfo, @JSONField(name = "partnerId") String partnerId, @JSONField(name = "partnerKey") String partnerKey) { super(appId, appSecret); this.paySignKey = paySignKey; + this.mchId = mchId; + this.subMchId = subMchId; + this.deviceInfo = deviceInfo; this.partnerId = partnerId; this.partnerKey = partnerKey; } @@ -126,9 +112,10 @@ public class WeixinPayAccount extends WeixinAccount { @Override public String toString() { - return "WeixinPayAccount [paySignKey=" + paySignKey + ", partnerId=" - + partnerId + ", partnerKey=" + partnerKey + ", mchId=" + mchId - + ", subMchId=" + subMchId + ", deviceInfo=" + deviceInfo - + ", version=" + version + "]"; + return "WeixinPayAccount [" + super.toString() + ", paySignKey=" + + paySignKey + ", partnerId=" + partnerId + ", partnerKey=" + + partnerKey + ", mchId=" + mchId + ", subMchId=" + subMchId + + ", deviceInfo=" + deviceInfo + ", version=" + getVersion() + + "]"; } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java index 2b223d6f..4cfec277 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/tuple/Video.java @@ -67,7 +67,7 @@ public class Video implements NotifyTuple { } /** - * 企业号 + * 企业号 & 公众号群发 * * @param mediaId * @param title diff --git a/weixin4j-mp/CHANGE.md b/weixin4j-mp/CHANGE.md index 621507b2..cd008887 100644 --- a/weixin4j-mp/CHANGE.md +++ b/weixin4j-mp/CHANGE.md @@ -120,4 +120,10 @@ * 2015-07-04 - + released 1.5.1 \ No newline at end of file + + released 1.5.1 + +* 2015-07-29 + + + 新增二维码结果类[QRResult.java](./src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java)并将二维码接口[QRApi.java](./weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java)名称变更为createQR和createQRFile + + + [Oauth授权](./src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java)跳转的uri在配置文件的属性名改为`oauth_redirect_uri` \ No newline at end of file diff --git a/weixin4j-mp/README.md b/weixin4j-mp/README.md index 450490a6..e62daec8 100644 --- a/weixin4j-mp/README.md +++ b/weixin4j-mp/README.md @@ -62,17 +62,14 @@ weixin4j.properties说明 | media_path | 调用媒体接口时保存媒体文件的物理路径 | | bill_path | 调用下载对账单接口保存excel文件的物理路径 | | ca_file | 调用某些接口(支付相关)强制需要auth的ca授权文件 | -| redirect_uri | 调用OauthApi接口时需要填写的重定向路径 | +| oauth_redirect_uri | 调用OauthApi接口时需要填写的重定向路径 | 示例(properties中换行用右斜杆\\) account={"id":"appId","secret":"appSecret",\ - "token":"开放者的token",\ - "encodingAesKey":"公众号设置了加密方式且为「安全模式」时需要填入",\ "mchId":"V3.x版本下的微信商户号",\ "partnerId":"V2版本下的财付通的商户号",\ "partnerKey":"V2版本下的财付通商户权限密钥Key",\ - "version":"针对微信支付的版本号(2,3),如果不填则按照mchId非空与否来判断",\ "paySignKey":"微信支付中调用API的密钥"} token_path=/tmp/weixin4j/token @@ -84,7 +81,7 @@ weixin4j.properties说明 #classpath路径下:ca_file=classpath:xxxxx.p12 #公众号登陆授权的重定向路径(使用OauthApi时需要填写) - redirect_uri=http://xxx + oauth_redirect_uri=http://xxx 2.实例化微信企业号接口实现对象,调用具体的API方法 diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java index 88d6d97c..19df5ef9 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/WeixinProxy.java @@ -36,6 +36,7 @@ import com.foxinmy.weixin4j.mp.model.KfAccount; import com.foxinmy.weixin4j.mp.model.KfSession; import com.foxinmy.weixin4j.mp.model.MenuSetting; import com.foxinmy.weixin4j.mp.model.QRParameter; +import com.foxinmy.weixin4j.mp.model.QRResult; import com.foxinmy.weixin4j.mp.model.SemQuery; import com.foxinmy.weixin4j.mp.model.SemResult; import com.foxinmy.weixin4j.mp.model.User; @@ -641,22 +642,6 @@ public class WeixinProxy { return massApi.uploadVideo(video); } - /** - * 分组群发 - * - * @param tuple - * 消息元件 - * @param groupId - * 分组ID - * @return 群发后的消息ID - * @see {@link #massMessage(MassTuple,boolean,int)} - * @throws WeixinException - */ - public String massByGroupId(MassTuple tuple, int groupId) - throws WeixinException { - return massApi.massByGroupId(tuple, groupId); - } - /** * 群发消息 *

@@ -685,9 +670,9 @@ public class WeixinProxy { * @see 根据分组群发 */ - public String massMessage(MassTuple tuple, boolean isToAll, int groupId) + public String massByGroupId(MassTuple tuple, boolean isToAll, int groupId) throws WeixinException { - return massApi.massMessage(tuple, isToAll, groupId); + return massApi.massByGroupId(tuple, isToAll, groupId); } /** @@ -1072,26 +1057,16 @@ public class WeixinProxy { * * @param parameter * 二维码参数 - * @return byte数据包 + * @return 二维码结果对象 * @throws WeixinException + * @see com.foxinmy.weixin4j.mp.model.QRResult * @see com.foxinmy.weixin4j.mp.model.QRParameter * @see com.foxinmy.weixin4j.mp.api.QrApi * @see 生成二维码 */ - public byte[] getQRData(QRParameter parameter) throws WeixinException { - return qrApi.getQRData(parameter); - } - - /** - * 生成带参数的二维码 - * - * @return 二维码图片解析后的地址 开发者可根据该地址自行生成需要的二维码图片 - * @throws WeixinException - * @see {@link #getQRData(QRParameter)} - */ - public String getQRUrl(QRParameter parameter) throws WeixinException { - return qrApi.getQRUrl(parameter); + public QRResult createQR(QRParameter parameter) throws WeixinException { + return qrApi.createQR(parameter); } /** @@ -1099,10 +1074,10 @@ public class WeixinProxy { * * @return 硬盘存储的文件对象 * @throws WeixinException - * @see {@link #getQRData(QRParameter)} + * @see {@link #createQR(QRParameter)} */ - public File getQRFile(QRParameter parameter) throws WeixinException { - return qrApi.getQRFile(parameter); + public File createQRFile(QRParameter parameter) throws WeixinException { + return qrApi.createQRFile(parameter); } /** diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MassApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MassApi.java index afa5518d..9c1339d0 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MassApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MassApi.java @@ -85,22 +85,6 @@ public class MassApi extends MpApi { /** * 分组群发 - * - * @param tuple - * 消息元件 - * @param groupId - * 分组ID - * @return 群发后的消息ID - * @see {@link com.foxinmy.weixin4j.mp.api.MassApi#massMessage(MassTuple,boolean,int)} - * @throws WeixinException - */ - public String massByGroupId(MassTuple tuple, int groupId) - throws WeixinException { - return massMessage(tuple, false, groupId); - } - - /** - * 群发消息 *

* 在返回成功时,意味着群发任务提交成功,并不意味着此时群发已经结束,所以,仍有可能在后续的发送过程中出现异常情况导致用户未收到消息, * 如消息有时会进行审核、服务器不稳定等,此外,群发任务一般需要较长的时间才能全部发送完毕 @@ -126,7 +110,7 @@ public class MassApi extends MpApi { * @see 根据分组群发 */ - public String massMessage(MassTuple tuple, boolean isToAll, int groupId) + public String massByGroupId(MassTuple tuple, boolean isToAll, int groupId) throws WeixinException { if (tuple instanceof MpNews) { MpNews _news = (MpNews) tuple; @@ -175,7 +159,7 @@ public class MassApi extends MpApi { public String massArticleByGroupId(List articles, int groupId) throws WeixinException { String mediaId = uploadArticle(articles); - return massByGroupId(new MpNews(mediaId), groupId); + return massByGroupId(new MpNews(mediaId), false, groupId); } /** diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MenuApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MenuApi.java index df0d23b7..a9372e75 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MenuApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MenuApi.java @@ -57,15 +57,16 @@ public class MenuApi extends MpApi { public String process(Object object, String name, Object value) { if (object instanceof Button && name.equals("content")) { - ButtonType buttonType = ((Button) object) - .getFormatType(); - if (buttonType == ButtonType.view) { - return "url"; - } else if (buttonType == ButtonType.media_id - || buttonType == ButtonType.view_limited) { - return "media_id"; - } else { - return "key"; + ButtonType buttonType = ((Button) object).getType(); + if (buttonType != null) { + if (ButtonType.view == buttonType) { + return "url"; + } else if (ButtonType.media_id == buttonType + || ButtonType.view_limited == buttonType) { + return "media_id"; + } else { + return "key"; + } } } return name; @@ -117,8 +118,8 @@ public class MenuApi extends MpApi { public JsonResult deleteMenu() throws WeixinException { String menu_delete_uri = getRequestUri("menu_delete_uri"); Token token = tokenHolder.getToken(); - WeixinResponse response = weixinClient.get(String.format(menu_delete_uri, - token.getAccessToken())); + WeixinResponse response = weixinClient.get(String.format( + menu_delete_uri, token.getAccessToken())); return response.getAsJsonResult(); } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java index f018893d..0896bd85 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/OauthApi.java @@ -32,7 +32,7 @@ public class OauthApi extends MpApi { */ public String getAuthorizeURL() { String appId = DEFAULT_WEIXIN_ACCOUNT.getId(); - String redirectUri = ConfigUtil.getValue("redirect_uri"); + String redirectUri = ConfigUtil.getValue("oauth_redirect_uri"); return getAuthorizeURL(appId, redirectUri, "state", "snsapi_login"); } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java index 91e5aab0..6cf4029a 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/QrApi.java @@ -5,11 +5,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; -import com.alibaba.fastjson.JSONObject; +import com.alibaba.fastjson.TypeReference; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.mp.model.QRParameter; +import com.foxinmy.weixin4j.mp.model.QRResult; import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.Weixin4jConst; @@ -37,42 +38,25 @@ public class QrApi extends MpApi { * * @param parameter * 二维码参数 - * @return 二维码图片解析后的地址 开发者可根据该地址自行生成需要的二维码图片 + * @return 二维码结果对象 * @throws WeixinException + * @see com.foxinmy.weixin4j.mp.model.QRResult + * @see com.foxinmy.weixin4j.mp.model.QRParameter * @see 生成二维码 */ - public String getQRUrl(QRParameter parameter) throws WeixinException { - return doQR(parameter).getString("url"); - } - - private JSONObject doQR(QRParameter parameter) throws WeixinException { + public QRResult createQR(QRParameter parameter) throws WeixinException { Token token = tokenHolder.getToken(); String qr_uri = getRequestUri("qr_ticket_uri"); WeixinResponse response = weixinClient.post( String.format(qr_uri, token.getAccessToken()), parameter.getContent()); - return response.getAsJson(); - } - - /** - * 生成带参数的二维码 - * - * @param parameter - * 二维码参数 - * @return byte数据包 - * @throws WeixinException - * @see com.foxinmy.weixin4j.mp.model.QRParameter - * @see 生成二维码 - */ - public byte[] getQRData(QRParameter parameter) throws WeixinException { - String ticket = doQR(parameter).getString("ticket"); - String qr_uri = getRequestUri("qr_image_uri"); - WeixinResponse response = weixinClient.get(String - .format(qr_uri, ticket)); - - return response.getContent(); + QRResult result = response.getAsObject(new TypeReference() { + }); + qr_uri = getRequestUri("qr_image_uri"); + response = weixinClient.get(String.format(qr_uri, result.getTicket())); + result.setContent(response.getContent()); + return result; } /** @@ -87,9 +71,10 @@ public class QrApi extends MpApi { * @throws WeixinException * @see 二维码 + * @see #createQR(QRParameter) * @see com.foxinmy.weixin4j.mp.model.QRParameter */ - public File getQRFile(QRParameter parameter) throws WeixinException { + public File createQRFile(QRParameter parameter) throws WeixinException { String qr_path = ConfigUtil.getValue("qr_path", Weixin4jConst.DEFAULT_QRCODE_PATH); String filename = String.format("%s_%s_%d.jpg", parameter.getQrType() @@ -99,11 +84,11 @@ public class QrApi extends MpApi { if (parameter.getQrType().ordinal() > 0 && file.exists()) { return file; } - byte[] datas = getQRData(parameter); + QRResult qrResult = createQR(parameter); OutputStream os = null; try { os = new FileOutputStream(file); - os.write(datas); + os.write(qrResult.getContent()); } catch (IOException e) { throw new WeixinException(e.getMessage()); } finally { @@ -111,7 +96,7 @@ public class QrApi extends MpApi { if (os != null) { os.close(); } - } catch (IOException ignore) { + } catch (IOException e) { ; } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java new file mode 100644 index 00000000..c0d65d14 --- /dev/null +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/model/QRResult.java @@ -0,0 +1,65 @@ +package com.foxinmy.weixin4j.mp.model; + +import java.io.Serializable; +import java.util.Arrays; + +import com.alibaba.fastjson.annotation.JSONField; + +/** + * 二维码 + * + * @className QRResult + * @author jy + * @date 2015年7月29日 + * @since JDK 1.7 + * @see + */ +public class QRResult implements Serializable { + + private static final long serialVersionUID = 7730781702153258151L; + + private String ticket; + private String url; + @JSONField(name = "expire_seconds") + private int expireSeconds; + private byte[] content; + + public String getTicket() { + return ticket; + } + + public void setTicket(String ticket) { + this.ticket = ticket; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public int getExpireSeconds() { + return expireSeconds; + } + + public void setExpireSeconds(int expireSeconds) { + this.expireSeconds = expireSeconds; + } + + public byte[] getContent() { + return content; + } + + public void setContent(byte[] content) { + this.content = content; + } + + @Override + public String toString() { + return "QRResult [ticket=" + ticket + ", url=" + url + + ", expireSeconds=" + expireSeconds + ", content=" + + Arrays.toString(content) + "]"; + } +} diff --git a/weixin4j-mp/src/main/resources/weixin4j.properties b/weixin4j-mp/src/main/resources/weixin4j.properties index f05c1af4..798fb2b3 100644 --- a/weixin4j-mp/src/main/resources/weixin4j.properties +++ b/weixin4j-mp/src/main/resources/weixin4j.properties @@ -1,10 +1,7 @@ # \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath # \u516c\u4f17\u53f7\u4fe1\u606f account={"id":"wx4ab8f8de58159a57","secret":"1d4eb0f4bf556aaed539f30ed05ca795",\ -"token":"\u5f00\u653e\u8005\u7684token",\ -"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 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\ -"version":2,\ "partnerId":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\ "partnerKey":"V2\u7248\u672c\u4e0b\u7684\u8d22\u4ed8\u901a\u5546\u6237\u6743\u9650\u5bc6\u94a5Key \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165",\ "paySignKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5 \u670d\u52a1\u53f7\u652f\u4ed8\u65f6\u9700\u8981\u586b\u5165"} @@ -23,4 +20,4 @@ ca_file=/tmp/weixin4j/xxxxx.p12 # ca_file=classpath:xxxxx.pfx # oauth\u6388\u6743\u540e\u91cd\u5b9a\u5411\u7684url -redirect_uri= \ No newline at end of file +oauth_redirect_uri= \ No newline at end of file diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CouponTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CouponTest.java index b8af7326..5023c00c 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CouponTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/CouponTest.java @@ -30,7 +30,8 @@ public class CouponTest { protected final static WeixinPayProxy WEIXINPAY; protected final static WeixinPayAccount ACCOUNT; static { - ACCOUNT = new WeixinPayAccount("appid", "appsecret", "paysign", "mchid"); + ACCOUNT = new WeixinPayAccount("appid", "appsecret", "paysign", + "mchid", null, null, null, null); WEIXINPAY = new WeixinPayProxy(ACCOUNT); } protected final File caFile = new File("证书文件路径(*.p12)"); diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java index bb56bbb0..f2c3e232 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/MassTest.java @@ -58,7 +58,7 @@ public class MassTest extends TokenTest { @Test public void massByGroupId() throws WeixinException { - String msgId = massApi.massByGroupId(new Image("mediaId"), 0); + String msgId = massApi.massByGroupId(new Image("mediaId"), true, 0); Assert.assertTrue(msgId != null); } diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java index f7fdc838..53ebf11a 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/PayTest.java @@ -33,11 +33,12 @@ public class PayTest { private final static WeixinPayAccount ACCOUNT3; static { ACCOUNT2 = new WeixinPayAccount("请填入v2版本的appid", "请填入v2版本的appSecret", - "请填入v3版本的paysignkey", "请填入v2版本的partnerId", "请填入v2版本的partnerKey"); + "请填入v2版本的paysignkey", null, null, null, "请填入v2版本的partnerId", + "请填入v2版本的partnerKey"); PAY2 = new Pay2Api(ACCOUNT2, new FileTokenStorager(ConfigUtil.getValue( "token_path", "/tmp/weixin4j/token"))); ACCOUNT3 = new WeixinPayAccount("请填入v3版本的appid", "请填入v3版本的appSecret", - "请填入v3版本的paysignkey", "请填入v3版本的mchid"); + "请填入v3版本的paysignkey", "请填入v3版本的mchid", null, null, null, null); PAY3 = new WeixinPayProxy(ACCOUNT3); } diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/QRTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/QRTest.java index 632493b4..27f429fc 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/QRTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/QRTest.java @@ -29,19 +29,19 @@ public class QRTest extends TokenTest { @Test public void temp_qr() throws WeixinException, IOException { - File file = qrApi.getQRFile(QRParameter.createTemporary(1200, 1200)); + File file = qrApi.createQRFile(QRParameter.createTemporary(1200, 1200)); Assert.assertTrue(file.exists()); } @Test public void forever_qr_int() throws WeixinException, IOException { - File file = qrApi.getQRFile(QRParameter.createPermanenceInt(1200)); + File file = qrApi.createQRFile(QRParameter.createPermanenceInt(1200)); Assert.assertTrue(file.exists()); } @Test public void forever_qr_str() throws WeixinException, IOException { - File file = qrApi.getQRFile(QRParameter.createPermanenceStr("1200中文")); + File file = qrApi.createQRFile(QRParameter.createPermanenceStr("1200中文")); Assert.assertTrue(file.exists()); } } diff --git a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java index b3e5690b..1aa3a89e 100644 --- a/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java +++ b/weixin4j-mp/src/test/java/com/foxinmy/weixin4j/mp/test/XmlstreamTest.java @@ -2,9 +2,15 @@ package com.foxinmy.weixin4j.mp.test; import java.io.BufferedReader; import java.io.FileReader; +import java.net.URL; import java.util.HashMap; import java.util.Map; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; + import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.mp.payment.v2.RefundRecordV2; import com.foxinmy.weixin4j.payment.mch.Order; @@ -99,6 +105,26 @@ public class XmlstreamTest { com.foxinmy.weixin4j.payment.mch.RefundRecord.class)); } + public static String errorXml() { + StringBuffer xml = new StringBuffer(); + String url = "http://qydev.weixin.qq.com/wiki/index.php?title=%E5%85%A8%E5%B1%80%E8%BF%94%E5%9B%9E%E7%A0%81%E8%AF%B4%E6%98%8E"; + try { + Document doc = Jsoup.parse(new URL(url), 5000); + Elements eles = doc.getElementsByTag("tr"); + for (Element ele : eles) { + xml.append(""); + xml.append("").append(ele.child(0).text()) + .append(""); + xml.append("").append(ele.child(1).text()) + .append(""); + xml.append(""); + } + } catch (Exception e) { + e.printStackTrace(); + } + return xml.toString(); + } + public static void main(String[] args) throws Exception { // map2xml(); // xml2map(); @@ -106,13 +132,15 @@ public class XmlstreamTest { // System.err.println(xml2refundRecordV2()); // xml2refundRecordV3(); // object2xmlWithoutRootElement(); - /*RefundRecord refundRecord = xml2refundRecordV2(); - System.err.println(refundRecord); - String sign = refundRecord.getSign(); - refundRecord.setSign(null); - String validSign = PayUtil.paysignMd5(refundRecord, "paysignkey"); - System.err.println("sign=" + sign + ",validSign=" + validSign); - System.err.println(ListsuffixResultSerializer - .serializeToXML(refundRecord));*/ + /* + * RefundRecord refundRecord = xml2refundRecordV2(); + * System.err.println(refundRecord); String sign = + * refundRecord.getSign(); refundRecord.setSign(null); String validSign + * = PayUtil.paysignMd5(refundRecord, "paysignkey"); + * System.err.println("sign=" + sign + ",validSign=" + validSign); + * System.err.println(ListsuffixResultSerializer + * .serializeToXML(refundRecord)); + */ + // System.out.println(errorXml()); } } diff --git a/weixin4j-qy/README.md b/weixin4j-qy/README.md index 29c28422..e5d07267 100644 --- a/weixin4j-qy/README.md +++ b/weixin4j-qy/README.md @@ -59,8 +59,8 @@ weixin4j.properties说明 account={"id":"corpid","secret":"corpsecret",\ "token":"企业号中应用在回调模式下的token",\ - "encodingAesKey":"企业号中应用在回调模式下AES加密密钥",\ - "providerSecret:"提供商的secret"} + "providerSecret:"第三方提供商secret(企业号登陆)",\ + "chatSecret":"消息服务secret(企业号聊天)"} token_path=/tmp/weixin4j/token media_path=/tmp/weixin4j/media diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MenuApi.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MenuApi.java index 4e8cfd38..b806c9f4 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MenuApi.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/api/MenuApi.java @@ -60,15 +60,16 @@ public class MenuApi extends QyApi { public String process(Object object, String name, Object value) { if (object instanceof Button && name.equals("content")) { - ButtonType buttonType = ((Button) object) - .getFormatType(); - if (buttonType == ButtonType.view) { - return "url"; - } else if (buttonType == ButtonType.media_id - || buttonType == ButtonType.view_limited) { - return "media_id"; - } else { - return "key"; + ButtonType buttonType = ((Button) object).getType(); + if (buttonType != null) { + if (ButtonType.view == buttonType) { + return "url"; + } else if (ButtonType.media_id == buttonType + || ButtonType.view_limited == buttonType) { + return "media_id"; + } else { + return "key"; + } } } return name; @@ -124,8 +125,8 @@ public class MenuApi extends QyApi { public JsonResult deleteMenu(int agentid) throws WeixinException { String menu_delete_uri = getRequestUri("menu_delete_uri"); Token token = tokenHolder.getToken(); - WeixinResponse response = weixinClient.get(String.format(menu_delete_uri, - token.getAccessToken(), agentid)); + WeixinResponse response = weixinClient.get(String.format( + menu_delete_uri, token.getAccessToken(), agentid)); return response.getAsJsonResult(); } diff --git a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/WeixinQyAccount.java b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/WeixinQyAccount.java index 420a378b..4db43912 100644 --- a/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/WeixinQyAccount.java +++ b/weixin4j-qy/src/main/java/com/foxinmy/weixin4j/qy/model/WeixinQyAccount.java @@ -1,5 +1,7 @@ package com.foxinmy.weixin4j.qy.model; +import com.alibaba.fastjson.annotation.JSONCreator; +import com.alibaba.fastjson.annotation.JSONField; import com.foxinmy.weixin4j.model.WeixinAccount; /** @@ -14,22 +16,36 @@ import com.foxinmy.weixin4j.model.WeixinAccount; * >企业号设置 */ public class WeixinQyAccount extends WeixinAccount { - + private static final long serialVersionUID = 3689999353867189585L; - public WeixinQyAccount(){ - - } - /** * * @param corpid * 企业ID * @param corpsecret * 管理组的凭证密钥 + * @param suiteId + * 应用套件的id + * @param suiteSecret + * 应用套件的secret + * @param providerSecret + * 第三方提供商secret(企业号登陆) + * @param chatSecret + * 消息服务secret(企业号聊天) */ - public WeixinQyAccount(String corpid, String corpsecret) { + @JSONCreator + public WeixinQyAccount(@JSONField(name = "id") String corpid, + @JSONField(name = "secret") String corpsecret, + @JSONField(name = "suiteId") String suiteId, + @JSONField(name = "suiteSecret") String suiteSecret, + @JSONField(name = "providerSecret") String providerSecret, + @JSONField(name = "chatSecret") String chatSecret) { super(corpid, corpsecret); + this.suiteId = suiteId; + this.suiteSecret = suiteSecret; + this.providerSecret = providerSecret; + this.chatSecret = chatSecret; } /** @@ -41,65 +57,34 @@ public class WeixinQyAccount extends WeixinAccount { */ private String suiteSecret; /** - * 应用套件token,用于生成签名,校验回调请求的合法性。后续所有托管的企业产生的回调消息都使用该值来解密。 - */ - private String suiteToken; - /** - * 应用套件encodingAesKey,回调消息加解密参数,是AES密钥的Base64编码,用于解密回调消息内容对应的密文。 - * 后续所有托管的企业产生的回调消息都使用该值来解密。 - */ - private String suiteEncodingAesKey; - - /** - * 提供商的secret + * 第三方提供商secret(企业号登陆) */ private String providerSecret; + /** + * 消息服务secret(企业号聊天) + */ + private String chatSecret; public String getSuiteId() { return suiteId; } - public void setSuiteId(String suiteId) { - this.suiteId = suiteId; - } - public String getSuiteSecret() { return suiteSecret; } - public void setSuiteSecret(String suiteSecret) { - this.suiteSecret = suiteSecret; - } - - public String getSuiteToken() { - return suiteToken; - } - - public void setSuiteToken(String suiteToken) { - this.suiteToken = suiteToken; - } - - public String getSuiteEncodingAesKey() { - return suiteEncodingAesKey; - } - - public void setSuiteEncodingAesKey(String suiteEncodingAesKey) { - this.suiteEncodingAesKey = suiteEncodingAesKey; - } - public String getProviderSecret() { return providerSecret; } - public void setProviderSecret(String providerSecret) { - this.providerSecret = providerSecret; + public String getChatSecret() { + return chatSecret; } @Override public String toString() { return "WeixinQyAccount [" + super.toString() + ", suiteId=" + suiteId - + ", suiteSecret=" + suiteSecret + ", suiteToken=" + suiteToken - + ", suiteEncodingAesKey=" + suiteEncodingAesKey - + ", providerSecret=" + providerSecret + "]"; + + ", suiteSecret=" + suiteSecret + ", providerSecret=" + + providerSecret + ", chatSecret=" + chatSecret + "]"; } } diff --git a/weixin4j-qy/src/main/resources/weixin4j.properties b/weixin4j-qy/src/main/resources/weixin4j.properties index 023e1e34..61224f5c 100644 --- a/weixin4j-qy/src/main/resources/weixin4j.properties +++ b/weixin4j-qy/src/main/resources/weixin4j.properties @@ -1,12 +1,9 @@ # \u6d4b\u8bd5\u4e4b\u7528 \u6b63\u5f0f\u73af\u5883\u4e0bcopy\u4e00\u4efd\u5230classpath # \u4f01\u4e1a\u53f7\u4fe1\u606f account={"id":"wx6d13cc18002bb2e5","secret":"vcCOTIb-cOzWWhL5r_qKVlfzdpInEEKPRz3K-5ezn-Xt48-tOkxPqEE5XbKLXXFn",\ -"token":"gp2eGT5mIpngr",\ -"encodingAesKey":"BRYfV4zPFUJb3v3MySNBg1ERKE3vyyMRoScu76vFySv",\ "suiteId":"\u5e94\u7528\u5957\u4ef6\u7684id","suiteSecret":"\u5e94\u7528\u5957\u4ef6\u7684secret",\ -"suiteToken":"\u5e94\u7528\u5957\u4ef6\u7684token",\ -"suiteEncodingAesKey":"\u5e94\u7528\u5957\u4ef6\u7684encodingAesKey",\ -"providerSecret":"\u63d0\u4f9b\u5546\u7684secret"} +"providerSecret":"\u7b2c\u4e09\u65b9\u63d0\u4f9b\u5546secret(\u4f01\u4e1a\u53f7\u767b\u9646)",\ +"chatSecret":"\u6d88\u606f\u670d\u52a1secret(\u4f01\u4e1a\u53f7\u804a\u5929)"} # \u4f7f\u7528FileTokenStorager\u65f6token\u7684\u5b58\u653e\u8def\u5f84 token_path=/tmp/weixin4j/token