切分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
@@ -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;
@@ -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;
}
@@ -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;
}
@@ -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");
}
}
@@ -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());
}
@@ -0,0 +1,97 @@
<?xml version="1.0"?>
<!-- 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 -->
<errors>
<error code="-1">系统繁忙</error>
<error code="40001">获取access_token时AppSecret错误,或者access_token无效</error>
<error code="40002">不合法的凭证类型</error>
<error code="40003">不合法的OpenID</error>
<error code="40004">不合法的媒体文件类型</error>
<error code="40005">不合法的文件类型</error>
<error code="40006">不合法的文件大小</error>
<error code="40007">不合法的媒体文件id</error>
<error code="40008">不合法的消息类型</error>
<error code="40009">不合法的图片文件大小</error>
<error code="40010">不合法的语音文件大小</error>
<error code="40011">不合法的视频文件大小</error>
<error code="40012">不合法的缩略图文件大小</error>
<error code="40013">不合法的APPID</error>
<error code="40014">不合法的access_token</error>
<error code="40015">不合法的菜单类型</error>
<error code="40016">不合法的按钮个数</error>
<error code="40017">不合法的按钮个数</error>
<error code="40018">不合法的按钮名字长度</error>
<error code="40019">不合法的按钮KEY长度</error>
<error code="40020">不合法的按钮URL长度</error>
<error code="40021">不合法的菜单版本号</error>
<error code="40022">不合法的子菜单级数</error>
<error code="40023">不合法的子菜单按钮个数</error>
<error code="40024">不合法的子菜单按钮类型</error>
<error code="40025">不合法的子菜单按钮名字长度</error>
<error code="40026">不合法的子菜单按钮KEY长度</error>
<error code="40027">不合法的子菜单按钮URL长度</error>
<error code="40028">不合法的自定义菜单使用用户</error>
<error code="40029">不合法的oauth_code</error>
<error code="40030">不合法的refresh_token</error>
<error code="40031">不合法的openid列表</error>
<error code="40032">不合法的openid列表长度</error>
<error code="40033">不合法的请求字符,不能包含\uxxxx格式的字符</error>
<error code="40035">不合法的参数</error>
<error code="40038">不合法的请求格式</error>
<error code="40039">不合法的URL长度</error>
<error code="40050">不合法的分组id</error>
<error code="40051">分组名字不合法</error>
<error code="41001">缺少access_token参数</error>
<error code="41002">缺少appid参数</error>
<error code="41003">缺少refresh_token参数</error>
<error code="41004">缺少secret参数</error>
<error code="41005">缺少多媒体文件数据</error>
<error code="41006">缺少media_id参数</error>
<error code="41007">缺少子菜单数据</error>
<error code="41008">缺少oauth code</error>
<error code="41009">缺少openid</error>
<error code="42001">access_token超时</error>
<error code="42002">refresh_token超时</error>
<error code="42003">oauth_code超时</error>
<error code="43001">需要GET请求</error>
<error code="43002">需要POST请求</error>
<error code="43003">需要HTTPS请求</error>
<error code="43004">需要接收者关注</error>
<error code="43005">需要好友关系</error>
<error code="44001">多媒体文件为空</error>
<error code="44002">POST的数据包为空</error>
<error code="44003">图文消息内容为空</error>
<error code="44004">文本消息内容为空</error>
<error code="45001">多媒体文件大小超过限制</error>
<error code="45002">消息内容超过限制</error>
<error code="45003">标题字段超过限制</error>
<error code="45004">描述字段超过限制</error>
<error code="45005">链接字段超过限制</error>
<error code="45006">图片链接字段超过限制</error>
<error code="45007">语音播放时间超过限制</error>
<error code="45008">图文消息超过限制</error>
<error code="45009">接口调用超过限制</error>
<error code="45010">创建菜单个数超过限制</error>
<error code="45015">回复时间超过限制</error>
<error code="45016">系统分组,不允许修改</error>
<error code="45017">分组名字过长</error>
<error code="45018">分组数量超过上限</error>
<error code="46001">不存在媒体数据</error>
<error code="46002">不存在的菜单版本</error>
<error code="46003">不存在的菜单数据</error>
<error code="46004">不存在的用户</error>
<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>
@@ -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() + "]";
}
}
@@ -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() + "]";
}
}
@@ -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() + "]";
}
}
@@ -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 + "]";
}
}
@@ -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);
}
/**
@@ -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");
}
}
@@ -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();
}
}
@@ -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");
}
}
@@ -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());
@@ -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;
}
@@ -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) {
@@ -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);
@@ -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();
}
}
}
@@ -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;
}
}