切分weixin.properties

This commit is contained in:
jy.hu 2014-10-31 11:13:28 +08:00
parent 277f3e4eec
commit 72229caf35
52 changed files with 697 additions and 359 deletions

View File

@ -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等类
接下来
------

View File

@ -1,4 +1,12 @@
weixin4j-base
=============
tencent weixin base java sdk 微信开发基础工程
tencent weixin base java sdk 微信开发基础工程
更新LOG
-------
* 2014-10-31
1).TokenApi重命名为TokenHolder
2).新增WeixinConfig等类

View File

@ -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;

View File

@ -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;
}

View File

@ -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 <a
* href="http://mp.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">全局返回码</a>
*/
@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;
}

View File

@ -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");
}
}

View File

@ -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> T getAsObject(Class<? extends Serializable> clazz) {
public <T> T getAsObject(Class<T> clazz) {
return (T) JSON.parseObject(text, clazz);
}
public Object getAsXml() {
XStream xs = new XStream();
xs.autodetectAnnotations(true);
return xs.fromXML(text);
public <T> T getAsXml(Class<T> 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());
}

View File

@ -82,4 +82,16 @@
<error code="47001">解析JSON/XML内容错误</error>
<error code="48001">api功能未授权</error>
<error code="50001">用户未授权该api</error>
<error code="SYSTEMERROR">接口后台错误</error>
<error code="INVALID_TRANSACTIONID">无效 transaction_id</error>
<error code="PARAM_ERROR">提交参数错误</error>
<error code="ORDERPAID">订单已支付</error>
<error code="OUT_TRADE_NO_USED">商户订单号重复</error>
<error code="NOAUTH">商户无权限</error>
<error code="NOTENOUGH">余额不足</error>
<error code="NOTSUPORTCARD">不支持卡类型</error>
<error code="ORDERCLOSED">订单已关闭</error>
<error code="BANKERROR">银行系统异常</error>
<error code="REFUND_FEE_INVALID">退款金额大于支付金额</error>
<error code="ORDERNOTEXIST">订单不存在</error>
</errors>

View File

@ -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() + "]";
}
}

View File

@ -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() + "]";
}
}

View File

@ -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() + "]";
}
}

View File

@ -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 + "]";
}
}

View File

@ -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<? extends BaseMessage> targetClass = getMsgType()
.getMessageClass();
xmlStream.alias("xml", targetClass);
return xmlStream;
}
/**
* 消息对象转换为微信服务器接受的xml格式消息
*
* @return xml字符串
*/
public String toXml() {
return getXStream().toXML(this);
Class<? extends BaseMessage> targetClass = getMsgType()
.getMessageClass();
xmlStream.alias("xml", targetClass);
return xmlStream.toXML(this);
}
/**

View File

@ -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");
}
}

View File

@ -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();
}
}

View File

@ -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说明</a>
* @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");
}
}

View File

@ -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说明</a>
* @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());

View File

@ -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;
}

View File

@ -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) {

View File

@ -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);

View File

@ -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();
}
}
}

View File

@ -29,9 +29,11 @@ public class XStream extends com.thoughtworks.xstream.XStream {
}
});
}
public XStream(HierarchicalStreamDriver hierarchicalStreamDriver) {
super(hierarchicalStreamDriver);
}
@SuppressWarnings("unchecked")
public <T> T fromXML(String xml, Class<T> t) {
return (T) super.fromXML(xml);
@ -41,4 +43,11 @@ public class XStream extends com.thoughtworks.xstream.XStream {
public <T> T fromXML(InputStream inputStream, Class<T> t) {
return (T) super.fromXML(inputStream);
}
public static XStream get() {
XStream xstream = new XStream();
xstream.ignoreUnknownElements();
xstream.autodetectAnnotations(true);
return xstream;
}
}

View File

@ -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抽象化
1).调整ActionMapping抽象化
* 2014-10-31
1).weixin.properties切分为API调用地址/公众号信息两部分
2).TokenApi重命名为TokenHolder

View File

@ -1 +0,0 @@
所有的API调用入口类

View File

@ -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);
}
}

View File

@ -30,9 +30,7 @@ public abstract class AbstractAction<M extends BaseMessage> implements
BaseMessage message = MessageUtil.xml2msg(msg);
if (message == null) {
Class<M> 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();

View File

@ -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();
}
}

View File

@ -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<Group> 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(

View File

@ -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">长链接转短链接</a>
*/
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");
}
}

View File

