大重构:weixin4j精简为weixin4j-base、weixin4j-mp、weixin4j-qy、weixin4j-server四个子工程。

This commit is contained in:
jinyu
2015-04-27 21:00:33 +08:00
parent e89e988c62
commit 69c9bdffa4
349 changed files with 450 additions and 27394 deletions
@@ -1,46 +0,0 @@
package com.foxinmy.weixin4j.action;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.dom4j.DocumentException;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.response.ResponseMessage;
import com.foxinmy.weixin4j.util.MessageUtil;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 继承的类需实现execute(M inMessage)
*
* @className AbstractAction
* @author jy
* @date 2014年10月12日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.action.WeixinAction
*/
@SuppressWarnings("unchecked")
public abstract class AbstractAction<M extends BaseMsg> implements WeixinAction {
public abstract ResponseMessage execute(M inMessage);
@Override
public ResponseMessage execute(String msg) throws DocumentException {
BaseMsg message = MessageUtil.xml2msg(msg);
if (message == null) {
return execute(XmlStream.get(msg, getGenericType()));
}
return execute((M) message);
}
private Class<M> getGenericType() {
Class<M> clazz = null;
Type type = getClass().getGenericSuperclass();
if (type instanceof ParameterizedType) {
ParameterizedType ptype = ((ParameterizedType) type);
Type[] args = ptype.getActualTypeArguments();
clazz = (Class<M>) args[0];
}
return clazz;
}
}
@@ -1,21 +0,0 @@
package com.foxinmy.weixin4j.action;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.response.ResponseMessage;
/**
* 回复一个空字符串 而不是一个XML结构体中content字段的内容为空
*
* @className BlankAction
* @author jy.hu
* @date 2014年10月2日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.action.AbstractAction
*/
public class BlankAction<M extends BaseMsg> extends AbstractAction<M> {
@Override
public ResponseMessage execute(M inMessage) {
return null;
}
}
@@ -1,22 +0,0 @@
package com.foxinmy.weixin4j.action;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.msg.model.Text;
import com.foxinmy.weixin4j.response.ResponseMessage;
/**
* 调试输出用户消息
*
* @className DebugAction
* @author jy
* @date 2014年10月8日
* @since JDK 1.7
* @see
*/
public class DebugAction<M extends BaseMsg> extends AbstractAction<M> {
@Override
public ResponseMessage execute(M message) {
return new ResponseMessage(new Text(message.toString()), message);
}
}
@@ -1,3 +0,0 @@
消息处理接口,与weixin4j-*-server配合使用
如果单纯只使用API包,则可以不关注
@@ -1,20 +0,0 @@
package com.foxinmy.weixin4j.action;
import org.dom4j.DocumentException;
import com.foxinmy.weixin4j.response.ResponseMessage;
/**
* 消息处理接口
*
* @className Action
* @author jy.hu
* @date 2014年10月2日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.action.AbstractAction
* @see com.foxinmy.weixin4j.action.BlankAction
* @see com.foxinmy.weixin4j.action.DebugAction
*/
public interface WeixinAction {
public ResponseMessage execute(String inMsg) throws DocumentException;
}
@@ -1,31 +0,0 @@
package com.foxinmy.weixin4j.action.mapping;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import com.foxinmy.weixin4j.type.MessageType;
/**
* 获取默认的Mapping Key 如text,event_click
*
* @className AbstractActionMapping
* @author jy
* @date 2014年10月28日
* @since JDK 1.7
* @see
*/
public abstract class AbstractActionMapping implements ActionMapping {
protected final static String DECOLLATOR = ":";
protected String getMappingKey(String xmlMsg) throws DocumentException {
Document doc = DocumentHelper.parseText(xmlMsg);
String msgType = doc.selectSingleNode("/xml/MsgType").getStringValue();
if (msgType.equalsIgnoreCase(MessageType.event.name())) {
msgType += DECOLLATOR
+ doc.selectSingleNode("/xml/Event").getStringValue();
}
return msgType.toLowerCase();
}
}
@@ -1,26 +0,0 @@
package com.foxinmy.weixin4j.action.mapping;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.foxinmy.weixin4j.type.EventType;
import com.foxinmy.weixin4j.type.MessageType;
/**
* 标注Action类来处理消息请求
* @className Action
* @author jy
* @date 2014年10月12日
* @since JDK 1.7
* @see
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ActionAnnotation {
MessageType msgType();
EventType[] eventType() default {};
}
@@ -1,18 +0,0 @@
package com.foxinmy.weixin4j.action.mapping;
import org.dom4j.DocumentException;
import com.foxinmy.weixin4j.action.WeixinAction;
/**
* 可扩展的Mapping接口
*
* @className ActionMapping
* @author jy
* @date 2014年10月28日
* @since JDK 1.7
* @see
*/
public interface ActionMapping {
public WeixinAction getAction(String xmlMsg) throws DocumentException;
}
@@ -1,58 +0,0 @@
package com.foxinmy.weixin4j.action.mapping;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.dom4j.DocumentException;
import com.foxinmy.weixin4j.action.WeixinAction;
import com.foxinmy.weixin4j.type.EventType;
import com.foxinmy.weixin4j.type.MessageType;
import com.foxinmy.weixin4j.util.ClassUtil;
/**
* 注解实现的Mapping
*
* @className AnnotationActionMapping
* @author jy
* @date 2014年10月28日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.action.mapping.ActionAnnotation
*/
public class AnnotationActionMapping extends AbstractActionMapping {
private final Map<String, WeixinAction> actionMap;
public AnnotationActionMapping(Package actionPackage) {
actionMap = new HashMap<String, WeixinAction>();
Set<Class<?>> weixinActions = ClassUtil.getClasses(actionPackage);
for (Class<?> clazz : weixinActions) {
ActionAnnotation action = clazz
.getAnnotation(ActionAnnotation.class);
if (action == null) {
continue;
}
WeixinAction weixinAction = null;
try {
weixinAction = (WeixinAction) clazz.newInstance();
} catch (Exception e) {
continue;
}
MessageType msgType = action.msgType();
EventType[] eventTypes = action.eventType();
if (eventTypes != null && eventTypes.length > 0) {
for (EventType e : eventTypes) {
actionMap.put((msgType.name() + DECOLLATOR + e.name())
.toLowerCase(), weixinAction);
}
continue;
}
actionMap.put(msgType.name().toLowerCase(), weixinAction);
}
}
public WeixinAction getAction(String xmlMsg) throws DocumentException {
String key = getMappingKey(xmlMsg);
return actionMap.get(key);
}
}
@@ -1,7 +0,0 @@
消息处理与Action类的mapping对应(使用注解类的方式)
一般来说Action中应该有自己的实际业务处理类,那么上述方式可能不妥
推荐用org.springframework.context.ApplicationContext#getBeansWithAnnotation函数
当然,也可以重写AbstractActionMapping类实现自己的Mapping
@@ -297,6 +297,26 @@
<code>40074</code>
<text>news消息不支持指定为高保密消息</text>
</error>
<error>
<code>40117</code>
<text>分组名字不合法</text>
</error>
<error>
<code>40118</code>
<text>media_id大小不合法</text>
</error>
<error>
<code>40119</code>
<text>button类型错误</text>
</error>
<error>
<code>40120</code>
<text>button类型错误</text>
</error>
<error>
<code>40121</code>
<text>不合法的media_id类型</text>
</error>
<error>
<code>41001</code>
<desc>access_token missing</desc>
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.model;
package com.foxinmy.weixin4j.message;
import java.io.Serializable;
@@ -7,12 +7,12 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 消息基类
*
* @className BaseMsg
* @className BaseMessage
* @author jy.hu
* @date 2014年4月6日
* @since JDK 1.7
*/
public class BaseMsg implements Serializable {
public class BaseMessage implements Serializable {
private static final long serialVersionUID = 7761192742840031607L;
@@ -49,19 +49,19 @@ public class BaseMsg implements Serializable {
@XStreamAlias("AgentID")
private String agentId;
public BaseMsg() {
public BaseMessage() {
}
public BaseMsg(String msgType) {
public BaseMessage(String msgType) {
this.msgType = msgType;
}
public BaseMsg(String toUserName, String fromUserName) {
public BaseMessage(String toUserName, String fromUserName) {
this(null, toUserName, fromUserName);
}
public BaseMsg(String msgType, String toUserName, String fromUserName) {
public BaseMessage(String msgType, String toUserName, String fromUserName) {
this.msgType = msgType;
this.toUserName = toUserName;
this.fromUserName = fromUserName;
@@ -124,8 +124,9 @@ public class BaseMsg implements Serializable {
@Override
public boolean equals(Object obj) {
if (obj instanceof BaseMsg) {
return ((BaseMsg) obj).getMsgId() == msgId;
if (obj instanceof BaseMessage) {
return ((BaseMessage) obj).getMsgId() == msgId
&& ((BaseMessage) obj).getCreateTime() == createTime;
}
return false;
}
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg;
package com.foxinmy.weixin4j.message;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF#image.E6.B6.88.E6.81.AF">企业号的图片消息</a>
*/
public class ImageMessage extends BaseMsg {
public class ImageMessage extends BaseMessage {
private static final long serialVersionUID = 8430800898756567016L;
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg;
package com.foxinmy.weixin4j.message;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -14,7 +13,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html#.E9.93.BE.E6.8E.A5.E6.B6.88.E6.81.AF">订阅号服务号的链接消息</a>
*/
public class LinkMessage extends BaseMsg {
public class LinkMessage extends BaseMessage {
private static final long serialVersionUID = 754952745115497030L;
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg;
package com.foxinmy.weixin4j.message;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF#location.E6.B6.88.E6.81.AF">企业号的地理位置消息</a>
*/
public class LocationMessage extends BaseMsg {
public class LocationMessage extends BaseMessage {
private static final long serialVersionUID = 2866021596599237334L;
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg;
package com.foxinmy.weixin4j.message;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF#text.E6.B6.88.E6.81.AF">企业号的文本消息</a>
*/
public class TextMessage extends BaseMsg {
public class TextMessage extends BaseMessage {
private static final long serialVersionUID = -7018053906644190260L;
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg;
package com.foxinmy.weixin4j.message;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -16,7 +15,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF#video.E6.B6.88.E6.81.AF">企业号的视频消息</a>
*/
public class VideoMessage extends BaseMsg {
public class VideoMessage extends BaseMessage {
private static final long serialVersionUID = -1013075358679078381L;
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg;
package com.foxinmy.weixin4j.message;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -19,7 +18,7 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E6%99%AE%E9%80%9A%E6%B6%88%E6%81%AF#voice.E6.B6.88.E6.81.AF">企业号的语音消息</a>
*/
public class VoiceMessage extends BaseMsg {
public class VoiceMessage extends BaseMessage {
private static final long serialVersionUID = -7988380977182214003L;
@@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.event;
package com.foxinmy.weixin4j.message.event;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.type.EventType;
import com.foxinmy.weixin4j.message.BaseMessage;
import com.foxinmy.weixin4j.type.MessageType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -17,11 +16,11 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E4%BA%8B%E4%BB%B6">企业号的事件消息</a>
*/
public class EventMessage extends BaseMsg {
public class EventMessage extends BaseMessage {
private static final long serialVersionUID = 7703667223814088865L;
public EventMessage(EventType eventType) {
public EventMessage(String eventType) {
super(MessageType.event.name());
this.eventType = eventType;
}
@@ -32,9 +31,9 @@ public class EventMessage extends BaseMsg {
* @see com.foxinmy.weixin4j.type.EventType
*/
@XStreamAlias("Event")
private EventType eventType;
private String eventType;
public EventType getEventType() {
public String getEventType() {
return eventType;
}
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg.event;
package com.foxinmy.weixin4j.message.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -20,7 +20,7 @@ public class LocationEventMessage extends EventMessage {
private static final long serialVersionUID = -2030716800669824861L;
public LocationEventMessage() {
super(EventType.location);
super(EventType.location.name());
}
/**
* 地理位置纬度
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg.event.menu;
package com.foxinmy.weixin4j.message.event;
import com.foxinmy.weixin4j.msg.event.EventMessage;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
@@ -21,11 +20,11 @@ public class MenuEventMessage extends EventMessage {
private static final long serialVersionUID = -1049672447995366063L;
public MenuEventMessage() {
super(EventType.click);
super(EventType.click.name());
}
public MenuEventMessage(EventType eventType) {
super(eventType);
super(eventType.name());
}
/**
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg.event.menu;
package com.foxinmy.weixin4j.message.event;
import java.io.Serializable;
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg.event.menu;
package com.foxinmy.weixin4j.message.event;
import java.io.Serializable;
import java.util.List;
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg.event.menu;
package com.foxinmy.weixin4j.message.event;
import java.io.Serializable;
@@ -1,3 +1,3 @@
菜单消息
菜单事件消息
用户点击自定义菜单后,微信会把点击事件推送给开发者,请注意,点击菜单弹出子菜单,不会产生上报。请注意,第3个到第8个的所有事件,仅支持微信iPhone5.4.1以上版本,和Android5.4以上版本的微信用户,旧版本微信用户点击后将没有回应,开发者也不能正常接收到事件推送。
@@ -25,10 +25,6 @@ public final class Consts {
public static final String PROTOCOL_FILE = "file";
public static final String PROTOCOL_JAR = "jar";
/**
* oauth验证url
*/
public static final String OAUTH_AUTHORIZE_URL = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
/**
* 公众平台获取token的url
*/
@@ -1,12 +1,6 @@
package com.foxinmy.weixin4j.model;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.commons.lang3.StringUtils;
import com.foxinmy.weixin4j.type.AccountType;
/**
* 微信账号信息
@@ -17,7 +11,7 @@ import com.foxinmy.weixin4j.type.AccountType;
* @since JDK 1.7
* @see
*/
public abstract class WeixinAccount implements Serializable {
public class WeixinAccount implements Serializable {
private static final long serialVersionUID = -6001008896414323534L;
/**
@@ -33,11 +27,6 @@ public abstract class WeixinAccount implements Serializable {
* 安全模式下的加密密钥
*/
private String encodingAesKey;
/**
* 账号类型
* @return
*/
public abstract AccountType getAccountType();
public WeixinAccount() {
}
@@ -79,39 +68,6 @@ public abstract class WeixinAccount implements Serializable {
this.encodingAesKey = encodingAesKey;
}
/**
* 拼接授权URL
*
* @param redirectUri
* 授权后重定向的回调链接地址
* @param scope
* 应用授权作用域,snsapi_base
* (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo
* (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息)
* @param state
* 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值
* @return 授权URL
*/
public String getOauthAuthorizeUrl(String redirectUri, String scope,
String state) {
if (StringUtils.isBlank(scope)) {
scope = "snsapi_base";
}
if (StringUtils.isBlank(state)) {
state = "STATE";
}
try {
return String.format(
Consts.OAUTH_AUTHORIZE_URL,
URLEncoder.encode(redirectUri,
org.apache.http.Consts.UTF_8.name()), id, scope,
state);
} catch (UnsupportedEncodingException ignore) {
;
}
return "";
}
@Override
public String toString() {
return "id=" + id + ", secret=" + secret + ", token=" + token
@@ -1,176 +0,0 @@
package com.foxinmy.weixin4j.model;
import org.apache.commons.lang3.StringUtils;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.AccountType;
/**
* 微信公众平台信息
*
* @className WeixinMpAccount
* @author jy
* @date 2014年8月17日
* @since JDK 1.7
* @see <a href=
* "https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=836970804&lang=zh_CN"
* >开发者模式</a>
*/
public class WeixinMpAccount extends WeixinAccount {
private static final long serialVersionUID = 3689999353867189585L;
/**
* 支付场景下为用户的openid 其余情况可能是公众号的原始ID
*/
private String openId;
/**
* 公众号支付请求中用于加密的密钥 Key,可验证商户唯一身份,PaySignKey 对应于支付场景中的 appKey 值
*/
private String paySignKey;
/**
* 财付通商户身份的标识
*/
private String partnerId;
/**
* 财付通商户权限密钥Key
*/
private String partnerKey;
/**
* 微信支付分配的商户号(商户平台版)
*/
private String mchId;
/**
* 微信支付分配的子商户号,受理模式下必填(商户平台版)
*/
private String subMchId;
/**
* 微信支付分配的设备号(商户平台版)
*/
private String deviceInfo;
/**
* 微信支付版本号(如果无则按照mchId来做判断)
*/
private int version;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getPaySignKey() {
return paySignKey;
}
public void setPaySignKey(String paySignKey) {
this.paySignKey = paySignKey;
}
public String getPartnerId() {
return partnerId;
}
public void setPartnerId(String partnerId) {
this.partnerId = partnerId;
}
public String getPartnerKey() {
return partnerKey;
}
public void setPartnerKey(String partnerKey) {
this.partnerKey = partnerKey;
}
public String getMchId() {
return mchId;
}
public void setMchId(String mchId) {
this.mchId = mchId;
}
public String getDeviceInfo() {
return deviceInfo;
}
public void setDeviceInfo(String deviceInfo) {
this.deviceInfo = deviceInfo;
}
public int getVersion() {
if (version == 0) {
return StringUtils.isNotBlank(mchId) ? 3 : 2;
}
return version;
}
public void setVersion(int version) {
this.version = version;
}
public String getSubMchId() {
return subMchId;
}
public void setSubMchId(String subMchId) {
this.subMchId = subMchId;
}
public WeixinMpAccount() {
}
public WeixinMpAccount(String appId, String appSecret) {
super(appId, appSecret);
}
/**
* 商户平台版本(V3)字段
*
* @param appId 公众号唯一的身份ID
* @param appSecret 调用接口的凭证
* @param paySignKey 支付密钥字符串
* @param mchId 微信支付分配的商户号
*/
public WeixinMpAccount(String appId, String appSecret, String paySignKey,
String mchId) {
this(appId, appSecret);
this.paySignKey = paySignKey;
this.mchId = mchId;
}
/**
* V2版本字段
*
* @param appId 公众号唯一的身份ID
* @param appSecret 调用接口的凭证
* @param paySignKey 支付密钥字符串
* @param partnerId 财付通账号的ID
* @param partnerKey 财付通账号的key
*/
public WeixinMpAccount(String appId, String appSecret, String paySignKey,
String partnerId, String partnerKey) {
this(appId, appSecret);
this.paySignKey = paySignKey;
this.partnerId = partnerId;
this.partnerKey = partnerKey;
}
@Override
@JSONField(deserialize = false)
public AccountType getAccountType() {
return AccountType.MP;
}
@Override
public String toString() {
return "WeixinMpAccount [openId=" + openId + ", paySignKey="
+ paySignKey + ", partnerId=" + partnerId + ", partnerKey="
+ partnerKey + ", mchId=" + mchId + ", deviceInfo="
+ deviceInfo + ", version=" + version + ", " + super.toString()
+ "]";
}
}
@@ -1,44 +0,0 @@
package com.foxinmy.weixin4j.model;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.AccountType;
/**
* 微信企业号信息
*
* @className WeixinQyAccount
* @author jy
* @date 2014年11月18日
* @since JDK 1.7
* @see <a href=
* "https://qy.weixin.qq.com/cgi-bin/home?lang=zh_CN&token=685923034#setting"
* >企业号设置</a>
*/
public class WeixinQyAccount extends WeixinAccount {
private static final long serialVersionUID = 3689999353867189585L;
public WeixinQyAccount() {
}
/**
*
* @param corpid
* 企业ID
* @param corpsecret
* 管理组的凭证密钥
*/
public WeixinQyAccount(String corpid, String corpsecret) {
super(corpid, corpsecret);
}
@Override
@JSONField(deserialize = false)
public AccountType getAccountType() {
return AccountType.QY;
}
@Override
public String toString() {
return "WeixinQyAccount [" + super.toString() + "]";
}
}
@@ -1,99 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import java.io.Serializable;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 异步任务事件完成通知
*
* @className BatchjobresultMessage
* @author jy
* @date 2015年3月31日
* @since JDK 1.7
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E4%BA%8B%E4%BB%B6#.E5.BC.82.E6.AD.A5.E4.BB.BB.E5.8A.A1.E5.AE.8C.E6.88.90.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81">异步任务事件完成通知</a>
*/
public class BatchjobresultMessage extends EventMessage {
private static final long serialVersionUID = 8014540441322209657L;
public BatchjobresultMessage() {
super(EventType.batch_job_result);
}
/**
* 任务信息
*/
@XStreamAlias("BatchJob")
private BatchJob batchJob;
public BatchJob getBatchJob() {
return batchJob;
}
/**
* 任务信息
*
* @className BatchJob
* @author jy
* @date 2015年4月1日
* @since JDK 1.7
* @see
*/
public static class BatchJob implements Serializable {
private static final long serialVersionUID = -7520032656787156391L;
/**
* 异步任务id,最大长度为64字符
*/
@XStreamAlias("JobId")
private String jobId;
/**
* 操作类型,字符串,目前分别有: 1. sync_user(增量更新成员) 2. replace_user(全量覆盖成员) 3.
* invite_user(邀请成员关注) 4. replace_party(全量覆盖部门)
*
* @see com.foxinmy.weixin4j.qy.type.BatchType
*/
@XStreamAlias("JobType")
private String jobType;
/**
* 返回码
*/
@XStreamAlias("ErrCode")
private String ErrCode;
/**
* 对返回码的文本描述内容
*/
@XStreamAlias("ErrMsg")
private String errMsg;
public String getJobId() {
return jobId;
}
public String getJobType() {
return jobType;
}
public String getErrCode() {
return ErrCode;
}
public String getErrMsg() {
return errMsg;
}
@Override
public String toString() {
return "[jobId=" + jobId + ", jobType=" + jobType + ", ErrCode="
+ ErrCode + ", errMsg=" + errMsg + "]";
}
}
@Override
public String toString() {
return "BatchjobresultMessage [batchJob=" + batchJob + ", "
+ super.toString() + "]";
}
}
@@ -1,40 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 用户进入应用的事件推送(企业号)本事件只有在应用的回调模式中打开上报开关时上报
*
* @className EnterAgentEventMessage
* @author jy
* @date 2014年12月28日
* @since JDK 1.7
* @see <a href=
* "http://qydev.weixin.qq.com/wiki/index.php?title=%E6%8E%A5%E6%94%B6%E4%BA%8B%E4%BB%B6#.E7.94.A8.E6.88.B7.E8.BF.9B.E5.85.A5.E5.BA.94.E7.94.A8.E7.9A.84.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81"
* >用户进入应用的事件推送</a>
*/
public class EnterAgentEventMessage extends EventMessage {
private static final long serialVersionUID = 7675732524832500820L;
public EnterAgentEventMessage() {
super(EventType.enter_agent);
}
/**
* 事件KEY值,与自定义菜单接口中KEY值对应
*/
@XStreamAlias("EventKey")
private String eventKey;
public String getEventKey() {
return eventKey;
}
@Override
public String toString() {
return "EnterAgentEventMessage [eventKey=" + eventKey + ", "
+ super.toString() + "]";
}
}
@@ -1,39 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 客服关闭会话事件
*
* @className KfCloseEventMessage
* @author jy
* @date 2015年3月22日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/2/6c20f3e323bdf5986cfcb33cbd3b829a.html#.E4.BC.9A.E8.AF.9D.E7.8A.B6.E6.80.81.E9.80.9A.E7.9F.A5.E4.BA.8B.E4.BB.B6">会话状态通知事件</a>
*/
public class KfCloseEventMessage extends EventMessage {
private static final long serialVersionUID = 3644449346935205541L;
public KfCloseEventMessage() {
super(EventType.kf_close_session);
}
/**
* 客服账号
*/
@XStreamAlias("KfAccount")
private String kfAccount;
public String getKfAccount() {
return kfAccount;
}
@Override
public String toString() {
return "KfCloseEventMessage [kfAccount=" + kfAccount + ", ="
+ super.toString() + "]";
}
}
@@ -1,39 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 客服接入会话事件
*
* @className KfCreateEventMessage
* @author jy
* @date 2015年3月22日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/2/6c20f3e323bdf5986cfcb33cbd3b829a.html#.E4.BC.9A.E8.AF.9D.E7.8A.B6.E6.80.81.E9.80.9A.E7.9F.A5.E4.BA.8B.E4.BB.B6">会话状态通知事件</a>
*/
public class KfCreateEventMessage extends EventMessage {
private static final long serialVersionUID = -8968189700999202108L;
public KfCreateEventMessage() {
super(EventType.kf_create_session);
}
/**
* 客服账号
*/
@XStreamAlias("KfAccount")
private String kfAccount;
public String getKfAccount() {
return kfAccount;
}
@Override
public String toString() {
return "KfCreateEventMessage [kfAccount=" + kfAccount + ", ="
+ super.toString() + "]";
}
}
@@ -1,47 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 客服转接会话事件
*
* @className KfSwitchEventMessage
* @author jy
* @date 2015年3月22日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/2/6c20f3e323bdf5986cfcb33cbd3b829a.html#.E4.BC.9A.E8.AF.9D.E7.8A.B6.E6.80.81.E9.80.9A.E7.9F.A5.E4.BA.8B.E4.BB.B6">会话状态通知事件</a>
*/
public class KfSwitchEventMessage extends EventMessage {
private static final long serialVersionUID = 4319501074109623413L;
public KfSwitchEventMessage() {
super(EventType.kf_switch_session);
}
/**
* 来自的客服账号
*/
@XStreamAlias("FromKfAccount")
private String fromKfAccount;
/**
* 转移给客服账号
*/
@XStreamAlias("ToKfAccount")
private String toKfAccount;
public String getFromKfAccount() {
return fromKfAccount;
}
public String getToKfAccount() {
return toKfAccount;
}
@Override
public String toString() {
return "KfSwitchEventMessage [fromKfAccount=" + fromKfAccount
+ ", toKfAccount=" + toKfAccount + "]";
}
}
@@ -1,128 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import java.util.HashMap;
import java.util.Map;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* 群发消息事件推送
*
* @className MassEventMessage
* @author jy
* @date 2014年4月27日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html#.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81.E7.BE.A4.E5.8F.91.E7.BB.93.E6.9E.9C">群发回调</a>
*/
public class MassEventMessage extends EventMessage {
private static final long serialVersionUID = -1660543255873723895L;
public MassEventMessage() {
super(EventType.masssendjobfinish);
}
/**
* 群发后的状态信息 为“send success”或“send fail”或“err(num)
*/
@XStreamAlias("Status")
private String status;
/**
* group_id下粉丝数;或者openid_list中的粉丝数
*/
@XStreamAlias("TotalCount")
private int totalCount;
/**
* 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,FilterCount =
* SentCount + ErrorCount
*/
@XStreamAlias("FilterCount")
private int filterCount;
/**
* 发送成功的粉丝数
*/
@XStreamAlias("SentCount")
private int sentCount;
/**
* 发送失败的粉丝数
*/
@XStreamAlias("ErrorCount")
private int errorCount;
@XStreamOmitField
private final static Map<String, String> statusMap;
static {
statusMap = new HashMap<String, String>();
statusMap.put("sendsuccess", "发送成功");
statusMap.put("send_success", "发送成功");
statusMap.put("success", "发送成功");
statusMap.put("send success", "发送成功");
statusMap.put("sendfail", "发送失败");
statusMap.put("send_fail", "发送失败");
statusMap.put("fail", "发送失败");
statusMap.put("send fail", "发送失败");
statusMap.put("err(10001)", "涉嫌广告");
statusMap.put("err(20001)", "涉嫌政治");
statusMap.put("err(20004)", "涉嫌社会");
statusMap.put("err(20006)", "涉嫌违法犯罪");
statusMap.put("err(20008)", "涉嫌欺诈");
statusMap.put("err(20013)", "涉嫌版权");
statusMap.put("err(22000)", "涉嫌互推(互相宣传)");
statusMap.put("err(21000)", "涉嫌其他");
}
public String getStatus() {
return status;
}
/**
* 发送状态描述</br> err(10001,涉嫌广告) err(20001,涉嫌政治) err(20004,涉嫌社会)</br>
* err(20002,涉嫌色情) err(20006,涉嫌违法犯罪) err(20008,涉嫌欺诈)</br> err(20013,涉嫌版权)
* err(22000,涉嫌互推(互相宣传) err(21000,涉嫌其他)
*
* @param status
* @return 中文描述
*/
public String getStatusDesc() {
return statusMap.get(status.toLowerCase());
}
/**
* 发送状态描述</br> err(10001,涉嫌广告) err(20001,涉嫌政治) err(20004,涉嫌社会)</br>
* err(20002,涉嫌色情) err(20006,涉嫌违法犯罪) err(20008,涉嫌欺诈)</br> err(20013,涉嫌版权)
* err(22000,涉嫌互推(互相宣传) err(21000,涉嫌其他)
*
* @param status
* @return 中文描述
*/
public static String getStatusDesc(String status) {
return statusMap.get(status.toLowerCase());
}
public int getTotalCount() {
return totalCount;
}
public int getFilterCount() {
return filterCount;
}
public int getSentCount() {
return sentCount;
}
public int getErrorCount() {
return errorCount;
}
@Override
public String toString() {
return "MassEventMessage [status=" + getStatusDesc() + ", totalCount="
+ totalCount + ", filterCount=" + filterCount + ", sentCount="
+ sentCount + ", errorCount=" + errorCount + ", "
+ super.toString() + "]";
}
}
@@ -1,10 +0,0 @@
事件消息
-------
当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。各消息类型的推送XML数据包结构如下:
微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
关于重试的消息排重,推荐使用msgid排重。
假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。
@@ -1,56 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 扫描二维码事件
*
* @className ScanEventMessage
* @author jy.hu
* @date 2014年4月6日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html#.E6.89.AB.E6.8F.8F.E5.B8.A6.E5.8F.82.E6.95.B0.E4.BA.8C.E7.BB.B4.E7.A0.81.E4.BA.8B.E4.BB.B6">扫描二维码事件</a>
*/
public class ScanEventMessage extends EventMessage {
private static final long serialVersionUID = 8078674062833071562L;
public ScanEventMessage() {
super(EventType.scan);
}
public ScanEventMessage(EventType eventType) {
super(eventType);
}
/**
* 事件KEY值,是一个32位无符号整数,即创建二维码时的二维码scene_id
*/
@XStreamAlias("EventKey")
private String eventKey;
/**
* 二维码的ticket,可用来换取二维码图片
*/
@XStreamAlias("Ticket")
private String ticket;
public String getEventKey() {
return eventKey;
}
public String getTicket() {
return ticket;
}
public String getParameter() {
return eventKey.replace("qrscene_", "");
}
@Override
public String toString() {
return "ScanEventMessage [eventKey=" + eventKey + ", ticket=" + ticket
+ ", " + super.toString() + "]";
}
}
@@ -1,31 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
/**
* 关注/取消关注事件</br> <font color="red">包括直接关注与扫描关注</font>
*
* @className ScribeEventMessage
* @author jy.hu
* @date 2014年4月6日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html#.E5.85.B3.E6.B3.A8.2F.E5.8F.96.E6.B6.88.E5.85.B3.E6.B3.A8.E4.BA.8B.E4.BB.B6">订阅号、服务号的关注/取消关注事件</a>
* @see <a href="http://qydev.weixin.qq.com/wiki/index.php?title=%
* E5%85%B3%E6%B3%A8%E4%B8%
* 8E%E5%8F%96%E6%B6%88%E5%85%B3%E6%B3%A8#.E5.85.B3.E6.B3.A8.2F.E5.8F.96.E6.B6.88.E5.85.B3.E6.B3.A8.E4.BA.8B.E4.BB.B6.E7.9A.84.E6.8E.A8.E9.80.81">企业号的关注/取消关注
* 事 件 </a>
*/
public class ScribeEventMessage extends ScanEventMessage {
private static final long serialVersionUID = -6846321620262204915L;
public ScribeEventMessage() {
super(EventType.subscribe);
}
@Override
public String toString() {
return "ScribeEventMessage [" + super.toString() + "]";
}
}
@@ -1,39 +0,0 @@
package com.foxinmy.weixin4j.msg.event;
import com.foxinmy.weixin4j.type.EventType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 模板消息事件推送(公众平台)
*
* @className TemplatesendjobfinishMessage
* @author jy
* @date 2014年9月19日
* @since JDK 1.7
* @see <a
* href="http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html#.E4.BA.8B.E4.BB.B6.E6.8E.A8.E9.80.81">模板消息事件推送</a>
*/
public class TemplatesendjobfinishMessage extends EventMessage {
private static final long serialVersionUID = -2903359365988594012L;
public TemplatesendjobfinishMessage() {
super(EventType.templatesendjobfinish);
}
/**
* 推送状态 如failed: system failed
*/
@XStreamAlias("Status")
private String status;
public String getStatus() {
return status;
}
@Override
public String toString() {
return "TemplatesendjobfinishMessage [status=" + status + ", "
+ super.toString() + "]";
}
}
@@ -1,41 +0,0 @@
package com.foxinmy.weixin4j.msg.model;
import java.io.Serializable;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
/**
* 消息对象基类
*
* @className Base
* @author jy
* @date 2015年3月21日
* @since JDK 1.7
* @see
*/
public class Base implements Serializable {
private static final long serialVersionUID = 8487251213352068227L;
/**
* 媒体类型
*/
@JSONField(serialize = false)
@XStreamOmitField
private MediaType mediaType;
public Base(MediaType mediaType) {
this.mediaType = mediaType;
}
public MediaType getMediaType() {
return mediaType;
}
@Override
public String toString() {
return "Base [mediaType=" + mediaType + "]";
}
}
@@ -1,18 +0,0 @@
package com.foxinmy.weixin4j.msg.model;
/**
* 标记群发消息
*
* @className Massable
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.msg.model.Text
* @see com.foxinmy.weixin4j.msg.model.Image
* @see com.foxinmy.weixin4j.msg.model.Voice
* @see com.foxinmy.weixin4j.msg.model.MpVideo
* @see com.foxinmy.weixin4j.msg.model.MpNews
*/
public interface Massable {
}
@@ -1,19 +0,0 @@
package com.foxinmy.weixin4j.msg.model;
/**
* 标记客服消息
*
* @className Notifyable
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.msg.model.Text
* @see com.foxinmy.weixin4j.msg.model.Image
* @see com.foxinmy.weixin4j.msg.model.Voice
* @see com.foxinmy.weixin4j.msg.model.Video
* @see com.foxinmy.weixin4j.msg.model.Music
* @see com.foxinmy.weixin4j.msg.model.News
*/
public interface Notifyable {
}
@@ -1,20 +0,0 @@
package com.foxinmy.weixin4j.msg.model;
/**
* 标记被动消息
*
* @className Responseable
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.msg.model.Text
* @see com.foxinmy.weixin4j.msg.model.Image
* @see com.foxinmy.weixin4j.msg.model.Voice
* @see com.foxinmy.weixin4j.msg.model.Video
* @see com.foxinmy.weixin4j.msg.model.Music
* @see com.foxinmy.weixin4j.msg.model.News
* @see com.foxinmy.weixin4j.msg.model.Trans
*/
public interface Responseable {
}
@@ -1,158 +0,0 @@
package com.foxinmy.weixin4j.response;
import java.io.Serializable;
import com.foxinmy.weixin4j.type.EncryptType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 微信的被动消息
*
* @className HttpWeixinMessage
* @author jy
* @date 2015年3月29日
* @since JDK 1.7
* @see
*/
@XStreamAlias("xml")
public class HttpWeixinMessage implements Serializable {
private static final long serialVersionUID = -9157395300510879866L;
// 以下字段是加密方式为「安全模式」时的参数
/**
* 公众号的唯一ID
*/
@XStreamAlias("ToUserName")
private String toUserName;
/**
* 加密后的内容
*/
@XStreamAlias("Encrypt")
private String encryptContent;
/**
* 加密类型
*
* @see com.foxinmy.weixin4j.type.EncryptType
*/
private EncryptType encryptType;
// 以下字段每次被动消息时都会带上
/**
* 随机字符串
*/
private String echoStr;
/**
* 时间戳
*/
private String timeStamp;
/**
* 随机数
*/
private String nonce;
/**
* 参数签名
*/
private String signature;
/**
* 设置的token
*/
private String token;
/**
* xml消息明文主体
*/
private String originalContent;
/**
* 请求的方式
*/
private String method;
public String getToUserName() {
return toUserName;
}
public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}
public String getEncryptContent() {
return encryptContent;
}
public void setEncryptContent(String encryptContent) {
this.encryptContent = encryptContent;
}
public EncryptType getEncryptType() {
return encryptType;
}
public void setEncryptType(EncryptType encryptType) {
this.encryptType = encryptType;
}
public String getEchoStr() {
return echoStr;
}
public void setEchoStr(String echoStr) {
this.echoStr = echoStr;
}
public String getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(String timeStamp) {
this.timeStamp = timeStamp;
}
public String getNonce() {
return nonce;
}
public void setNonce(String nonce) {
this.nonce = nonce;
}
public String getSignature() {
return signature;
}
public void setSignature(String signature) {
this.signature = signature;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public String getOriginalContent() {
return originalContent;
}
public void setOriginalContent(String originalContent) {
this.originalContent = originalContent;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
@Override
public String toString() {
return "HttpWeixinMessage [toUserName=" + toUserName
+ ", encryptContent=" + encryptContent + ", encryptType="
+ encryptType + ", echoStr=" + echoStr + ", timeStamp="
+ timeStamp + ", nonce=" + nonce + ", signature=" + signature
+ ", token=" + token + ", originalContent=" + originalContent
+ ", method=" + method + "]";
}
}
@@ -1,122 +0,0 @@
package com.foxinmy.weixin4j.response;
import org.apache.commons.lang3.StringUtils;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.msg.model.Article;
import com.foxinmy.weixin4j.msg.model.Base;
import com.foxinmy.weixin4j.msg.model.News;
import com.foxinmy.weixin4j.msg.model.Responseable;
import com.foxinmy.weixin4j.util.ClassUtil;
import com.foxinmy.weixin4j.xml.TextConverter;
import com.foxinmy.weixin4j.xml.XmlStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
* 被动消息
* <p>
* <font color="red">回复图片等多媒体消息时需要预先上传多媒体文件到微信服务器,
* 假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试</font>
* </p>
*
* @className ResponseMessage
* @author jy.hu
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.msg.model.Text
* @see com.foxinmy.weixin4j.msg.model.Image
* @see com.foxinmy.weixin4j.msg.model.Voice
* @see com.foxinmy.weixin4j.msg.model.Video
* @see com.foxinmy.weixin4j.msg.model.Music
* @see com.foxinmy.weixin4j.msg.model.News
* @see com.foxinmy.weixin4j.msg.model.Trans
* @see <a href=
* "http://mp.weixin.qq.com/wiki/9/2c15b20a16019ae613d413e30cac8ea1.html"
* >订阅号、服务号的被动响应消息</a>
* @see <a
* href="http://qydev.weixin.qq.com/wiki/index.php?title=%E8%A2%AB%E5%8A%A8%E5%93%8D%E5%BA%94%E6%B6%88%E6%81%AF">企业号的被动响应消息</a>
*/
@XStreamAlias("xml")
public class ResponseMessage extends BaseMsg {
private static final long serialVersionUID = 7761192742840031607L;
protected final static XmlStream xmlStream = XmlStream.get();
static {
Class<?>[] classes = ClassUtil.getClasses(Base.class.getPackage())
.toArray(new Class[0]);
xmlStream.autodetectAnnotations(true);
xmlStream.processAnnotations(classes);
xmlStream.processAnnotations(ResponseMessage.class);
xmlStream.registerConverter(new TextConverter());
xmlStream.omitField(BaseMsg.class, "msgId");
xmlStream.alias("item", Article.class);
xmlStream.addImplicitCollection(News.class, "articles");
xmlStream.aliasSystemAttribute(null, "class");
}
/**
* 附加数据
*/
private String attach;
/**
* 消息对象
*
* @see com.foxinmy.weixin4j.msg.model.Responseable
*/
private final Base box;
public ResponseMessage(Base box) {
super(box.getMediaType().name());
this.box = box;
}
public ResponseMessage(Base box, BaseMsg inMessage) {
this(box, inMessage.getFromUserName(), inMessage.getToUserName());
}
public ResponseMessage(Base box, String toUserName, String fromUserName) {
super(box.getMediaType().name(), toUserName, fromUserName);
this.box = box;
}
public String getAttach() {
return attach;
}
public Base getBox() {
return box;
}
/**
* 消息对象转换为微信服务器接受的xml格式消息 </br> <font
* color="color">需Responseable标识,否则返回空</font>
*
* @see com.foxinmy.weixin4j.msg.model.Responseable
* @return xml字符串
*/
public String toXml() {
// check responseable
if (!(box instanceof Responseable)) {
return "";
}
String boxAlias = StringUtils.capitalize(getMsgType());
XStreamAlias alias = box.getClass().getAnnotation(XStreamAlias.class);
if (alias != null) {
boxAlias = alias.value();
}
xmlStream.aliasField(boxAlias, ResponseMessage.class, "box");
if (box instanceof News) {
attach = Integer.toString(((News) box).getArticles().size());
xmlStream.aliasField("ArticleCount", ResponseMessage.class,
"attach");
}
return xmlStream.toXML(this);
}
@Override
public String toString() {
return "ResponseMessage [ " + super.toString() + ", attach=" + attach
+ ", box=" + box + "]";
}
}
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import java.io.Serializable;
@@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -16,9 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
public class File extends Base implements Notifyable {
public class File implements NotifyTuple {
private static final long serialVersionUID = -8149837316289636110L;
@Override
public String getMessageType() {
return "file";
}
/**
* 上传后的微信返回的媒体ID
*/
@@ -27,7 +32,6 @@ public class File extends Base implements Notifyable {
private String mediaId;
public File(String mediaId) {
super(MediaType.file);
this.mediaId = mediaId;
}
@@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
public class Image extends Base implements Responseable, Notifyable, Massable {
public class Image implements ResponseTuple, MassTuple, NotifyTuple {
private static final long serialVersionUID = 6928681900960656161L;
@Override
public String getMessageType() {
return "image";
}
/**
* 上传后的微信返回的媒体ID
*/
@@ -28,12 +32,6 @@ public class Image extends Base implements Responseable, Notifyable, Massable {
private String mediaId;
public Image(String mediaId) {
super(MediaType.image);
this.mediaId = mediaId;
}
public Image(MediaType mediaType, String mediaId) {
super(mediaType);
this.mediaId = mediaId;
}
@@ -0,0 +1,18 @@
package com.foxinmy.weixin4j.tuple;
/**
* 群发消息元件
*
* @className MassTuple
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.tuple.Text
* @see com.foxinmy.weixin4j.tuple.Image
* @see com.foxinmy.weixin4j.tuple.Voice
* @see com.foxinmy.weixin4j.tuple.MpVideo
* @see com.foxinmy.weixin4j.tuple.MpNews
*/
public interface MassTuple extends Tuple {
}
@@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import java.io.Serializable;
@@ -1,10 +1,9 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@@ -20,10 +19,15 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField;
* @since JDK 1.7
* @see
*/
public class MpNews extends Base implements Massable, Notifyable {
public class MpNews implements MassTuple, NotifyTuple {
private static final long serialVersionUID = 8853054484809101524L;
@Override
public String getMessageType() {
return "mpnews";
}
/**
* 上传图文列表后微信返回的媒体ID
*/
@@ -42,7 +46,6 @@ public class MpNews extends Base implements Massable, Notifyable {
}
public MpNews(String mediaId) {
super(MediaType.mpnews);
this.mediaId = mediaId;
this.articles = new ArrayList<MpArticle>();
}
@@ -88,7 +91,6 @@ public class MpNews extends Base implements Massable, Notifyable {
@Override
public String toString() {
return "MpNews [articles=" + articles + ", mediaId=" + mediaId
+ ", getMediaType()=" + getMediaType() + "]";
return "MpNews [articles=" + articles + ", mediaId=" + mediaId + "]";
}
}
@@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
public class MpVideo extends Base implements Massable {
public class MpVideo implements MassTuple {
private static final long serialVersionUID = 2167437425244069128L;
@Override
public String getMessageType() {
return "mpvideo";
}
/**
* 上传视频后微信返回的媒体ID
*/
@@ -28,7 +32,6 @@ public class MpVideo extends Base implements Massable {
private String mediaId;
public MpVideo(String mediaId) {
super(MediaType.mpvideo);
this.mediaId = mediaId;
}
@@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @since JDK 1.7
* @see
*/
public class Music extends Base implements Responseable, Notifyable {
public class Music implements ResponseTuple, NotifyTuple {
private static final long serialVersionUID = -5952134916367253297L;
@Override
public String getMessageType() {
return "music";
}
/**
* 音乐标题
*/
@@ -56,7 +60,6 @@ public class Music extends Base implements Responseable, Notifyable {
public Music(String title, String desc, String musicUrl, String hqMusicUrl,
String thumbMediaId) {
super(MediaType.music);
this.title = title;
this.desc = desc;
this.musicUrl = musicUrl;
@@ -1,10 +1,9 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -20,21 +19,27 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see
*/
@XStreamAlias("Articles")
public class News extends Base implements Responseable, Notifyable {
private static final int MAX_ARTICLE_COUNT = 10;
public class News implements ResponseTuple, NotifyTuple {
private static final long serialVersionUID = 3348756809039388415L;
@Override
public String getMessageType() {
return "news";
}
private static final int MAX_ARTICLE_COUNT = 10;
/**
* 图文列表
*
* @see com.foxinmy.weixin4j.msg.model.Article
* @see com.foxinmy.weixin4j.tuple.Article
*/
@JSONField(name = "articles")
@XStreamAlias("Articles")
private List<Article> articles;
public News() {
super(MediaType.news);
this.articles = new ArrayList<Article>();
}
@@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.tuple;
/**
* 客服消息元件
*
* @className Notifyable
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.tuple.Text
* @see com.foxinmy.weixin4j.tuple.Image
* @see com.foxinmy.weixin4j.tuple.Voice
* @see com.foxinmy.weixin4j.tuple.Video
* @see com.foxinmy.weixin4j.tuple.Music
* @see com.foxinmy.weixin4j.tuple.News
*/
public interface NotifyTuple extends Tuple {
}
@@ -0,0 +1,20 @@
package com.foxinmy.weixin4j.tuple;
/**
* 被动消息元件
*
* @className ResponseTuple
* @author jy
* @date 2014年11月22日
* @since JDK 1.7
* @see com.foxinmy.weixin4j.tuple.Text
* @see com.foxinmy.weixin4j.tuple.Image
* @see com.foxinmy.weixin4j.tuple.Voice
* @see com.foxinmy.weixin4j.tuple.Video
* @see com.foxinmy.weixin4j.tuple.Music
* @see com.foxinmy.weixin4j.tuple.News
* @see com.foxinmy.weixin4j.tuple.Trans
*/
public interface ResponseTuple extends Tuple {
}
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -16,17 +15,21 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see
*/
@XStreamAlias("Content")
public class Text extends Base implements Responseable, Notifyable, Massable {
public class Text implements ResponseTuple, MassTuple, NotifyTuple {
private static final long serialVersionUID = 520050144519064503L;
@Override
public String getMessageType() {
return "text";
}
/**
* 内容
*/
private String content;
public Text(String content) {
super(MediaType.text);
this.content = content;
}
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
/**
@@ -16,10 +15,15 @@ import com.thoughtworks.xstream.annotations.XStreamAlias;
* @see
*/
@XStreamAlias("TransInfo")
public class Trans extends Base implements Responseable {
public class Trans implements ResponseTuple {
private static final long serialVersionUID = -214711609286629729L;
@Override
public String getMessageType() {
return "transfer_customer_service";
}
/**
* 指定会话接入的客服账号
*/
@@ -31,7 +35,6 @@ public class Trans extends Base implements Responseable {
}
public Trans(String kfAccount) {
super(MediaType.transfer_customer_service);
this.kfAccount = kfAccount;
}
@@ -43,4 +46,5 @@ public class Trans extends Base implements Responseable {
public String toString() {
return "Trans [kfAccount=" + kfAccount + "]";
}
}
@@ -1,7 +1,6 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.type.MediaType;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamOmitField;
@@ -17,10 +16,15 @@ import com.thoughtworks.xstream.annotations.XStreamOmitField;
* @since JDK 1.7
* @see
*/
public class Video extends Base implements Responseable, Notifyable {
public class Video implements ResponseTuple, NotifyTuple {
private static final long serialVersionUID = 2167437425244069128L;
@Override
public String getMessageType() {
return "video";
}
/**
* 上传视频微信返回的媒体ID
*/
@@ -46,7 +50,6 @@ public class Video extends Base implements Responseable, Notifyable {
private String desc;
public Video(String mediaId) {
super(MediaType.video);
this.mediaId = mediaId;
}
@@ -59,7 +62,6 @@ public class Video extends Base implements Responseable, Notifyable {
}
public Video(String mediaId, String thumbMediaId, String title, String desc) {
super(MediaType.video);
this.mediaId = mediaId;
this.thumbMediaId = thumbMediaId;
this.title = title;
@@ -101,7 +103,6 @@ public class Video extends Base implements Responseable, Notifyable {
@Override
public String toString() {
return "Video [thumbMediaId=" + thumbMediaId + ", title=" + title
+ ", desc=" + desc + ", mediaId=" + mediaId
+ ", getMediaType()=" + getMediaType() + "]";
+ ", desc=" + desc + ", mediaId=" + mediaId + "]";
}
}
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.msg.model;
package com.foxinmy.weixin4j.tuple;
import com.foxinmy.weixin4j.type.MediaType;
/**
* 语音对象
@@ -14,11 +13,16 @@ import com.foxinmy.weixin4j.type.MediaType;
* @since JDK 1.7
* @see
*/
public class Voice extends Image implements Responseable, Notifyable, Massable {
public class Voice extends Image implements ResponseTuple, NotifyTuple {
private static final long serialVersionUID = 8853054484809101524L;
@Override
public String getMessageType() {
return "voice";
}
public Voice(String mediaId) {
super(MediaType.voice, mediaId);
super(mediaId);
}
}
@@ -1,22 +0,0 @@
package com.foxinmy.weixin4j.type;
/**
* 账号类型
*
* @className AccountType
* @author jy
* @date 2014年11月18日
* @since JDK 1.7
* @see
*/
public enum AccountType {
/**
* 公众号
*/
MP,
/**
* 企业号
*/
QY;
}
@@ -1,21 +0,0 @@
package com.foxinmy.weixin4j.type;
/**
* 消息加密类型
*
* @className EncryptType
* @author jy
* @date 2014年11月23日
* @since JDK 1.7
* @see
*/
public enum EncryptType {
/**
* 明文模式
*/
RAW,
/**
* 密文模式
*/
AES;
}
@@ -1,21 +1,5 @@
package com.foxinmy.weixin4j.type;
import com.foxinmy.weixin4j.msg.event.BatchjobresultMessage;
import com.foxinmy.weixin4j.msg.event.EnterAgentEventMessage;
import com.foxinmy.weixin4j.msg.event.EventMessage;
import com.foxinmy.weixin4j.msg.event.KfCloseEventMessage;
import com.foxinmy.weixin4j.msg.event.KfCreateEventMessage;
import com.foxinmy.weixin4j.msg.event.KfSwitchEventMessage;
import com.foxinmy.weixin4j.msg.event.LocationEventMessage;
import com.foxinmy.weixin4j.msg.event.MassEventMessage;
import com.foxinmy.weixin4j.msg.event.ScanEventMessage;
import com.foxinmy.weixin4j.msg.event.ScribeEventMessage;
import com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage;
import com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage;
import com.foxinmy.weixin4j.msg.event.menu.MenuLocationEventMessage;
import com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage;
import com.foxinmy.weixin4j.msg.event.menu.MenuScanEventMessage;
/**
* 事件类型
*
@@ -29,125 +13,65 @@ public enum EventType {
/**
* 关注事件
*
* @see com.foxinmy.weixin4j.msg.event.ScribeEventMessage
*/
subscribe(ScribeEventMessage.class),
subscribe,
/**
* 取消关注事件
*
* @see com.foxinmy.weixin4j.msg.event.ScribeEventMessage
*/
unsubscribe(ScribeEventMessage.class),
/**
* 二维码扫描事件
*
* @see com.foxinmy.weixin4j.msg.event.ScanEventMessage
*/
scan(ScanEventMessage.class),
unsubscribe,
/**
* 上报地理位置事件
*
* @see com.foxinmy.weixin4j.msg.event.LocationEventMessage
*/
location(LocationEventMessage.class),
location,
/**
* 菜单扫描事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuScanEventMessage
*/
scancode_push(MenuScanEventMessage.class),
scancode_push,
/**
* 菜单点击关键字事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage
*/
view(MenuEventMessage.class),
view,
/**
* 菜单点击链接事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage
*/
click(MenuEventMessage.class),
click,
/**
* 菜单扫描并调出等待界面事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuScanEventMessage
*/
scancode_waitmsg(MenuScanEventMessage.class),
scancode_waitmsg,
/**
* 菜单弹出拍照事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage
*/
pic_sysphoto(MenuPhotoEventMessage.class),
pic_sysphoto,
/**
* 菜单弹出发图事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage
*/
pic_photo_or_album(MenuPhotoEventMessage.class),
pic_photo_or_album,
/**
* 菜单弹出发图事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuPhotoEventMessage
*/
pic_weixin(MenuPhotoEventMessage.class),
pic_weixin,
/**
* 菜单发送地理位置事件
*
* @see com.foxinmy.weixin4j.msg.event.menu.MenuLocationEventMessage
*/
location_select(MenuLocationEventMessage.class),
/**
* 群发消息事件
*
* @see com.foxinmy.weixin4j.msg.event.MassEventMessage
*/
masssendjobfinish(MassEventMessage.class),
/**
* 模板消息事件
*
* @see com.foxinmy.weixin4j.msg.event.TemplatesendjobfinishMessage
*/
templatesendjobfinish(TemplatesendjobfinishMessage.class),
/**
* 进入企业号应用事件
*
* @see com.foxinmy.weixin4j.msg.event.EnterAgentEventMessage
*/
enter_agent(EnterAgentEventMessage.class),
/**
* 客服接入会话事件
*
* @see com.foxinmy.weixin4j.msg.event.KfCreateEventMessage
*/
kf_create_session(KfCreateEventMessage.class),
/**
* 客服关闭会话事件
*
* @see com.foxinmy.weixin4j.msg.event.KfCloseEventMessage
*/
kf_close_session(KfCloseEventMessage.class),
/**
* 客服转接会话事件
*
* @see com.foxinmy.weixin4j.msg.event.KfSwitchEventMessage
*/
kf_switch_session(KfSwitchEventMessage.class),
/**
* 异步任务完成事件
*
* @see com.foxinmy.weixin4j.msg.event.BatchjobresultMessage
*/
batch_job_result(BatchjobresultMessage.class);
private Class<? extends EventMessage> eventClass;
EventType(Class<? extends EventMessage> eventClass) {
this.eventClass = eventClass;
}
public Class<? extends EventMessage> getEventClass() {
return eventClass;
}
location_select;
}
@@ -3,17 +3,13 @@ package com.foxinmy.weixin4j.type;
/**
* 上传的媒体类型</br>
* <p>
* 公众平台上传限制:</br>
* 图片(image): 128K,支持JPG格式</br>
* 语音(voice):256K,播放长度不超过60s,支持AMR\MP3格式</br>
* 视频(video):1MB,支持MP4格式</br>
* 公众平台上传限制:</br> 图片(image): 128K,支持JPG格式</br>
* 语音(voice):256K,播放长度不超过60s,支持AMR\MP3格式</br> 视频(video):1MB,支持MP4格式</br>
* 缩略图(thumb):64KB,支持JPG格式</br>
* </p>
* <p>
* 企业号上传限制:</br>
* 图片(image:1MB,支持JPG格式</br>
* 语音(voice):2MB,播放长度不超过60s,支持AMR格式</br>
* 视频(video):10MB,支持MP4格式</br>
* 企业号上传限制:</br> 图片(image:1MB,支持JPG格式</br>
* 语音(voice):2MB,播放长度不超过60s,支持AMR格式</br> 视频(video):10MB,支持MP4格式</br>
* 普通文件(file):10MB</br>
* </p>
* <p>
@@ -25,8 +21,7 @@ package com.foxinmy.weixin4j.type;
* @since JDK 1.7
*/
public enum MediaType {
image("jpg"), voice("amr/mp3"), video("mp4"), thumb("jpg"), file("unknown"), text(
""), music(""), news(""), mpnews(""), mpvideo(""), transfer_customer_service(
image("jpg"), voice("amr/mp3"), video("mp4"), thumb("jpg"), file("unknown"), news(
"");
MediaType(String formatName) {
@@ -1,13 +1,5 @@
package com.foxinmy.weixin4j.type;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.msg.ImageMessage;
import com.foxinmy.weixin4j.msg.LinkMessage;
import com.foxinmy.weixin4j.msg.LocationMessage;
import com.foxinmy.weixin4j.msg.TextMessage;
import com.foxinmy.weixin4j.msg.VideoMessage;
import com.foxinmy.weixin4j.msg.VoiceMessage;
import com.foxinmy.weixin4j.msg.event.EventMessage;
/**
*
@@ -22,56 +14,47 @@ public enum MessageType {
*
* @see com.foxinmy.weixin4j.msg.TextMessage
*/
text(TextMessage.class),
text,
/**
* 图片消息
*
* @see com.foxinmy.weixin4j.msg.ImageMessage
*/
image(ImageMessage.class),
image,
/**
* 语音消息
*
* @see com.foxinmy.weixin4j.msg.VoiceMessage
*/
voice(VoiceMessage.class),
voice,
/**
* 视频消息
*
* @see com.foxinmy.weixin4j.msg.VideoMessage
*/
video(VideoMessage.class),
video,
/**
* 小视频消息
*
* @see com.foxinmy.weixin4j.msg.VideoMessage
*/
shortvideo(VideoMessage.class),
shortvideo,
/**
* 位置消息
*
* @see com.foxinmy.weixin4j.msg.LocationMessage
*/
location(LocationMessage.class),
location,
/**
* 链接消息
*
* @see com.foxinmy.weixin4j.msg.LinkMessage
*/
link(LinkMessage.class),
link,
/**
* 事件消息
*
* @see com.foxinmy.weixin4j.msg.event.EventMessage
*/
event(EventMessage.class);
private Class<? extends BaseMsg> messageClass;
MessageType(Class<? extends BaseMsg> messageClass) {
this.messageClass = messageClass;
}
public Class<? extends BaseMsg> getMessageClass() {
return messageClass;
}
event;
}
@@ -6,8 +6,6 @@ import java.util.Set;
import com.alibaba.fastjson.JSON;
import com.foxinmy.weixin4j.model.WeixinAccount;
import com.foxinmy.weixin4j.model.WeixinMpAccount;
import com.foxinmy.weixin4j.model.WeixinQyAccount;
/**
* 商户配置工具类
@@ -62,16 +60,8 @@ public class ConfigUtil {
CLASSPATH_VALUE)).getPath();
}
public static <T extends WeixinAccount> T getWeixinAccount(Class<T> clazz) {
public static WeixinAccount getWeixinAccount() {
String text = getValue("account");
return JSON.parseObject(text, clazz);
}
public static WeixinMpAccount getWeixinMpAccount() {
return getWeixinAccount(WeixinMpAccount.class);
}
public static WeixinQyAccount getWeixinQyAccount() {
return getWeixinAccount(WeixinQyAccount.class);
return JSON.parseObject(text, WeixinAccount.class);
}
}
@@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.util;
import java.io.InputStream;
import java.util.Arrays;
import javax.crypto.Cipher;
@@ -9,18 +8,9 @@ import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.SAXReader;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.model.BaseMsg;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.type.EventType;
import com.foxinmy.weixin4j.type.MessageType;
import com.foxinmy.weixin4j.xml.XmlStream;
/**
* 消息工具类
@@ -165,62 +155,4 @@ public class MessageUtil {
}
return xmlContent;
}
/**
* xml消息转换为消息对象
*
* @param xmlMsg
* 消息字符串
* @return 消息对象
* @throws DocumentException
* @see <a
* href="http://mp.weixin.qq.com/wiki/4/2ccadaef44fe1e4b0322355c2312bfa8.html">验证消息的合法性</a>
* @see <a
* href="http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html">普通消息</a>
* @see <a
* href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html">事件消息</a>
* @see com.foxinmy.weixin4j.type.MessageType
* @see com.feican.weixin.msg.BaeMessage
* @see com.foxinmy.weixin4j.msg.TextMessage
* @see com.foxinmy.weixin4j.msg.ImageMessage
* @see com.foxinmy.weixin4j.msg.VoiceMessage
* @see com.foxinmy.weixin4j.msg.VideoMessage
* @see com.foxinmy.weixin4j.msg.LocationMessage
* @see com.foxinmy.weixin4j.msg.LinkMessage
* @see com.foxinmy.weixin4j.msg.event.ScribeEventMessage
* @see com.foxinmy.weixin4j.msg.event.ScanEventMessage
* @see com.foxinmy.weixin4j.msg.event.LocationEventMessage
* @see com.foxinmy.weixin4j.msg.event.menu.MenuEventMessage
*/
public static BaseMsg xml2msg(String xmlMsg) throws DocumentException {
Document doc = DocumentHelper.parseText(xmlMsg);
String type = doc.selectSingleNode("/xml/MsgType").getStringValue();
if (StringUtils.isBlank(type)) {
return null;
}
MessageType messageType = MessageType.valueOf(type.toLowerCase());
Class<? extends BaseMsg> messageClass = messageType.getMessageClass();
if (messageType == MessageType.event) {
type = doc.selectSingleNode("/xml/Event").getStringValue();
messageClass = EventType.valueOf(type.toLowerCase())
.getEventClass();
}
return XmlStream.get(xmlMsg, messageClass);
}
/**
* xml消息转换为消息对象
*
* @param inputStream
* 带消息字符串的输入流
* @return 消息对象
* @throws DocumentException
* @see {@link com.foxinmy.weixin4j.util.MessageUtil#xml2msg(String)}
*/
public static BaseMsg xml2msg(InputStream inputStream)
throws DocumentException {
SAXReader reader = new SAXReader();
Document doc = reader.read(inputStream);
return xml2msg(doc.asXML());
}
}
@@ -1,6 +1,6 @@
package com.foxinmy.weixin4j.xml;
import com.foxinmy.weixin4j.msg.model.Text;
import com.foxinmy.weixin4j.tuple.Text;
import com.thoughtworks.xstream.converters.SingleValueConverter;
/**