diff --git a/README.md b/README.md index 203ed8ed..c9308858 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,13 @@ weixin4j 1).weixin4j-mp:调整ActionMapping抽象化 +* 2014-10-31 + + 1).weixin4j-mp:weixin.properties切分为API调用地址/公众号信息两部分 + + 2).weixin4j-base:TokenApi重命名为TokenHolder + + 3).weixin4j-base:新增WeixinConfig等类 接下来 ------ diff --git a/weixin4j-base/README.md b/weixin4j-base/README.md index f0e6446f..534da030 100644 --- a/weixin4j-base/README.md +++ b/weixin4j-base/README.md @@ -1,4 +1,12 @@ weixin4j-base ============= -tencent weixin base java sdk 微信开发基础工程 \ No newline at end of file +tencent weixin base java sdk 微信开发基础工程 + +更新LOG +------- +* 2014-10-31 + + 1).TokenApi重命名为TokenHolder + + 2).新增WeixinConfig等类 \ No newline at end of file diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/PayException.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/PayException.java index 1d928d1d..bfd492a1 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/PayException.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/PayException.java @@ -1,5 +1,13 @@ package com.foxinmy.weixin4j.exception; +/** + * 调用微信支付抛出的异常 + * @className PayException + * @author jy + * @date 2014年10月28日 + * @since JDK 1.7 + * @see + */ public class PayException extends Exception { private static final long serialVersionUID = 7148145661883468514L; diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java index 2933f61a..e27673eb 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/exception/WeixinException.java @@ -13,14 +13,10 @@ public class WeixinException extends Exception { private static final long serialVersionUID = 7148145661883468514L; - private int errorCode; + private String errorCode; private String errorMsg; - public WeixinException(int errorCode) { - this.errorCode = errorCode; - } - - public WeixinException(int errorCode, String errorMsg) { + public WeixinException(String errorCode, String errorMsg) { this.errorCode = errorCode; this.errorMsg = errorMsg; } @@ -29,7 +25,7 @@ public class WeixinException extends Exception { this.errorMsg = errorMsg; } - public int getErrorCode() { + public String getErrorCode() { return errorCode; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/BaseResult.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/BaseResult.java index c19b7e46..b3031f9d 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/BaseResult.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/BaseResult.java @@ -2,6 +2,8 @@ package com.foxinmy.weixin4j.http; import java.io.Serializable; +import com.thoughtworks.xstream.annotations.XStreamAlias; + /** * 调用接口响应值 * @@ -12,12 +14,15 @@ import java.io.Serializable; * @see 全局返回码 */ +@XStreamAlias("xml") public class BaseResult implements Serializable { private static final long serialVersionUID = -6185313616955051150L; - private int errcode; - private String errmsg; + @XStreamAlias("return_code") + private String errcode = "0"; + @XStreamAlias("return_msg") + private String errmsg = ""; private String msgid; private String text; @@ -25,13 +30,11 @@ public class BaseResult implements Serializable { } - public BaseResult(int errcode, String errmsg, String text) { - this.errcode = errcode; - this.errmsg = errmsg; - this.text = text; + public BaseResult(String errcode, String errmsg, String text) { + this(errcode, errmsg, null, text); } - public BaseResult(int errcode, String errmsg, String msgid, String text) { + public BaseResult(String errcode, String errmsg, String msgid, String text) { this.errcode = errcode; this.errmsg = errmsg; this.msgid = msgid; @@ -46,11 +49,11 @@ public class BaseResult implements Serializable { this.text = text; } - public int getErrcode() { + public String getErrcode() { return errcode; } - public void setErrcode(int errcode) { + public void setErrcode(String errcode) { this.errcode = errcode; } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java index c8076612..180b2540 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/HttpRequest.java @@ -3,10 +3,10 @@ package com.foxinmy.weixin4j.http; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.apache.http.Consts; import org.apache.http.Header; import org.apache.http.HttpEntity; @@ -33,6 +33,7 @@ import org.apache.http.params.CoreConnectionPNames; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; +import com.alibaba.fastjson.JSONException; import com.foxinmy.weixin4j.exception.WeixinException; /** @@ -155,12 +156,12 @@ public class HttpRequest { int status = statusLine.getStatusCode(); if (status != HttpStatus.SC_OK) { - throw new WeixinException(status, "request fail"); + throw new WeixinException(status + "", "request fail"); } // 301或者302 if (status == HttpStatus.SC_MOVED_PERMANENTLY || status == HttpStatus.SC_MOVED_TEMPORARILY) { - throw new WeixinException(status, String.format( + throw new WeixinException(status + "", String.format( "the page was redirected to %s", httpResponse.getFirstHeader("location"))); } @@ -170,7 +171,7 @@ public class HttpRequest { response.setStatusCode(status); response.setStatusText(statusLine.getReasonPhrase()); response.setStream(new ByteArrayInputStream(data)); - response.setText(StringUtils.join(data)); + response.setText(new String(data, StandardCharsets.UTF_8)); Header contentType = httpResponse .getFirstHeader(HttpHeaders.CONTENT_TYPE); @@ -178,18 +179,25 @@ public class HttpRequest { ContentType.APPLICATION_JSON.getMimeType()) || contentType.getValue().contains( ContentType.TEXT_PLAIN.getMimeType())) { - BaseResult result = response.getAsResult(); - if (result.getErrcode() != 0) { - throw new WeixinException(result.getErrcode(), - result.getErrmsg()); + BaseResult result = null; + try { + result = response.getAsResult(); + } catch (JSONException e) { + result = response.getAsXml(BaseResult.class); } + if (result.getErrcode().equals("0") + || result.getErrcode().equalsIgnoreCase("success")) { + EntityUtils.consume(httpEntity); + return response; + } + throw new WeixinException(result.getErrcode(), + result.getErrmsg()); } - EntityUtils.consume(httpEntity); - return response; } catch (IOException e) { throw new WeixinException(e.getMessage()); } finally { request.releaseConnection(); } + throw new WeixinException("-1", "request fail"); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/Response.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/Response.java index 5d066380..228e64af 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/Response.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/Response.java @@ -1,7 +1,6 @@ package com.foxinmy.weixin4j.http; import java.io.InputStream; -import java.io.Serializable; import org.dom4j.Document; import org.dom4j.DocumentException; @@ -10,7 +9,7 @@ import org.dom4j.io.SAXReader; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; -import com.thoughtworks.xstream.XStream; +import com.foxinmy.weixin4j.xml.XStream; public class Response { @@ -39,15 +38,14 @@ public class Response { return JSON.parseObject(text); } - @SuppressWarnings("unchecked") - public T getAsObject(Class clazz) { + public T getAsObject(Class clazz) { return (T) JSON.parseObject(text, clazz); } - public Object getAsXml() { - XStream xs = new XStream(); - xs.autodetectAnnotations(true); - return xs.fromXML(text); + public T getAsXml(Class clazz) { + XStream xStream = XStream.get(); + xStream.processAnnotations(clazz); + return xStream.fromXML(text, clazz); } /** @@ -60,12 +58,11 @@ public class Response { */ public BaseResult getBaseError() throws DocumentException { BaseResult result = getAsResult(); - if (result.getErrcode() != 0) { + if (!result.getErrcode().equals("0")) { SAXReader reader = new SAXReader(); - Document doc = reader.read(Thread.currentThread() - .getContextClassLoader().getResourceAsStream("error.xml")); + Document doc = reader.read(Response.class.getResourceAsStream("error.xml")); Node node = doc.getRootElement().selectSingleNode( - String.format("error[@code='%d']", result.getErrcode())); + String.format("error[@code='%s']", result.getErrcode())); if (node != null) { result.setText(node.getStringValue()); } diff --git a/weixin4j-mp/src/main/resources/error.xml b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml similarity index 85% rename from weixin4j-mp/src/main/resources/error.xml rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml index ff8ed8bd..c38e2f10 100644 --- a/weixin4j-mp/src/main/resources/error.xml +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/http/error.xml @@ -82,4 +82,16 @@ 解析JSON/XML内容错误 api功能未授权 用户未授权该api + 接口后台错误 + 无效 transaction_id + 提交参数错误 + 订单已支付 + 商户订单号重复 + 商户无权限 + 余额不足 + 不支持卡类型 + 订单已关闭 + 银行系统异常 + 退款金额大于支付金额 + 订单不存在 \ No newline at end of file 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 new file mode 100644 index 00000000..6f7d2057 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccount.java @@ -0,0 +1,84 @@ +package com.foxinmy.weixin4j.model; + +/** + * 微信账户信息 + * + * @className WeixinAccountV2 + * @author jy + * @date 2014年8月17日 + * @since JDK 1.7 + * @see + */ +public class WeixinAccount extends WeixinAccountV2 { + private static final long serialVersionUID = 3689999353867189585L; + // 是否已经认证 + private boolean isAlive; + // 是否是服务号 + private boolean isService; + // 是否是订阅号 + private boolean isSubscribe = true; + // 微信支付商户号 + private String mchId; + + 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 String getMchId() { + return mchId; + } + public void setMchId(String mchId) { + this.mchId = mchId; + } + public void setIsSubscribe(Boolean isSubscribe) { + this.isSubscribe = isSubscribe; + } + + public WeixinAccount() { + } + + public WeixinAccount(boolean isAlive, boolean isService, + boolean isSubscribe, String token, String openId) { + super.setToken(token); + super.setOpenId(openId); + this.isAlive = isAlive; + this.isService = isService; + this.isSubscribe = isSubscribe; + } + + public WeixinAccount(boolean isAlive, boolean isService, + boolean isSubscribe, String token, String openId, String appId, + String appSecret) { + super.setToken(token); + super.setOpenId(openId); + super.setAppId(appId); + super.setAppSecret(appSecret); + this.isAlive = isAlive; + this.isService = isService; + this.isSubscribe = isSubscribe; + } + + @Override + public String toString() { + return "WeixinAccount [isAlive=" + isAlive + ", isService=" + isService + + ", isSubscribe=" + isSubscribe + ", mchId=" + mchId + + ", getIsAlive()=" + getIsAlive() + ", getIsService()=" + + getIsService() + ", getIsSubscribe()=" + getIsSubscribe() + + ", getMchId()=" + getMchId() + "]"; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccountV2.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccountV2.java new file mode 100644 index 00000000..fa434a39 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccountV2.java @@ -0,0 +1,56 @@ +package com.foxinmy.weixin4j.model; + +/** + * 微信支付V2.7 + * + * @className WeixinAccountV2 + * @author jy + * @date 2014年8月17日 + * @since JDK 1.7 + * @see + */ +public class WeixinAccountV2 extends WeixinConfig { + private static final long serialVersionUID = 3689999353867189585L; + // 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值 + private String paySignKey; + // 财付通商户身份的标识 + private String partnerId; + // 财付通商户权限密钥Key + private String partnerKey; + + 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 WeixinAccountV2() { + } + public WeixinAccountV2(String openId, String appId, String appSecret, + String paySignKey, String partnerId, String partnerKey) { + super(null, openId, appId, appSecret); + this.paySignKey = paySignKey; + this.partnerId = partnerId; + this.partnerKey = partnerKey; + } + @Override + public String toString() { + return "WeixinAccountV2 [paySignKey=" + paySignKey + ", partnerId=" + + partnerId + ", partnerKey=" + partnerKey + + ", getPaySignKey()=" + getPaySignKey() + ", getPartnerId()=" + + getPartnerId() + ", getPartnerKey()=" + getPartnerKey() + "]"; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccountV3.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccountV3.java new file mode 100644 index 00000000..ff08b783 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinAccountV3.java @@ -0,0 +1,46 @@ +package com.foxinmy.weixin4j.model; + +/** + * 微信支付V3.3.6 + * + * @className WeixinConfig + * @author jy + * @date 2014年8月17日 + * @since JDK 1.7 + * @see + */ +public class WeixinAccountV3 extends WeixinConfig { + private static final long serialVersionUID = 3689999353867189585L; + // 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值 + private String paySignKey; + // 微信支付商户号 + private String mchId; + + public String getPaySignKey() { + return paySignKey; + } + public void setPaySignKey(String paySignKey) { + this.paySignKey = paySignKey; + } + public String getMchId() { + return mchId; + } + public void setMchId(String mchId) { + this.mchId = mchId; + } + public WeixinAccountV3() { + } + + public WeixinAccountV3(String appId, String appSecret, String paySignKey, + String mchId, String openId) { + super(null, openId, appId, appSecret); + this.mchId = mchId; + this.paySignKey = paySignKey; + } + @Override + public String toString() { + return "WeixinAccountV3 [paySignKey=" + paySignKey + ", mchId=" + mchId + + ", getPaySignKey()=" + getPaySignKey() + ", getMchId()=" + + getMchId() + "]"; + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinConfig.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinConfig.java new file mode 100644 index 00000000..9aee9c61 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/model/WeixinConfig.java @@ -0,0 +1,56 @@ +package com.foxinmy.weixin4j.model; + +import java.io.Serializable; + +public class WeixinConfig implements Serializable { + + private static final long serialVersionUID = -3454743453282851243L; + + private String token; + // 支付场景下为用户的openid 其余情况可能是公众号的原始ID + private String openId; + // 公众号身份的唯一标识 + private String appId; + // 除了支付请求需要用到 paySignKey,公众平台接口 API 的权限获取所需密 钥 Key + private String appSecret; + public String getToken() { + return token; + } + public void setToken(String token) { + 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 WeixinConfig() { + + } + public WeixinConfig(String token, String openId, String appId, + String appSecret) { + this.token = token; + this.openId = openId; + this.appId = appId; + this.appSecret = appSecret; + } + @Override + public String toString() { + return "WeixinConfig [token=" + token + ", openId=" + openId + + ", appId=" + appId + ", appSecret=" + appSecret + "]"; + } + +} 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 7016b775..0df83ba2 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 @@ -26,7 +26,7 @@ import com.thoughtworks.xstream.io.json.JsonWriter; public class BaseMessage implements Serializable { private static final long serialVersionUID = 7761192742840031607L; - private final static XStream xmlStream = new XStream(); + private final static XStream xmlStream = XStream.get(); private final static XStream jsonStream = new XStream( new JsonHierarchicalStreamDriver() { public HierarchicalStreamWriter createWriter(Writer writer) { @@ -49,8 +49,6 @@ public class BaseMessage implements Serializable { Class[] classes = ClassUtil.getClasses( TextMessage.class.getPackage()).toArray(new Class[0]); - xmlStream.ignoreUnknownElements(); - xmlStream.autodetectAnnotations(true); xmlStream.processAnnotations(classes); xmlStream.omitField(BaseMessage.class, "msgId"); @@ -123,20 +121,16 @@ public class BaseMessage implements Serializable { return false; } - protected XStream getXStream() { - Class targetClass = getMsgType() - .getMessageClass(); - xmlStream.alias("xml", targetClass); - return xmlStream; - } - /** * 消息对象转换为微信服务器接受的xml格式消息 * * @return xml字符串 */ public String toXml() { - return getXStream().toXML(this); + Class targetClass = getMsgType() + .getMessageClass(); + xmlStream.alias("xml", targetClass); + return xmlStream.toXML(this); } /** diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenApi.java deleted file mode 100644 index d8f13d65..00000000 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenApi.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.foxinmy.weixin4j.token; - -import com.foxinmy.weixin4j.util.ConfigUtil; - -/** - * 获取config.properties中的appid&appsecret信息 - * - * @className AbstractTokenApi - * @author jy - * @date 2014年10月6日 - * @since JDK 1.7 - * @see - */ -public abstract class AbstractTokenApi implements TokenApi { - - protected String getAppid() { - return ConfigUtil.getValue("app_id"); - } - - protected String getAppsecret() { - return ConfigUtil.getValue("app_secret"); - } -} 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 new file mode 100644 index 00000000..e8124706 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/AbstractTokenHolder.java @@ -0,0 +1,34 @@ +package com.foxinmy.weixin4j.token; + +import com.alibaba.fastjson.JSON; +import com.foxinmy.weixin4j.http.HttpRequest; +import com.foxinmy.weixin4j.model.WeixinConfig; +import com.foxinmy.weixin4j.util.ConfigUtil; + +/** + * 获取config.properties中的appid&appsecret信息 + * + * @className AbstractTokenApi + * @author jy + * @date 2014年10月6日 + * @since JDK 1.7 + * @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 WeixinConfig weixinConfig; + + public AbstractTokenHolder() { + weixinConfig = JSON.parseObject(ConfigUtil.getValue("account"), + WeixinConfig.class); + } + + protected String getAppid() { + return weixinConfig.getAppId(); + } + + protected String getAppsecret() { + return weixinConfig.getAppSecret(); + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java similarity index 78% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenApi.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java index c9fe2f5f..76fdbeb2 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/FileTokenHolder.java @@ -8,7 +8,6 @@ import java.util.Calendar; import org.apache.commons.lang3.StringUtils; import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.util.ConfigUtil; @@ -17,7 +16,7 @@ import com.foxinmy.weixin4j.xml.XStream; /** * 基于文件保存的Token获取类 * - * @className FileTokenApi + * @className FileTokenHolder * @author jy.hu * @date 2014年9月27日 * @since JDK 1.7 @@ -25,19 +24,17 @@ import com.foxinmy.weixin4j.xml.XStream; * href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">获取token说明 * @see com.foxinmy.weixin4j.model.Token */ -public class FileTokenApi extends AbstractTokenApi { - - private final HttpRequest request = new HttpRequest(); +public class FileTokenHolder extends AbstractTokenHolder { private final String appid; private final String appsecret; - public FileTokenApi() { + public FileTokenHolder() { this.appid = getAppid(); this.appsecret = getAppsecret(); } - public FileTokenApi(String appid, String appsecret) { + public FileTokenHolder(String appid, String appsecret) { this.appid = appid; this.appsecret = appsecret; } @@ -60,8 +57,7 @@ public class FileTokenApi extends AbstractTokenApi { throw new IllegalArgumentException( "appid or appsecret not be null!"); } - XStream xstream = new XStream(); - xstream.autodetectAnnotations(true); + XStream xstream = XStream.get(); xstream.processAnnotations(Token.class); File token_file = new File(String.format("%s/token_%s.xml", ConfigUtil.getValue("token_path"), appid)); @@ -69,9 +65,6 @@ public class FileTokenApi extends AbstractTokenApi { Calendar ca = Calendar.getInstance(); long now_time = ca.getTimeInMillis(); try { - String api_token_uri = String.format( - ConfigUtil.getValue("api_token_uri"), appid, appsecret); - Response response = null; if (token_file.exists()) { token = (Token) xstream.fromXML(token_file); @@ -80,22 +73,24 @@ public class FileTokenApi extends AbstractTokenApi { if (expise_time > now_time) { return token; } - response = request.get(api_token_uri); } else { - response = request.get(api_token_uri); try { token_file.createNewFile(); } catch (IOException e) { token_file.getParentFile().mkdirs(); } } + String api_token_uri = String.format( + tokenUrl, appid, appsecret); + Response response = request.get(api_token_uri); token = response.getAsObject(Token.class); token.setTime(now_time); token.setOpenid(appid); xstream.toXML(token, new FileOutputStream(token_file)); + return token; } catch (IOException e) { ; } - return token; + throw new WeixinException("-1", "request fail"); } } diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java similarity index 77% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenApi.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java index c1135dc6..472e8ae7 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/RedisTokenHolder.java @@ -7,14 +7,12 @@ import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import com.foxinmy.weixin4j.exception.WeixinException; -import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.util.ConfigUtil; /** * 基于redis保存的Token获取类 * - * @className RedisTokenApi + * @className RedisTokenHolder * @author jy.hu * @date 2014年9月27日 * @since JDK 1.7 @@ -22,24 +20,23 @@ import com.foxinmy.weixin4j.util.ConfigUtil; * href="http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96access_token">获取token说明 * @see com.foxinmy.weixin4j.model.Token */ -public class RedisTokenApi extends AbstractTokenApi { - - private final HttpRequest request = new HttpRequest(); +public class RedisTokenHolder extends AbstractTokenHolder { private final String appid; private final String appsecret; private JedisPool jedisPool; - public RedisTokenApi() { + public RedisTokenHolder() { this.appid = getAppid(); this.appsecret = getAppsecret(); } - public RedisTokenApi(String appid, String appsecret) { + public RedisTokenHolder(String appid, String appsecret) { this(appid, appsecret, "localhost", 6379); } - public RedisTokenApi(String appid, String appsecret, String host, int port) { + public RedisTokenHolder(String appid, String appsecret, String host, + int port) { this.appid = appid; this.appsecret = appsecret; JedisPoolConfig poolConfig = new JedisPoolConfig(); @@ -64,8 +61,8 @@ public class RedisTokenApi extends AbstractTokenApi { String key = String.format("token:%s", appid); String accessToken = jedis.get(key); if (StringUtils.isBlank(accessToken)) { - String api_token_uri = String.format( - ConfigUtil.getValue("api_token_uri"), appid, appsecret); + String api_token_uri = String + .format(tokenUrl, appid, appsecret); token = request.get(api_token_uri).getAsObject(Token.class); jedis.setex(key, token.getExpiresIn() - 3, token.getAccessToken()); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenApi.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java similarity index 57% rename from weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenApi.java rename to weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java index e5574745..5ebd0abf 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenApi.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/token/TokenHolder.java @@ -6,15 +6,15 @@ import com.foxinmy.weixin4j.model.Token; /** * 获取Token接口 * - * @className TokenApi + * @className TokenHolder * @author jy.hu * @date 2014年9月27日 * @since JDK 1.7 * @see com.foxinmy.weixin4j.model.Token - * @see com.foxinmy.weixin4j.token.AbstractTokenApi - * @see com.foxinmy.weixin4j.token.FileTokenApi - * @see com.foxinmy.weixin4j.token.RedisTokenApi + * @see com.foxinmy.weixin4j.token.AbstractTokenHolder + * @see com.foxinmy.weixin4j.token.FileTokenHolder + * @see com.foxinmy.weixin4j.token.RedisTokenHolder */ -public interface TokenApi { +public interface TokenHolder { public Token getToken() throws WeixinException; } 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 9cb2fc40..d3c6cbf0 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 @@ -3,13 +3,8 @@ package com.foxinmy.weixin4j.util; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Properties; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class ConfigUtil { - public ConfigUtil() { - } - private static Properties props = new Properties(); static { try { @@ -23,18 +18,7 @@ public class ConfigUtil { } public static String getValue(String key) { - String url = props.getProperty(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, - getValue(sub.substring(1, sub.length() - 1))); - } - m.appendTail(sb); - return sb.toString(); + return props.getProperty(key); } public static void main(String[] args) { diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java index f55b7fc4..0cd38658 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/util/MessageUtil.java @@ -111,9 +111,7 @@ public class MessageUtil { messageClass = EventType.valueOf(type.toLowerCase()) .getEventClass(); } - XStream xstream = new XStream(); - xstream.ignoreUnknownElements(); - xstream.autodetectAnnotations(true); + XStream xstream = XStream.get(); xstream.processAnnotations(messageClass); xstream.alias("xml", messageClass); return xstream.fromXML(xmlMsg, messageClass); diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/Map2ObjectConverter.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/Map2ObjectConverter.java new file mode 100644 index 00000000..b7044e13 --- /dev/null +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/Map2ObjectConverter.java @@ -0,0 +1,31 @@ +package com.foxinmy.weixin4j.xml; + +import java.util.Iterator; +import java.util.Map; + +import com.thoughtworks.xstream.converters.MarshallingContext; +import com.thoughtworks.xstream.converters.collections.MapConverter; +import com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper; +import com.thoughtworks.xstream.io.HierarchicalStreamWriter; +import com.thoughtworks.xstream.mapper.Mapper; + +public class Map2ObjectConverter extends MapConverter { + + public Map2ObjectConverter(Mapper mapper) { + super(mapper); + } + + @Override + public void marshal(Object source, HierarchicalStreamWriter writer, + MarshallingContext context) { + Map map = (Map) source; + for (Iterator iterator = map.entrySet().iterator(); iterator + .hasNext();) { + Map.Entry entry = (Map.Entry) iterator.next(); + ExtendedHierarchicalStreamWriterHelper.startNode(writer, entry + .getKey().toString(), entry.getClass()); + writer.setValue(entry.getValue().toString()); + writer.endNode(); + } + } +} diff --git a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XStream.java b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XStream.java index 09e11765..4700853e 100644 --- a/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XStream.java +++ b/weixin4j-base/src/main/java/com/foxinmy/weixin4j/xml/XStream.java @@ -29,9 +29,11 @@ public class XStream extends com.thoughtworks.xstream.XStream { } }); } + public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) { super(hierarchicalStreamDriver); } + @SuppressWarnings("unchecked") public T fromXML(String xml, Class t) { return (T) super.fromXML(xml); @@ -41,4 +43,11 @@ public class XStream extends com.thoughtworks.xstream.XStream { public T fromXML(InputStream inputStream, Class t) { return (T) super.fromXML(inputStream); } + + public static XStream get() { + XStream xstream = new XStream(); + xstream.ignoreUnknownElements(); + xstream.autodetectAnnotations(true); + return xstream; + } } diff --git a/weixin4j-mp/README.md b/weixin4j-mp/README.md index 2f23022a..d5113aa1 100644 --- a/weixin4j-mp/README.md +++ b/weixin4j-mp/README.md @@ -6,7 +6,7 @@ tencent weixin platform java sdk 微信公众平台开发工具包 http://mp.wei 功能列表 ------- -* TokenApi token实现API +* TokenHolder token的实现 * MediaApi 上传/下载媒体文件API @@ -34,16 +34,16 @@ tencent weixin platform java sdk 微信公众平台开发工具包 http://mp.wei 1.编辑weixin.properties文件,填入appid/appsecret信息,当然也可通过构造函数传入. -2.实例化一个WeixinProxy对象,如无特别指明appid/appsecret则使用weixin.properties中的值. +2.实例化一个WeixinProxy对象,调用API. WeixinProxy weixinProxy = new WeixinProxy(); // weixinProxy = new WeixinProxy(appid,appsecret); weixinProxy.getUser(openId); -3.针对token存储有两种方案,File存储/Redis存储,当然也可自己实现TokenApi,如无特别指明默认使用文件(xml)的方式保存token,如果环境中支持redis,建议使用RedisTokenApi. +3.针对token存储有两种方案,File存储/Redis存储,当然也可自己实现TokenHolder(继承AbstractTokenHolder类并重写getToken方法),默认使用文件(xml)的方式保存token,如果环境中支持redis,建议使用RedisTokenHolder. - WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenApi()); - // weixinProxy = new WeixinProxy(new RedisTokenApi(appid,appsecret)); + WeixinProxy weixinProxy = new WeixinProxy(new RedisTokenHolder()); + // weixinProxy = new WeixinProxy(new RedisTokenHolder(appid,appsecret)); 4.mvn package,得到一个zip的压缩包,解压到启动目录(见src/main/startup.sh/APP_HOME) @@ -60,4 +60,10 @@ tencent weixin platform java sdk 微信公众平台开发工具包 http://mp.wei * 2014-10-28 - 1).调整ActionMapping抽象化 \ No newline at end of file + 1).调整ActionMapping抽象化 + +* 2014-10-31 + + 1).weixin.properties切分为API调用地址/公众号信息两部分 + + 2).TokenApi重命名为TokenHolder \ No newline at end of file diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/README.md b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/README.md deleted file mode 100644 index ba68f7c5..00000000 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/README.md +++ /dev/null @@ -1 +0,0 @@ -所有的API调用入口类 \ No newline at end of file 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 91de198e..a6644c53 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 @@ -8,6 +8,7 @@ import com.alibaba.fastjson.JSONObject; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.BaseResult; import com.foxinmy.weixin4j.model.WeixinAccountV2; +import com.foxinmy.weixin4j.model.WeixinAccountV3; import com.foxinmy.weixin4j.mp.api.GroupApi; import com.foxinmy.weixin4j.mp.api.HelperApi; import com.foxinmy.weixin4j.mp.api.MassApi; @@ -29,10 +30,10 @@ import com.foxinmy.weixin4j.mp.model.UserToken; import com.foxinmy.weixin4j.mp.msg.model.Article; import com.foxinmy.weixin4j.mp.msg.model.BaseMsg; import com.foxinmy.weixin4j.mp.msg.notify.BaseNotify; -import com.foxinmy.weixin4j.mp.payment.Order; +import com.foxinmy.weixin4j.mp.payment.v2.Order; import com.foxinmy.weixin4j.mp.response.TemplateMessage; -import com.foxinmy.weixin4j.token.FileTokenApi; -import com.foxinmy.weixin4j.token.TokenApi; +import com.foxinmy.weixin4j.token.FileTokenHolder; +import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.type.MediaType; /** @@ -60,7 +61,7 @@ public class WeixinProxy { * 默认采用文件存放Token跟配置文件中的appi信息 */ public WeixinProxy() { - this(new FileTokenApi()); + this(new FileTokenHolder()); } /** @@ -70,10 +71,10 @@ public class WeixinProxy { * @param appsecret */ public WeixinProxy(String appid, String appsecret) { - this(new FileTokenApi(appid, appsecret)); + this(new FileTokenHolder(appid, appsecret)); } - public WeixinProxy(TokenApi tokenApi) { + public WeixinProxy(TokenHolder tokenApi) { this.mediaApi = new MediaApi(tokenApi); this.notifyApi = new NotifyApi(tokenApi); this.massApi = new MassApi(tokenApi); @@ -749,4 +750,36 @@ public class WeixinProxy { throws WeixinException { return payApi.orderQuery(weixinConfig, orderNo); } + + /** + * 维权处理 + * + * @param openId + * 用户ID + * @param feedbackId + * 维权单号 + * @return + * @see com.foxinmy.weixin4j.mp.api.PayApi + * @throws WeixinException + */ + public BaseResult updateFeedback(String openId, String feedbackId) + throws WeixinException { + return payApi.updateFeedback(openId, feedbackId); + } + + /** + * native支付URL转短链接 + * + * @param weixinConfig + * 商户配置 + * @param url + * native支付URL + * @return 转换后的短链接 + * @see com.foxinmy.weixin4j.mp.api.PayApi + * @throws WeixinException + */ + public String getShorturl(WeixinAccountV3 weixinConfig, String url) + throws WeixinException { + return payApi.getShorturl(weixinConfig, url); + } } diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/action/AbstractAction.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/action/AbstractAction.java index 5ee27ce3..6bb26a1f 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/action/AbstractAction.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/action/AbstractAction.java @@ -30,9 +30,7 @@ public abstract class AbstractAction implements BaseMessage message = MessageUtil.xml2msg(msg); if (message == null) { Class messageClass = getGenericType(); - XStream xstream = new XStream(); - xstream.ignoreUnknownElements(); - xstream.autodetectAnnotations(true); + XStream xstream = XStream.get(); xstream.processAnnotations(messageClass); xstream.alias("xml", messageClass); return execute(xstream.fromXML(msg, messageClass)).toXml(); diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java index a8536813..57605198 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/BaseApi.java @@ -1,6 +1,13 @@ package com.foxinmy.weixin4j.mp.api; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +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.XStream; /** * @@ -12,4 +19,26 @@ import com.foxinmy.weixin4j.http.HttpRequest; */ public class BaseApi { protected final HttpRequest request = new HttpRequest(); + protected final XStream xStream = XStream.get(); + protected final Charset utf8 = StandardCharsets.UTF_8; + private final static ResourceBundle weixinBundle; + static { + weixinBundle = ResourceBundle + .getBundle("com/foxinmy/weixin4j/mp/api/weixin"); + } + + 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-mp/src/main/java/com/foxinmy/weixin4j/mp/api/GroupApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/GroupApi.java index c640994d..3ca1f44d 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/GroupApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/GroupApi.java @@ -8,8 +8,7 @@ import com.foxinmy.weixin4j.http.BaseResult; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.mp.model.Group; -import com.foxinmy.weixin4j.token.TokenApi; -import com.foxinmy.weixin4j.util.ConfigUtil; +import com.foxinmy.weixin4j.token.TokenHolder; /** * 分组相关API @@ -24,8 +23,8 @@ import com.foxinmy.weixin4j.util.ConfigUtil; */ public class GroupApi extends BaseApi { - private final TokenApi tokenApi; - public GroupApi(TokenApi tokenApi) { + private final TokenHolder tokenApi; + public GroupApi(TokenHolder tokenApi) { this.tokenApi = tokenApi; } @@ -42,7 +41,7 @@ public class GroupApi extends BaseApi { * @see com.foxinmy.weixin4j.mp.model.Group#toCreateJson() */ public Group createGroup(String name) throws WeixinException { - String group_create_uri = ConfigUtil.getValue("group_create_uri"); + String group_create_uri = getRequestUri("group_create_uri"); Token token = tokenApi.getToken(); Group group = new Group(name); Response response = request.post( @@ -62,7 +61,7 @@ public class GroupApi extends BaseApi { * @see com.foxinmy.weixin4j.mp.model.Group */ public List getGroups() throws WeixinException { - String group_get_uri = ConfigUtil.getValue("group_get_uri"); + String group_get_uri = getRequestUri("group_get_uri"); Token token = tokenApi.getToken(); Response response = request.get(String.format(group_get_uri, token.getAccessToken())); @@ -83,7 +82,7 @@ public class GroupApi extends BaseApi { * @see com.foxinmy.weixin4j.mp.model.Group */ public int getGroupByOpenId(String openId) throws WeixinException { - String group_getid_uri = ConfigUtil.getValue("group_getid_uri"); + String group_getid_uri = getRequestUri("group_getid_uri"); Token token = tokenApi.getToken(); Response response = request.post( String.format(group_getid_uri, token.getAccessToken()), @@ -107,7 +106,7 @@ public class GroupApi extends BaseApi { */ public BaseResult modifyGroup(int groupId, String name) throws WeixinException { - String group_modify_uri = ConfigUtil.getValue("group_modify_uri"); + String group_modify_uri = getRequestUri("group_modify_uri"); Token token = tokenApi.getToken(); Group group = new Group(groupId, name); @@ -131,7 +130,7 @@ public class GroupApi extends BaseApi { */ public BaseResult moveGroup(String openId, int groupId) throws WeixinException { - String group_move_uri = ConfigUtil.getValue("group_move_uri"); + String group_move_uri = getRequestUri("group_move_uri"); Token token = tokenApi.getToken(); Response response = request.post(String.format(group_move_uri, token.getAccessToken()), String.format( diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java index 6998f9d8..4becb1a7 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/HelperApi.java @@ -4,8 +4,7 @@ import com.alibaba.fastjson.JSONObject; import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.token.TokenApi; -import com.foxinmy.weixin4j.util.ConfigUtil; +import com.foxinmy.weixin4j.token.TokenHolder; /** * 辅助相关API @@ -17,12 +16,13 @@ import com.foxinmy.weixin4j.util.ConfigUtil; * @see */ public class HelperApi extends BaseApi { - - private final TokenApi tokenApi; - public HelperApi(TokenApi tokenApi){ + + private final TokenHolder tokenApi; + + public HelperApi(TokenHolder tokenApi) { this.tokenApi = tokenApi; } - + /** * 长链接转短链接 * @@ -33,13 +33,15 @@ public class HelperApi extends BaseApi { * href="http://mp.weixin.qq.com/wiki/index.php?title=%E9%95%BF%E9%93%BE%E6%8E%A5%E8%BD%AC%E7%9F%AD%E9%93%BE%E6%8E%A5%E6%8E%A5%E5%8F%A3">长链接转短链接 */ public String getShorturl(String url) throws WeixinException { - String shorturl_uri = ConfigUtil.getValue("shorturl_uri"); + String shorturl_uri = getRequestUri("shorturl_uri"); Token token = tokenApi.getToken(); JSONObject obj = new JSONObject(); obj.put("action", "long2short"); obj.put("long_url", url); - Response response = request.post(String.format(shorturl_uri, token.getAccessToken()), obj.toJSONString()); - + Response response = request.post( + String.format(shorturl_uri, token.getAccessToken()), + obj.toJSONString()); + return response.getAsJson().getString("short_url"); } } 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 de3aa88b..57caad6b 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 @@ -9,9 +9,8 @@ import com.foxinmy.weixin4j.http.BaseResult; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.mp.model.MpArticle; -import com.foxinmy.weixin4j.token.TokenApi; +import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.type.MediaType; -import com.foxinmy.weixin4j.util.ConfigUtil; /** * 群发相关API @@ -26,9 +25,9 @@ import com.foxinmy.weixin4j.util.ConfigUtil; */ public class MassApi extends BaseApi { - private final TokenApi tokenApi; + private final TokenHolder tokenApi; - public MassApi(TokenApi tokenApi) { + public MassApi(TokenHolder tokenApi) { this.tokenApi = tokenApi; } @@ -47,7 +46,7 @@ public class MassApi extends BaseApi { */ public String uploadArticle(List articles) throws WeixinException { - String article_upload_uri = ConfigUtil.getValue("article_upload_uri"); + String article_upload_uri = getRequestUri("article_upload_uri"); Token token = tokenApi.getToken(); JSONObject obj = new JSONObject(); obj.put("articles", articles); @@ -75,7 +74,7 @@ public class MassApi extends BaseApi { */ public String uploadVideo(String mediaId, String title, String desc) throws WeixinException { - String video_upload_uri = ConfigUtil.getValue("video_upload_uri"); + String video_upload_uri = getRequestUri("video_upload_uri"); Token token = tokenApi.getToken(); JSONObject obj = new JSONObject(); obj.put("media_id", mediaId); @@ -109,7 +108,7 @@ public class MassApi extends BaseApi { */ private String massByGroup(JSONObject jsonPara, String groupId) throws WeixinException { - String mass_group_uri = ConfigUtil.getValue("mass_group_uri"); + String mass_group_uri = getRequestUri("mass_group_uri"); Token token = tokenApi.getToken(); Response response = request.post( String.format(mass_group_uri, token.getAccessToken()), @@ -133,7 +132,7 @@ public class MassApi extends BaseApi { */ private String massByOpenIds(JSONObject jsonPara, String... openIds) throws WeixinException { - String mass_openid_uri = ConfigUtil.getValue("mass_openid_uri"); + String mass_openid_uri = getRequestUri("mass_openid_uri"); Token token = tokenApi.getToken(); Response response = request.post( String.format(mass_openid_uri, token.getAccessToken()), @@ -259,7 +258,7 @@ public class MassApi extends BaseApi { public BaseResult deleteMassNews(String msgid) throws WeixinException { JSONObject obj = new JSONObject(); obj.put("msgid", msgid); - String mass_delete_uri = ConfigUtil.getValue("mass_delete_uri"); + String mass_delete_uri = getRequestUri("mass_delete_uri"); Token token = tokenApi.getToken(); Response response = request.post( String.format(mass_delete_uri, token.getAccessToken()), diff --git a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java index d2d31cc0..784ea9ad 100644 --- a/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java +++ b/weixin4j-mp/src/main/java/com/foxinmy/weixin4j/mp/api/MediaApi.java @@ -11,9 +11,8 @@ import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.http.PartParameter; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; -import com.foxinmy.weixin4j.token.TokenApi; +import com.foxinmy.weixin4j.token.TokenHolder; import com.foxinmy.weixin4j.type.MediaType; -import com.foxinmy.weixin4j.util.ConfigUtil; import com.foxinmy.weixin4j.util.IOUtil; /** @@ -29,9 +28,9 @@ import com.foxinmy.weixin4j.util.IOUtil; */ public class MediaApi extends BaseApi { - private final TokenApi tokenApi; + private final TokenHolder tokenApi; - public MediaApi(TokenApi tokenApi) { + public MediaApi(TokenHolder tokenApi) { this.tokenApi = tokenApi; } @@ -74,7 +73,7 @@ public class MediaApi extends BaseApi { public String uploadMedia(String fileName, byte[] bytes, MediaType mediaType) throws WeixinException { Token token = tokenApi.getToken(); - String file_upload_uri = ConfigUtil.getValue("file_upload_uri"); + String file_upload_uri = getRequestUri("file_upload_uri"); Response response = request.post(String.format(file_upload_uri, token.getAccessToken(), mediaType.name()), new PartParameter( "media", new ByteArrayBody(bytes, fileName))); @@ -101,7 +100,7 @@ public class MediaApi extends BaseApi { */ public File downloadMedia(String mediaId, MediaType mediaType) throws WeixinException, IOException { - String media_path = ConfigUtil.getValue("media_path"); + String media_path = getRequestUri("media_path"); byte[] datas = downloadMediaData(mediaId, mediaType); String filename = mediaId + "." + mediaType.getFormatType(); File file = new File(media_path + File.separator + filename); @@ -133,7 +132,7 @@ public class MediaApi extends BaseApi { public byte[] downloadMediaData(String mediaId, MediaType mediaType) throws WeixinException { Token token = tokenApi.getToken(); - String file_download_uri = ConfigUtil.getValue("file_download_uri"); + String file_download_uri = getRequestUri("file_download_uri"); Response response = request.get(String.format(file_download_uri, token.getAccessToken(), mediaId)); 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 d264c5d8..3647f394 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 @@ -9,8 +9,7 @@ import com.foxinmy.weixin4j.http.BaseResult; import com.foxinmy.weixin4j.http.Response; import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.mp.model.Button; -import com.foxinmy.weixin4j.token.TokenApi; -import com.foxinmy.weixin4j.util.ConfigUtil; +import com.foxinmy.weixin4j.token.TokenHolder; /** * 菜单相关API @@ -23,9 +22,9 @@ import com.foxinmy.weixin4j.util.ConfigUtil; */ public class MenuApi extends BaseApi { - private final TokenApi tokenApi; + private final TokenHolder tokenApi; - public MenuApi(TokenApi tokenApi) { + public MenuApi(TokenHolder tokenApi) { this.tokenApi = tokenApi; } @@ -39,7 +38,7 @@ public class MenuApi extends BaseApi { * @see com.foxinmy.weixin4j.mp.model.Button */ public BaseResult createMenu(List