@ -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<MpArticle> 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()),

View File

@ -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));

View File

@ -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<Button> btnList) throws WeixinException {
String menu_create_uri = ConfigUtil.getValue("menu_create_uri");
String menu_create_uri = getRequestUri("menu_create_uri");
Token token = tokenApi.getToken();
JSONObject obj = new JSONObject();
obj.put("button", btnList);
@ -60,7 +59,7 @@ public class MenuApi extends BaseApi {
* @see com.foxinmy.weixin4j.mp.model.Button
*/
public List<Button> getMenu() throws WeixinException {
String menu_get_uri = ConfigUtil.getValue("menu_get_uri");
String menu_get_uri = getRequestUri("menu_get_uri");
Token token = tokenApi.getToken();
Response response = request.get(String.format(menu_get_uri,
token.getAccessToken()));
@ -79,7 +78,7 @@ public class MenuApi extends BaseApi {
* @see com.foxinmy.weixin4j.mp.model.Button
*/
public BaseResult deleteMenu() throws WeixinException {
String menu_delete_uri = ConfigUtil.getValue("menu_delete_uri");
String menu_delete_uri = getRequestUri("menu_delete_uri");
Token token = tokenApi.getToken();
Response response = request.get(String.format(menu_delete_uri,
token.getAccessToken()));

View File

@ -13,8 +13,7 @@ import com.foxinmy.weixin4j.mp.msg.model.Article;
import com.foxinmy.weixin4j.mp.msg.model.BaseMsg;
import com.foxinmy.weixin4j.mp.msg.notify.ArticleNotify;
import com.foxinmy.weixin4j.mp.msg.notify.BaseNotify;
import com.foxinmy.weixin4j.token.TokenApi;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
* 客服相关API
@ -34,9 +33,9 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
*/
public class NotifyApi extends BaseApi {
private final TokenApi tokenApi;
private final TokenHolder tokenApi;
public NotifyApi(TokenApi tokenApi) {
public NotifyApi(TokenHolder tokenApi) {
this.tokenApi = tokenApi;
}
@ -50,7 +49,7 @@ public class NotifyApi extends BaseApi {
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E5%8F%91%E9%80%81%E5%AE%A2%E6%9C%8D%E6%B6%88%E6%81%AF#.E5.8F.91.E9.80.81.E9.9F.B3.E4.B9.90.E6.B6.88.E6.81.AF">发送客服消息</a>
*/
private BaseResult sendNotify(String jsonPara) throws WeixinException {
String custom_notify_uri = ConfigUtil.getValue("custom_notify_uri");
String custom_notify_uri = getRequestUri("custom_notify_uri");
Token token = tokenApi.getToken();
Response response = request.post(
String.format(custom_notify_uri, token.getAccessToken()),
@ -154,7 +153,7 @@ public class NotifyApi extends BaseApi {
obj.put("endtime", endtime);
obj.put("pagesize", pagesize > 1000 ? 1000 : pagesize);
obj.put("pageindex", pageindex);
String custom_record_uri = ConfigUtil.getValue("custom_record_uri");
String custom_record_uri = getRequestUri("custom_record_uri");
Token token = tokenApi.getToken();
Response response = request.post(
String.format(custom_record_uri, token.getAccessToken()),

View File

@ -10,8 +10,7 @@ import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.QRParameter;
import com.foxinmy.weixin4j.mp.model.QRParameter.QRType;
import com.foxinmy.weixin4j.token.TokenApi;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
* 二维码相关API
@ -25,9 +24,9 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
*/
public class QrApi extends BaseApi {
private final TokenApi tokenApi;
private final TokenHolder tokenApi;
public QrApi(TokenApi tokenApi) {
public QrApi(TokenHolder tokenApi) {
this.tokenApi = tokenApi;
}
@ -41,12 +40,12 @@ public class QrApi extends BaseApi {
*/
public byte[] getQRData(QRParameter parameter) throws WeixinException {
Token token = tokenApi.getToken();
String qr_uri = ConfigUtil.getValue("qr_ticket_uri");
String qr_uri = getRequestUri("qr_ticket_uri");
Response response = request.post(
String.format(qr_uri, token.getAccessToken()),
parameter.toJson());
String ticket = response.getAsJson().getString("ticket");
qr_uri = ConfigUtil.getValue("qr_image_uri");
qr_uri = getRequestUri("qr_image_uri");
response = request.get(String.format(qr_uri, ticket));
return response.getBody();
@ -90,7 +89,7 @@ public class QrApi extends BaseApi {
*/
public File getQR(QRParameter parameter) throws WeixinException,
IOException {
String qr_path = ConfigUtil.getValue("qr_path");
String qr_path = getRequestUri("qr_path");
String filename = String.format("%s_%d_%d.jpg", parameter.getQrType()
.name(), parameter.getSceneId(), parameter.getExpireSeconds());
File file = new File(qr_path + File.separator + filename);

View File

@ -5,8 +5,7 @@ import com.foxinmy.weixin4j.http.BaseResult;
import com.foxinmy.weixin4j.http.Response;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.response.TemplateMessage;
import com.foxinmy.weixin4j.token.TokenApi;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
* 模板消息相关API
@ -19,9 +18,9 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
*/
public class TmplApi extends BaseApi {
private final TokenApi tokenApi;
private final TokenHolder tokenApi;
public TmplApi(TokenApi tokenApi) {
public TmplApi(TokenHolder tokenApi) {
this.tokenApi = tokenApi;
}
@ -39,7 +38,7 @@ public class TmplApi extends BaseApi {
public BaseResult sendTmplMessage(TemplateMessage tplMessage)
throws WeixinException {
Token token = tokenApi.getToken();
String template_send_uri = ConfigUtil.getValue("template_send_uri");
String template_send_uri = getRequestUri("template_send_uri");
Response response = request.post(
String.format(template_send_uri, token.getAccessToken()),
tplMessage.toJson());

View File

@ -12,8 +12,7 @@ import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.model.Following;
import com.foxinmy.weixin4j.mp.model.User;
import com.foxinmy.weixin4j.mp.model.UserToken;
import com.foxinmy.weixin4j.token.TokenApi;
import com.foxinmy.weixin4j.util.ConfigUtil;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
* 用户相关API
@ -26,9 +25,9 @@ import com.foxinmy.weixin4j.util.ConfigUtil;
*/
public class UserApi extends BaseApi {
private final TokenApi tokenApi;
private final TokenHolder tokenApi;
public UserApi(TokenApi tokenApi) {
public UserApi(TokenHolder tokenApi) {
this.tokenApi = tokenApi;
}
@ -44,7 +43,7 @@ public class UserApi extends BaseApi {
* @see com.foxinmy.weixin4j.mp.model.UserToken
*/
public UserToken getAccessToken(String code) throws WeixinException {
String user_token_uri = ConfigUtil.getValue("sns_user_token_uri");
String user_token_uri = getRequestUri("sns_user_token_uri");
Response response = request.get(String.format(user_token_uri, code));
return response.getAsObject(UserToken.class);
@ -64,7 +63,7 @@ public class UserApi extends BaseApi {
* {@link com.foxinmy.weixin4j.mp.api.UserApi#getAccessToken(String)}
*/
public User getUser(UserToken token) throws WeixinException {
String user_info_uri = ConfigUtil.getValue("sns_user_info_uri");
String user_info_uri = getRequestUri("sns_user_info_uri");
Response response = request.get(String.format(user_info_uri,
token.getAccessToken(), token.getOpenid()));
@ -87,7 +86,7 @@ public class UserApi extends BaseApi {
* @see com.foxinmy.weixin4j.mp.model.User
*/
public User getUser(String openId) throws WeixinException {
String user_info_uri = ConfigUtil.getValue("api_user_info_uri");
String user_info_uri = getRequestUri("api_user_info_uri");
Token token = tokenApi.getToken();
Response response = request.get(String.format(user_info_uri,
token.getAccessToken(), openId));
@ -107,7 +106,7 @@ public class UserApi extends BaseApi {
* @see com.foxinmy.weixin4j.mp.model.Following
*/
public Following getFollowing(String nextOpenId) throws WeixinException {
String fllowing_uri = ConfigUtil.getValue("following_uri");
String fllowing_uri = getRequestUri("following_uri");
Token token = tokenApi.getToken();
Response response = request.get(String.format(fllowing_uri,
token.getAccessToken(), nextOpenId == null ? "" : nextOpenId));
@ -168,7 +167,7 @@ public class UserApi extends BaseApi {
*/
public BaseResult remarkUserName(String openId, String remark)
throws WeixinException {
String updateremark_uri = ConfigUtil.getValue("updateremark_uri");
String updateremark_uri = getRequestUri("updateremark_uri");
Token token = tokenApi.getToken();
JSONObject obj = new JSONObject();
obj.put("openid", openId);

View File

@ -0,0 +1,73 @@
# ----------------------------------------------------------------------------
# api\u9996\u9875
# http://mp.weixin.qq.com/wiki/index.php
# \u63a5\u53e3\u8c03\u7528\u8bf4\u660e
# http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E5%8F%A3%E9%A2%91%E7%8E%87%E9%99%90%E5%88%B6%E8%AF%B4%E6%98%8E
# ----------------------------------------------------------------------------
api_base_url=https://api.weixin.qq.com/cgi-bin
mp_base_url=https://mp.weixin.qq.com/cgi-bin
file_base_url=http://file.api.weixin.qq.com/cgi-bin
mch_base_url=https://api.mch.weixin.qq.com
# \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f
user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid={app_id}&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect
sns_user_token_uri=https://api.weixin.qq.com/sns/oauth2/access_token?appid={app_id}&secret={app_secret}&code=%s&grant_type=authorization_code
sns_user_info_uri=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
# \u76f4\u63a5\u83b7\u53d6\u7528\u6237\u4fe1\u606f
api_user_info_uri={api_base_url}/user/info?access_token=%s&openid=%s&lang=zh_CN
# \u83b7\u53d6token
api_token_uri={api_base_url}/token?grant_type=client_credential&appid=%s&secret=%s
# \u83b7\u53d6\u4e8c\u7ef4\u7801
qr_ticket_uri={api_base_url}/qrcode/create?access_token=%s
qr_image_uri={mp_base_url}/showqrcode?ticket=%s
# \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6
file_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s
# \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6
file_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s
# \u53d1\u9001\u5ba2\u670d\u6d88\u606f
custom_notify_uri={api_base_url}/message/custom/send?access_token=%s
# \u521b\u5efa\u5206\u7ec4
group_create_uri={api_base_url}/groups/create?access_token=%s
# \u67e5\u8be2\u5206\u7ec4
group_get_uri={api_base_url}/groups/get?access_token=%s
# \u67e5\u8be2\u7528\u6237\u6240\u5728\u5206\u7ec4
group_getid_uri={api_base_url}/groups/getid?access_token=%s
# \u4fee\u6539\u5206\u7ec4\u540d
group_modify_uri={api_base_url}/groups/update?access_token=%s
# \u79fb\u52a8\u7528\u6237\u5206\u7ec4
group_move_uri={api_base_url}/groups/members/update?access_token=%s
# \u83b7\u53d6\u5173\u6ce8\u7740
following_uri={api_base_url}/user/get?access_token=%s&next_openid=%s
# \u81ea\u5b9a\u4e49\u83dc\u5355
menu_create_uri={api_base_url}/menu/create?access_token=%s
# \u67e5\u8be2\u83dc\u5355
menu_get_uri={api_base_url}/menu/get?access_token=%s
# \u5220\u9664\u83dc\u5355
menu_delete_uri={api_base_url}/menu/delete?access_token=%s
# \u4e0a\u4f20\u56fe\u6587
article_upload_uri={api_base_url}/media/uploadnews?access_token=%s
# \u4e0a\u4f20\u89c6\u9891
video_upload_uri={file_base_url}/media/uploadvideo?access_token=%s
# \u5206\u7ec4\u7fa4\u53d1
mass_group_uri={api_base_url}/message/mass/sendall?access_token=%s
# openId\u7fa4\u53d1
mass_openid_uri={api_base_url}/message/mass/send?access_token=%s
# \u5220\u9664\u7fa4\u53d1
mass_delete_uri={api_base_url}/message/mass/delete?access_token=%s
# \u5ba2\u670d\u804a\u5929\u8bb0\u5f55
custom_record_uri={api_base_url}/customservice/getrecord?access_token=%s
# \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5
shorturl_uri={api_base_url}/shorturl?access_token=%s
p_shorturl_uri={mch_base_url}/tools/shorturl
# \u8bbe\u7f6e\u5907\u6ce8\u540d
updateremark_uri={api_base_url}/user/info/updateremark?access_token=%s
# \u6a21\u677f\u6d88\u606f
template_send_uri={api_base_url}/message/template/send?access_token=%s
# \u67e5\u8be2\u8ba2\u5355
orderquery_uri={api_base_url}/pay/orderquery?access_token=%s
# \u53d1\u8d27\u901a\u77e5
delivernotify_uri={api_base_url}/pay/delivernotify?access_token=%s
# \u7ef4\u6743\u5904\u7406
payfeedback_update_uri={api_base_url}/payfeedback/update?access_token=%s&openid=%s&feedbackid=%s

View File

@ -2,11 +2,9 @@ package com.foxinmy.weixin4j.mp.model;
import java.io.Serializable;
import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.io.json.JsonHierarchicalStreamDriver;
/**
* 分组
*
* @author jy.hu
* @date 2014年4月4日
* @since JDK 1.7
@ -56,29 +54,22 @@ public class Group implements Serializable {
/**
* 返回创建分组所需的json格式字符串
*
* @return {"group": {"id": 107, "name": "test"}}
*/
public String toCreateJson() {
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
xstream.omitField(this.getClass(), "id");
xstream.omitField(this.getClass(), "count");
xstream.alias("group", this.getClass());
xstream.autodetectAnnotations(true);
xstream.processAnnotations(this.getClass());
return xstream.toXML(this);
return String.format("{\"group\":{\"id\":%s,\"name\":\"%s\"}}", id,
name);
}
/**
* 返回修改分组所需的json格式字符串
* @return
*
* @return {"group": {"id": 107, "name": "test"}}
*/
public String toModifyJson() {
XStream xstream = new XStream(new JsonHierarchicalStreamDriver());
xstream.omitField(this.getClass(), "count");
xstream.alias("group", this.getClass());
xstream.autodetectAnnotations(true);
xstream.processAnnotations(this.getClass());
return xstream.toXML(this);
return String.format("{\"group\":{\"id\":%s,\"name\":\"%s\"}}", id,
name);
}
@Override
@ -91,6 +82,7 @@ public class Group implements Serializable {
@Override
public String toString() {
return String.format("[Group id=%d ,name=%s ,count=%d]", id, name, count);
return String.format("[Group id=%d ,name=%s ,count=%d]", id, name,
count);
}
}

View File

@ -5,7 +5,6 @@ import java.util.LinkedList;
import com.foxinmy.weixin4j.mp.msg.model.Article;
import com.foxinmy.weixin4j.mp.type.ResponseType;
import com.foxinmy.weixin4j.msg.BaseMessage;
import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@ -21,6 +20,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class ArticleResponse extends BaseResponse {
private static final int MAX_ARTICLE_COUNT = 10;
private static final long serialVersionUID = -7331603018352309317L;
@ -82,13 +82,12 @@ public class ArticleResponse extends BaseResponse {
@Override
public String toXml() {
this.count = articles.size();
XStream xstream = getXStream();
xstream.alias("item", Article.class);
xstream.aliasField("Title", Article.class, "title");
xstream.aliasField("Description", Article.class, "desc");
xstream.aliasField("PicUrl", Article.class, "picUrl");
xstream.aliasField("Url", Article.class, "url");
return xstream.toXML(this);
xmlStream.alias("item", Article.class);
xmlStream.aliasField("Title", Article.class, "title");
xmlStream.aliasField("Description", Article.class, "desc");
xmlStream.aliasField("PicUrl", Article.class, "picUrl");
xmlStream.aliasField("Url", Article.class, "url");
return xmlStream.toXML(this);
}
@Override

View File

@ -27,7 +27,7 @@ import com.thoughtworks.xstream.io.json.JsonWriter;
public class BaseResponse implements Serializable {
private static final long serialVersionUID = 7761192742840031607L;
private final static XStream xmlStream = new XStream();
protected final static XStream xmlStream = XStream.get();
private final static XStream jsonStream = new XStream(
new JsonHierarchicalStreamDriver() {
public HierarchicalStreamWriter createWriter(Writer writer) {
@ -48,8 +48,6 @@ public class BaseResponse implements Serializable {
Class<?>[] classes = ClassUtil.getClasses(
BaseResponse.class.getPackage()).toArray(new Class[0]);
xmlStream.ignoreUnknownElements();
xmlStream.autodetectAnnotations(true);
xmlStream.processAnnotations(classes);
jsonStream.setMode(XStream.NO_REFERENCES);
@ -104,20 +102,13 @@ public class BaseResponse implements Serializable {
this.msgType = msgType;
}
protected XStream getXStream() {
Class<? extends BaseResponse> targetClass = this.msgType
.getMessageClass();
xmlStream.alias("xml", targetClass);
return xmlStream;
}
/**
* 消息对象转换为微信服务器接受的xml格式消息
*
* @return xml字符串
*/
public String toXml() {
return getXStream().toXML(this);
return xmlStream.toXML(this);
}
/**

View File

@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.mp.response;
import com.foxinmy.weixin4j.mp.msg.model.Image;
import com.foxinmy.weixin4j.mp.type.ResponseType;
import com.foxinmy.weixin4j.msg.BaseMessage;
import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@ -20,6 +19,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class ImageResponse extends BaseResponse {
private static final long serialVersionUID = 6998255203997554731L;
@ -42,9 +42,8 @@ public class ImageResponse extends BaseResponse {
@Override
public String toXml() {
XStream xstream = getXStream();
xstream.aliasField("MediaId", Image.class, "mediaId");
return xstream.toXML(this);
xmlStream.aliasField("MediaId", Image.class, "mediaId");
return xmlStream.toXML(this);
}
@Override

View File

@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.mp.response;
import com.foxinmy.weixin4j.mp.msg.model.Music;
import com.foxinmy.weixin4j.mp.type.ResponseType;
import com.foxinmy.weixin4j.msg.BaseMessage;
import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@ -19,6 +18,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class MusicResponse extends BaseResponse {
private static final long serialVersionUID = 4384403772658796395L;
@ -40,13 +40,12 @@ public class MusicResponse extends BaseResponse {
@Override
public String toXml() {
XStream xstream = getXStream();
xstream.aliasField("MediaId", Music.class, "musicUrl");
xstream.aliasField("Title", Music.class, "title");
xstream.aliasField("Description", Music.class, "desc");
xstream.aliasField("HQMusicUrl", Music.class, "hqMusicUrl");
xstream.aliasField("ThumbMediaId", Music.class, "thumbMediaId");
return xstream.toXML(this);
xmlStream.aliasField("MediaId", Music.class, "musicUrl");
xmlStream.aliasField("Title", Music.class, "title");
xmlStream.aliasField("Description", Music.class, "desc");
xmlStream.aliasField("HQMusicUrl", Music.class, "hqMusicUrl");
xmlStream.aliasField("ThumbMediaId", Music.class, "thumbMediaId");
return xmlStream.toXML(this);
}
@Override

View File

@ -14,7 +14,8 @@ import com.alibaba.fastjson.annotation.JSONField;
* @author jy
* @date 2014年9月29日
* @since JDK 1.7
* @see <a href="http://mp.weixin.qq.com/wiki/index.php?title=%E6%A8%A1%E6%9D%BF%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3">模板消息</a>
* @see <a
* href="http://mp.weixin.qq.com/wiki/index.php?title=%E6%A8%A1%E6%9D%BF%E6%B6%88%E6%81%AF%E6%8E%A5%E5%8F%A3">模板消息</a>
*/
public class TemplateMessage implements Serializable {

View File

@ -19,6 +19,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class TextResponse extends BaseResponse {
private static final long serialVersionUID = -7018053906644190260L;

View File

@ -2,6 +2,7 @@ package com.foxinmy.weixin4j.mp.response;
import com.foxinmy.weixin4j.mp.type.ResponseType;
import com.foxinmy.weixin4j.msg.BaseMessage;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 转移消息到多客服端消息
@ -15,6 +16,7 @@ import com.foxinmy.weixin4j.msg.BaseMessage;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class TransferResponse extends BaseResponse {
private static final long serialVersionUID = -5479496746108594940L;

View File

@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.mp.response;
import com.foxinmy.weixin4j.mp.msg.model.Video;
import com.foxinmy.weixin4j.mp.type.ResponseType;
import com.foxinmy.weixin4j.msg.BaseMessage;
import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@ -19,6 +18,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class VideoResponse extends BaseResponse {
private static final long serialVersionUID = -1013075358679078381L;
@ -41,12 +41,11 @@ public class VideoResponse extends BaseResponse {
@Override
public String toXml() {
XStream xstream = getXStream();
xstream.aliasField("MediaId", Video.class, "mediaId");
xstream.aliasField("Title", Video.class, "title");
xstream.aliasField("Description", Video.class, "desc");
xstream.omitField(Video.class, "thumbMediaId");
return xstream.toXML(this);
xmlStream.aliasField("MediaId", Video.class, "mediaId");
xmlStream.aliasField("Title", Video.class, "title");
xmlStream.aliasField("Description", Video.class, "desc");
xmlStream.omitField(Video.class, "thumbMediaId");
return xmlStream.toXML(this);
}
@Override

View File

@ -3,7 +3,6 @@ package com.foxinmy.weixin4j.mp.response;
import com.foxinmy.weixin4j.mp.msg.model.Voice;
import com.foxinmy.weixin4j.mp.type.ResponseType;
import com.foxinmy.weixin4j.msg.BaseMessage;
import com.foxinmy.weixin4j.xml.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@ -19,6 +18,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see com.foxinmy.weixin4j.mp.response.BaseResponse
* @see com.foxinmy.weixin4j.mp.response.BaseResponse#toXml()
*/
@XStreamAlias("xml")
public class VoiceResponse extends BaseResponse {
private static final long serialVersionUID = -7944926238652243793L;
@ -42,9 +42,8 @@ public class VoiceResponse extends BaseResponse {
@Override
public String toXml() {
XStream xstream = getXStream();
xstream.aliasField("MediaId", Voice.class, "mediaId");
return xstream.toXML(this);
xmlStream.aliasField("MediaId", Voice.class, "mediaId");
return xmlStream.toXML(this);
}
@Override

View File

@ -1,5 +0,0 @@
package com.foxinmy.weixin4j.mp.spider;
public final class MpWeixin {
}

View File

@ -1,80 +1,10 @@
# app\u4fe1\u606f
app_id=wx4ab8f8de58159a57
app_secret=1d4eb0f4bf556aaed539f30ed05ca795
app_openId=gh_22b350df957b
app_token=wexintoken
# \u516c\u4f17\u53f7\u4fe1\u606f
account={"appId":"wx4ab8f8de58159a57","appSecret":"1d4eb0f4bf556aaed539f30ed05ca795",\
"token":"\u5f00\u653e\u8005\u7684token \u975e\u5fc5\u987b","openId":"\u516c\u4f17\u53f7\u7684openid \u975e\u5fc5\u987b",\
"mchId":"V3.x\u7248\u672c\u4e0b\u7684\u5fae\u4fe1\u5546\u6237\u53f7",\
"partnerId":"\u8d22\u4ed8\u901a\u7684\u5546\u6237\u53f7","partnerKey":"\u5fae\u4fe1\u652f\u4ed8\u4e2d\u8c03\u7528API\u7684\u5bc6\u94a5"}
# ----------------------------------------------------------------------------
# api\u9996\u9875
# http://mp.weixin.qq.com/wiki/index.php
# \u63a5\u53e3\u8c03\u7528\u8bf4\u660e
# http://mp.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E5%8F%A3%E9%A2%91%E7%8E%87%E9%99%90%E5%88%B6%E8%AF%B4%E6%98%8E
# ----------------------------------------------------------------------------
api_base_url=https://api.weixin.qq.com/cgi-bin
mp_base_url=https://mp.weixin.qq.com/cgi-bin
file_base_url=http://file.api.weixin.qq.com/cgi-bin
# \u7f51\u9875\u6388\u6743\u83b7\u53d6\u7528\u6237\u4fe1\u606f
user_auth_uri=https://open.weixin.qq.com/connect/oauth2/authorize?appid={app_id}&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect
sns_user_token_uri=https://api.weixin.qq.com/sns/oauth2/access_token?appid={app_id}&secret={app_secret}&code=%s&grant_type=authorization_code
sns_user_info_uri=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
# \u76f4\u63a5\u83b7\u53d6\u7528\u6237\u4fe1\u606f
api_user_info_uri={api_base_url}/user/info?access_token=%s&openid=%s&lang=zh_CN
# \u83b7\u53d6\u6211\u7684token
api_token_uri={api_base_url}/token?grant_type=client_credential&appid=%s&secret=%s
# \u83b7\u53d6\u4e8c\u7ef4\u7801
qr_ticket_uri={api_base_url}/qrcode/create?access_token=%s
qr_image_uri={mp_base_url}/showqrcode?ticket=%s
# \u4e0a\u4f20\u5a92\u4f53\u6587\u4ef6
file_upload_uri={file_base_url}/media/upload?access_token=%s&type=%s
# \u4e0b\u8f7d\u5a92\u4f53\u6587\u4ef6
file_download_uri={file_base_url}/media/get?access_token=%s&media_id=%s
# \u53d1\u9001\u5ba2\u670d\u6d88\u606f
custom_notify_uri={api_base_url}/message/custom/send?access_token=%s
# \u521b\u5efa\u5206\u7ec4
group_create_uri={api_base_url}/groups/create?access_token=%s
# \u67e5\u8be2\u5206\u7ec4
group_get_uri={api_base_url}/groups/get?access_token=%s
# \u67e5\u8be2\u7528\u6237\u6240\u5728\u5206\u7ec4
group_getid_uri={api_base_url}/groups/getid?access_token=%s
# \u4fee\u6539\u5206\u7ec4\u540d
group_modify_uri={api_base_url}/groups/update?access_token=%s
# \u79fb\u52a8\u7528\u6237\u5206\u7ec4
group_move_uri={api_base_url}/groups/members/update?access_token=%s
# \u83b7\u53d6\u5173\u6ce8\u7740
following_uri={api_base_url}/user/get?access_token=%s&next_openid=%s
# \u81ea\u5b9a\u4e49\u83dc\u5355
menu_create_uri={api_base_url}/menu/create?access_token=%s
# \u67e5\u8be2\u83dc\u5355
menu_get_uri={api_base_url}/menu/get?access_token=%s
# \u5220\u9664\u83dc\u5355
menu_delete_uri={api_base_url}/menu/delete?access_token=%s
# \u4e0a\u4f20\u56fe\u6587
article_upload_uri={api_base_url}/media/uploadnews?access_token=%s
# \u4e0a\u4f20\u89c6\u9891
video_upload_uri={file_base_url}/media/uploadvideo?access_token=%s
# \u5206\u7ec4\u7fa4\u53d1
mass_group_uri={api_base_url}/message/mass/sendall?access_token=%s
# openId\u7fa4\u53d1
mass_openid_uri={api_base_url}/message/mass/send?access_token=%s
# \u5220\u9664\u7fa4\u53d1
mass_delete_uri={api_base_url}/message/mass/delete?access_token=%s
# \u5ba2\u670d\u804a\u5929\u8bb0\u5f55
custom_record_uri={api_base_url}/customservice/getrecord?access_token=%s
# \u957f\u94fe\u63a5\u8f6c\u77ed\u94fe\u63a5
shorturl_uri={api_base_url}/shorturl?access_token=%s
# \u8bbe\u7f6e\u5907\u6ce8\u540d
updateremark_uri={api_base_url}/user/info/updateremark?access_token=%s
# \u6a21\u677f\u6d88\u606f
template_send_uri={api_base_url}/message/template/send?access_token=%s
# \u67e5\u8be2\u8ba2\u5355
orderquery_uri={api_base_url}/pay/orderquery?access_token=%s
# \u53d1\u8d27\u901a\u77e5
delivernotify_uri={api_base_url}/pay/delivernotify?access_token=%s
# token\u5b58\u653e\u8def\u5f84
# \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

View File

@ -37,7 +37,7 @@ public class GroupTest extends TokenTest {
public void get() throws WeixinException {
List<Group> groups = groupApi.getGroups();
for (Group group : groups) {
System.out.println(group);
System.out.println(group.toModifyJson());
}
Assert.assertEquals(1, groups.size());
}

View File

@ -5,8 +5,8 @@ import org.junit.Before;
import org.junit.Test;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.token.FileTokenApi;
import com.foxinmy.weixin4j.token.TokenApi;
import com.foxinmy.weixin4j.token.FileTokenHolder;
import com.foxinmy.weixin4j.token.TokenHolder;
/**
* token测试
@ -18,11 +18,11 @@ import com.foxinmy.weixin4j.token.TokenApi;
*/
public class TokenTest {
protected TokenApi tokenApi;
protected TokenHolder tokenApi;
@Before
public void setUp() {
tokenApi = new FileTokenApi();
tokenApi = new FileTokenHolder();
}
@Test

View File

@ -23,8 +23,7 @@ public class MessagePush {
public MessagePush() {
this.httpClient = new DefaultHttpClient();
ResourceBundle config = ResourceBundle
.getBundle("netty");
ResourceBundle config = ResourceBundle.getBundle("netty");
httpPost = new HttpPost();
httpPost.setURI(URI.create(String.format("http://localhost:%s",
Integer.parseInt(config.getString("port")))));
@ -37,11 +36,11 @@ public class MessagePush {
int status = statusLine.getStatusCode();
if (status != HttpStatus.SC_OK) {
throw new WeixinException(status, "request fail");
throw new WeixinException(status + "", "request fail");
}
if (status == HttpStatus.SC_MOVED_PERMANENTLY
|| status == HttpStatus.SC_MOVED_TEMPORARILY) {
throw new WeixinException(status, "uri moved");
throw new WeixinException(status + "", "uri moved");
}
return EntityUtils.toString(httpResponse.getEntity(),
StandardCharsets.UTF_8);